home *** CD-ROM | disk | FTP | other *** search
/ Photo CD Demo 1 / Demo.bin / compresn / jpegv3sr / jdcolor.c < prev    next >
C/C++ Source or Header  |  1992-03-14  |  9KB  |  297 lines

  1. /*
  2.  * jdcolor.c
  3.  *
  4.  * Copyright (C) 1991, 1992, Thomas G. Lane.
  5.  * This file is part of the Independent JPEG Group's software.
  6.  * For conditions of distribution and use, see the accompanying README file.
  7.  *
  8.  * This file contains output colorspace conversion routines.
  9.  * These routines are invoked via the methods color_convert
  10.  * and colorout_init/term.
  11.  */
  12.  
  13. #include "jinclude.h"
  14.  
  15.  
  16. /**************** YCbCr -> RGB conversion: most common case **************/
  17.  
  18. /*
  19.  * YCbCr is defined per CCIR 601-1, except that Cb and Cr are
  20.  * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
  21.  * The conversion equations to be implemented are therefore
  22.  *    R = Y                + 1.40200 * Cr
  23.  *    G = Y - 0.34414 * Cb - 0.71414 * Cr
  24.  *    B = Y + 1.77200 * Cb
  25.  * where Cb and Cr represent the incoming values less MAXJSAMPLE/2.
  26.  * (These numbers are derived from TIFF Appendix O, draft of 4/10/91.)
  27.  *
  28.  * To avoid floating-point arithmetic, we represent the fractional constants
  29.  * as integers scaled up by 2^14 (about 4 digits precision); we have to divide
  30.  * the products by 2^14, with appropriate rounding, to get the correct answer.
  31.  * Notice that Y, being an integral input, does not contribute any fraction
  32.  * so it need not participate in the rounding.
  33.  *
  34.  * For even more speed, we avoid doing any multiplications in the inner loop
  35.  * by precalculating the constants times Cb and Cr for all possible values.
  36.  * For 8-bit JSAMPLEs this is very reasonable (only 256 table entries); for
  37.  * 12-bit samples it is still acceptable.  It's not very reasonable for 16-bit
  38.  * samples, but if you want lossless storage you shouldn't be changing
  39.  * colorspace anyway.
  40.  * The Cr=>R and Cb=>B values can be rounded to integers in advance; the
  41.  * values for the G calculation are left scaled up, since we must add them
  42.  * together before rounding.
  43.  */
  44.  
  45. #define SCALEBITS    14
  46. #define ONE_HALF    ((INT32) 1 << (SCALEBITS-1))
  47. #define FIX(x)        ((INT32) ((x) * (1L<<SCALEBITS) + 0.5))
  48.  
  49. static INT16 * Cr_r_tab;    /* => table for Cr to R conversion */
  50. static INT16 * Cb_b_tab;    /* => table for Cb to B conversion */
  51. static INT32 * Cr_g_tab;    /* => table for Cr to G conversion */
  52. static INT32 * Cb_g_tab;    /* => table for Cb to G conversion */
  53.  
  54.  
  55. /*
  56.  * Initialize for colorspace conversion.
  57.  */
  58.  
  59. METHODDEF void
  60. ycc_rgb_init (decompress_info_ptr cinfo)
  61. {
  62. #ifdef SIXTEEN_BIT_SAMPLES
  63.   INT32 i, x2;
  64. #else
  65.   int i, x2;            /* smart compiler may do 16x16=>32 multiply */
  66. #endif
  67.   SHIFT_TEMPS
  68.  
  69.   Cr_r_tab = (INT16 *) (*cinfo->emethods->alloc_small)
  70.                 ((MAXJSAMPLE+1) * SIZEOF(INT16));
  71.   Cb_b_tab = (INT16 *) (*cinfo->emethods->alloc_small)
  72.                 ((MAXJSAMPLE+1) * SIZEOF(INT16));
  73.   Cr_g_tab = (INT32 *) (*cinfo->emethods->alloc_small)
  74.                 ((MAXJSAMPLE+1) * SIZEOF(INT32));
  75.   Cb_g_tab = (INT32 *) (*cinfo->emethods->alloc_small)
  76.                 ((MAXJSAMPLE+1) * SIZEOF(INT32));
  77.  
  78.   for (i = 0; i <= MAXJSAMPLE; i++) {
  79.     /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
  80.     /* The Cb or Cr value we are thinking of is x = i - MAXJSAMPLE/2 */
  81.     x2 = 2*i - MAXJSAMPLE;    /* twice x */
  82.     /* Cr=>R value is nearest int to 1.40200 * x */
  83.     Cr_r_tab[i] = (INT16)
  84.             RIGHT_SHIFT(FIX(1.40200/2) * x2 + ONE_HALF, SCALEBITS);
  85.     /* Cb=>B value is nearest int to 1.77200 * x */
  86.     Cb_b_tab[i] = (INT16)
  87.             RIGHT_SHIFT(FIX(1.77200/2) * x2 + ONE_HALF, SCALEBITS);
  88.     /* Cr=>G value is scaled-up -0.71414 * x */
  89.     Cr_g_tab[i] = (- FIX(0.71414/2)) * x2;
  90.     /* Cb=>G value is scaled-up -0.34414 * x */
  91.     /* We also add in ONE_HALF so that need not do it in inner loop */
  92.     Cb_g_tab[i] = (- FIX(0.34414/2)) * x2 + ONE_HALF;
  93.   }
  94. }
  95.  
  96.  
  97. /*
  98.  * Convert some rows of samples to the output colorspace.
  99.  */
  100.  
  101. METHODDEF void
  102. ycc_rgb_convert (decompress_info_ptr cinfo, int num_rows, long num_cols,
  103.          JSAMPIMAGE input_data, JSAMPIMAGE output_data)
  104. {
  105. #ifdef SIXTEEN_BIT_SAMPLES
  106.   register UINT16 y, cb, cr;
  107.   register INT32 x;
  108. #else
  109.   register int y, cb, cr;
  110.   register int x;
  111. #endif
  112.   register JSAMPROW inptr0, inptr1, inptr2;
  113.   register JSAMPROW outptr0, outptr1, outptr2;
  114.   long col;
  115.   int row;
  116.   SHIFT_TEMPS
  117.   
  118.   for (row = 0; row < num_rows; row++) {
  119.     inptr0 = input_data[0][row];
  120.     inptr1 = input_data[1][row];
  121.     inptr2 = input_data[2][row];
  122.     outptr0 = output_data[0][row];
  123.     outptr1 = output_data[1][row];
  124.     outptr2 = output_data[2][row];
  125.     for (col = num_cols; col > 0; col--) {
  126.       y  = GETJSAMPLE(*inptr0++);
  127.       cb = GETJSAMPLE(*inptr1++);
  128.       cr = GETJSAMPLE(*inptr2++);
  129.       /* Note: if the inputs were computed directly from RGB values,
  130.        * range-limiting would be unnecessary here; but due to possible
  131.        * noise in the DCT/IDCT phase, we do need to apply range limits.
  132.        */
  133.       x = y + Cr_r_tab[cr];    /* red */
  134.       if (x < 0) x = 0;
  135.       else if (x > MAXJSAMPLE) x = MAXJSAMPLE;
  136.       *outptr0++ = (JSAMPLE) x;
  137.       x = y + ((int) RIGHT_SHIFT(Cb_g_tab[cb] + Cr_g_tab[cr], SCALEBITS));
  138.       if (x < 0) x = 0;
  139.       else if (x > MAXJSAMPLE) x = MAXJSAMPLE;
  140.       *outptr1++ = (JSAMPLE) x;
  141.       x = y + Cb_b_tab[cb];    /* blue */
  142.       if (x < 0) x = 0;
  143.       else if (x > MAXJSAMPLE) x = MAXJSAMPLE;
  144.       *outptr2++ = (JSAMPLE) x;
  145.     }
  146.   }
  147. }
  148.  
  149.  
  150. /*
  151.  * Finish up at the end of the file.
  152.  */
  153.  
  154. METHODDEF void
  155. ycc_rgb_term (decompress_info_ptr cinfo)
  156. {
  157.   /* no work (we let free_all release the workspace) */
  158. }
  159.  
  160.  
  161. /**************** Cases other than YCbCr -> RGB **************/
  162.  
  163.  
  164. /*
  165.  * Initialize for colorspace conversion.
  166.  */
  167.  
  168. METHODDEF void
  169. null_init (decompress_info_ptr cinfo)
  170. /* colorout_init for cases where no setup is needed */
  171. {
  172.   /* no work needed */
  173. }
  174.  
  175.  
  176. /*
  177.  * Color conversion for no colorspace change: just copy the data.
  178.  */
  179.  
  180. METHODDEF void
  181. null_convert (decompress_info_ptr cinfo, int num_rows, long num_cols,
  182.           JSAMPIMAGE input_data, JSAMPIMAGE output_data)
  183. {
  184.   short ci;
  185.  
  186.   for (ci = 0; ci < cinfo->num_components; ci++) {
  187.     jcopy_sample_rows(input_data[ci], 0, output_data[ci], 0,
  188.               num_rows, num_cols);
  189.   }
  190. }
  191.  
  192.  
  193. /*
  194.  * Color conversion for grayscale: just copy the data.
  195.  * This also works for YCbCr/YIQ -> grayscale conversion, in which
  196.  * we just copy the Y (luminance) component and ignore chrominance.
  197.  */
  198.  
  199. METHODDEF void
  200. grayscale_convert (decompress_info_ptr cinfo, int num_rows, long num_cols,
  201.            JSAMPIMAGE input_data, JSAMPIMAGE output_data)
  202. {
  203.   jcopy_sample_rows(input_data[0], 0, output_data[0], 0,
  204.             num_rows, num_cols);
  205. }
  206.  
  207.  
  208. /*
  209.  * Finish up at the end of the file.
  210.  */
  211.  
  212. METHODDEF void
  213. null_term (decompress_info_ptr cinfo)
  214. /* colorout_term for cases where no teardown is needed */
  215. {
  216.   /* no work needed */
  217. }
  218.  
  219.  
  220.  
  221. /*
  222.  * The method selection routine for output colorspace conversion.
  223.  */
  224.  
  225. GLOBAL void
  226. jseldcolor (decompress_info_ptr cinfo)
  227. {
  228.   /* Make sure num_components agrees with jpeg_color_space */
  229.   switch (cinfo->jpeg_color_space) {
  230.   case CS_GRAYSCALE:
  231.     if (cinfo->num_components != 1)
  232.       ERREXIT(cinfo->emethods, "Bogus JPEG colorspace");
  233.     break;
  234.  
  235.   case CS_RGB:
  236.   case CS_YCbCr:
  237.   case CS_YIQ:
  238.     if (cinfo->num_components != 3)
  239.       ERREXIT(cinfo->emethods, "Bogus JPEG colorspace");
  240.     break;
  241.  
  242.   case CS_CMYK:
  243.     if (cinfo->num_components != 4)
  244.       ERREXIT(cinfo->emethods, "Bogus JPEG colorspace");
  245.     break;
  246.  
  247.   default:
  248.     ERREXIT(cinfo->emethods, "Unsupported JPEG colorspace");
  249.     break;
  250.   }
  251.  
  252.   /* Set color_out_comps and conversion method based on requested space */
  253.   switch (cinfo->out_color_space) {
  254.   case CS_GRAYSCALE:
  255.     cinfo->color_out_comps = 1;
  256.     if (cinfo->jpeg_color_space == CS_GRAYSCALE ||
  257.     cinfo->jpeg_color_space == CS_YCbCr ||
  258.     cinfo->jpeg_color_space == CS_YIQ) {
  259.       cinfo->methods->color_convert = grayscale_convert;
  260.       cinfo->methods->colorout_init = null_init;
  261.       cinfo->methods->colorout_term = null_term;
  262.     } else
  263.       ERREXIT(cinfo->emethods, "Unsupported color conversion request");
  264.     break;
  265.  
  266.   case CS_RGB:
  267.     cinfo->color_out_comps = 3;
  268.     if (cinfo->jpeg_color_space == CS_YCbCr) {
  269.       cinfo->methods->color_convert = ycc_rgb_convert;
  270.       cinfo->methods->colorout_init = ycc_rgb_init;
  271.       cinfo->methods->colorout_term = ycc_rgb_term;
  272.     } else if (cinfo->jpeg_color_space == CS_RGB) {
  273.       cinfo->methods->color_convert = null_convert;
  274.       cinfo->methods->colorout_init = null_init;
  275.       cinfo->methods->colorout_term = null_term;
  276.     } else
  277.       ERREXIT(cinfo->emethods, "Unsupported color conversion request");
  278.     break;
  279.  
  280.   default:
  281.     /* Permit null conversion from CMYK or YCbCr to same output space */
  282.     if (cinfo->out_color_space == cinfo->jpeg_color_space) {
  283.       cinfo->color_out_comps = cinfo->num_components;
  284.       cinfo->methods->color_convert = null_convert;
  285.       cinfo->methods->colorout_init = null_init;
  286.       cinfo->methods->colorout_term = null_term;
  287.     } else            /* unsupported non-null conversion */
  288.       ERREXIT(cinfo->emethods, "Unsupported color conversion request");
  289.     break;
  290.   }
  291.  
  292.   if (cinfo->quantize_colors)
  293.     cinfo->final_out_comps = 1;    /* single colormapped output component */
  294.   else
  295.     cinfo->final_out_comps = cinfo->color_out_comps;
  296. }
  297.