/* * jdcolor.c * * Copyright (C) 1991, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * * This file contains output colorspace conversion routines. * These routines are invoked via the methods color_convert * and colorout_init/term. */ #include "jinclude.h" /* * Initialize for colorspace conversion. */ METHODDEF void colorout_init (decompress_info_ptr cinfo) { /* no work needed */ } /* * Convert some rows of samples to the output colorspace. * This version handles YCbCr -> RGB conversion. * YCbCr is defined per CCIR 601-1, except that Cb and Cr are * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5. */ METHODDEF void ycc_rgb_convert (decompress_info_ptr cinfo, int num_rows, JSAMPIMAGE input_data, JSAMPIMAGE output_data) { register INT32 y, u, v, x; register JSAMPROW inptr0, inptr1, inptr2; register JSAMPROW outptr0, outptr1, outptr2; register long col; register long width = cinfo->image_width; register int row; for (row = 0; row < num_rows; row++) { inptr0 = input_data[0][row]; inptr1 = input_data[1][row]; inptr2 = input_data[2][row]; outptr0 = output_data[0][row]; outptr1 = output_data[1][row]; outptr2 = output_data[2][row]; for (col = width; col > 0; col--) { y = GETJSAMPLE(*inptr0++); u = (int) GETJSAMPLE(*inptr1++) - CENTERJSAMPLE; v = (int) GETJSAMPLE(*inptr2++) - CENTERJSAMPLE; /* Note: if the inputs were computed directly from RGB values, * range-limiting would be unnecessary here; but due to possible * noise in the DCT/IDCT phase, we do need to apply range limits. */ y *= 1024; /* in case compiler can't spot common subexpression */ x = y + 1436*v + 512; /* red */ if (x < 0) x = 0; if (x > ((INT32) MAXJSAMPLE*1024)) x = (INT32) MAXJSAMPLE*1024; *outptr0++ = x >> 10; x = y - 352*u - 731*v + 512; /* green */ if (x < 0) x = 0; if (x > ((INT32) MAXJSAMPLE*1024)) x = (INT32) MAXJSAMPLE*1024; *outptr1++ = x >> 10; x = y + 1815*u + 512; /* blue */ if (x < 0) x = 0; if (x > ((INT32) MAXJSAMPLE*1024)) x = (INT32) MAXJSAMPLE*1024; *outptr2++ = x >> 10; } } } /* * Color conversion for no colorspace change: just copy the data. */ METHODDEF void null_convert (decompress_info_ptr cinfo, int num_rows, JSAMPIMAGE input_data, JSAMPIMAGE output_data) { short ci; for (ci = 0; ci < cinfo->num_components; ci++) { jcopy_sample_rows(input_data[ci], 0, output_data[ci], 0, num_rows, cinfo->image_width); } } /* * Color conversion for grayscale: just copy the data. * This also works for YCbCr/YIQ -> grayscale conversion, in which * we just copy the Y (luminance) component and ignore chrominance. */ METHODDEF void grayscale_convert (decompress_info_ptr cinfo, int num_rows, JSAMPIMAGE input_data, JSAMPIMAGE output_data) { jcopy_sample_rows(input_data[0], 0, output_data[0], 0, num_rows, cinfo->image_width); } /* * Finish up at the end of the file. */ METHODDEF void colorout_term (decompress_info_ptr cinfo) { /* no work needed */ } /* * The method selection routine for output colorspace conversion. */ GLOBAL void jseldcolor (decompress_info_ptr cinfo) { /* Make sure num_components agrees with jpeg_color_space */ switch (cinfo->jpeg_color_space) { case CS_GRAYSCALE: if (cinfo->num_components != 1) ERREXIT(cinfo->emethods, "Bogus JPEG colorspace"); break; case CS_RGB: case CS_YIQ: case CS_YCbCr: if (cinfo->num_components != 3) ERREXIT(cinfo->emethods, "Bogus JPEG colorspace"); break; case CS_CMYK: if (cinfo->num_components != 4) ERREXIT(cinfo->emethods, "Bogus JPEG colorspace"); break; default: ERREXIT(cinfo->emethods, "Unsupported JPEG colorspace"); break; } /* Set color_out_comps and conversion method based on requested space */ switch (cinfo->out_color_space) { case CS_GRAYSCALE: cinfo->color_out_comps = 1; if (cinfo->jpeg_color_space == CS_GRAYSCALE || cinfo->jpeg_color_space == CS_YCbCr || cinfo->jpeg_color_space == CS_YIQ) cinfo->methods->color_convert = grayscale_convert; else ERREXIT(cinfo->emethods, "Unsupported color conversion request"); break; case CS_RGB: cinfo->color_out_comps = 3; if (cinfo->jpeg_color_space == CS_YCbCr) cinfo->methods->color_convert = ycc_rgb_convert; else if (cinfo->jpeg_color_space == CS_RGB) cinfo->methods->color_convert = null_convert; else ERREXIT(cinfo->emethods, "Unsupported color conversion request"); break; case CS_CMYK: cinfo->color_out_comps = 4; if (cinfo->jpeg_color_space == CS_CMYK) cinfo->methods->color_convert = null_convert; else ERREXIT(cinfo->emethods, "Unsupported color conversion request"); break; default: ERREXIT(cinfo->emethods, "Unsupported output colorspace"); break; } if (cinfo->quantize_colors) cinfo->final_out_comps = 1; /* single colormapped output component */ else cinfo->final_out_comps = cinfo->color_out_comps; cinfo->methods->colorout_init = colorout_init; cinfo->methods->colorout_term = colorout_term; }