home *** CD-ROM | disk | FTP | other *** search
/ Encyclopedia of Graphics File Formats Companion / GFF_CD.ISO / software / unix / jpeg / jpegv4a.tar / jccolor.c < prev    next >
C/C++ Source or Header  |  1992-08-07  |  11KB  |  362 lines

  1. /*
  2.  * jccolor.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 input colorspace conversion routines.
  9.  * These routines are invoked via the methods get_sample_rows
  10.  * and colorin_init/term.
  11.  */
  12.  
  13. #include "jinclude.h"
  14.  
  15.  
  16. static JSAMPARRAY pixel_row;    /* Workspace for a pixel row in input format */
  17.  
  18.  
  19. /**************** RGB -> YCbCr conversion: most common case **************/
  20.  
  21. /*
  22.  * YCbCr is defined per CCIR 601-1, except that Cb and Cr are
  23.  * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
  24.  * The conversion equations to be implemented are therefore
  25.  *    Y  =  0.29900 * R + 0.58700 * G + 0.11400 * B
  26.  *    Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B  + MAXJSAMPLE/2
  27.  *    Cr =  0.50000 * R - 0.41869 * G - 0.08131 * B  + MAXJSAMPLE/2
  28.  * (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.)
  29.  *
  30.  * To avoid floating-point arithmetic, we represent the fractional constants
  31.  * as integers scaled up by 2^16 (about 4 digits precision); we have to divide
  32.  * the products by 2^16, with appropriate rounding, to get the correct answer.
  33.  *
  34.  * For even more speed, we avoid doing any multiplications in the inner loop
  35.  * by precalculating the constants times R,G,B for all possible values.
  36.  * For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table);
  37.  * for 12-bit samples it is still acceptable.  It's not very reasonable for
  38.  * 16-bit samples, but if you want lossless storage you shouldn't be changing
  39.  * colorspace anyway.
  40.  * The MAXJSAMPLE/2 offsets and the rounding fudge-factor of 0.5 are included
  41.  * in the tables to save adding them separately in the inner loop.
  42.  */
  43.  
  44. #ifdef SIXTEEN_BIT_SAMPLES
  45. #define SCALEBITS    14    /* avoid overflow */
  46. #else
  47. #define SCALEBITS    16    /* speedier right-shift on some machines */
  48. #endif
  49. #define ONE_HALF    ((INT32) 1 << (SCALEBITS-1))
  50. #define FIX(x)        ((INT32) ((x) * (1L<<SCALEBITS) + 0.5))
  51.  
  52. /* We allocate one big table and divide it up into eight parts, instead of
  53.  * doing eight alloc_small requests.  This lets us use a single table base
  54.  * address, which can be held in a register in the inner loops on many
  55.  * machines (more than can hold all eight addresses, anyway).
  56.  */
  57.  
  58. static INT32 * rgb_ycc_tab;    /* => table for RGB to YCbCr conversion */
  59. #define R_Y_OFF        0            /* offset to R => Y section */
  60. #define G_Y_OFF        (1*(MAXJSAMPLE+1))    /* offset to G => Y section */
  61. #define B_Y_OFF        (2*(MAXJSAMPLE+1))    /* etc. */
  62. #define R_CB_OFF    (3*(MAXJSAMPLE+1))
  63. #define G_CB_OFF    (4*(MAXJSAMPLE+1))
  64. #define B_CB_OFF    (5*(MAXJSAMPLE+1))
  65. #define R_CR_OFF    B_CB_OFF        /* B=>Cb, R=>Cr are the same */
  66. #define G_CR_OFF    (6*(MAXJSAMPLE+1))
  67. #define B_CR_OFF    (7*(MAXJSAMPLE+1))
  68. #define TABLE_SIZE    (8*(MAXJSAMPLE+1))
  69.  
  70.  
  71. /*
  72.  * Initialize for colorspace conversion.
  73.  */
  74.  
  75. METHODDEF void
  76. rgb_ycc_init (compress_info_ptr cinfo)
  77. {
  78.   INT32 i;
  79.  
  80.   /* Allocate a workspace for the result of get_input_row. */
  81.   pixel_row = (*cinfo->emethods->alloc_small_sarray)
  82.         (cinfo->image_width, (long) cinfo->input_components);
  83.  
  84.   /* Allocate and fill in the conversion tables. */
  85.   rgb_ycc_tab = (INT32 *) (*cinfo->emethods->alloc_small)
  86.                 (TABLE_SIZE * SIZEOF(INT32));
  87.  
  88.   for (i = 0; i <= MAXJSAMPLE; i++) {
  89.     rgb_ycc_tab[i+R_Y_OFF] = FIX(0.29900) * i;
  90.     rgb_ycc_tab[i+G_Y_OFF] = FIX(0.58700) * i;
  91.     rgb_ycc_tab[i+B_Y_OFF] = FIX(0.11400) * i     + ONE_HALF;
  92.     rgb_ycc_tab[i+R_CB_OFF] = (-FIX(0.16874)) * i;
  93.     rgb_ycc_tab[i+G_CB_OFF] = (-FIX(0.33126)) * i;
  94.     rgb_ycc_tab[i+B_CB_OFF] = FIX(0.50000) * i    + ONE_HALF*(MAXJSAMPLE+1);
  95. /*  B=>Cb and R=>Cr tables are the same
  96.     rgb_ycc_tab[i+R_CR_OFF] = FIX(0.50000) * i    + ONE_HALF*(MAXJSAMPLE+1);
  97. */
  98.     rgb_ycc_tab[i+G_CR_OFF] = (-FIX(0.41869)) * i;
  99.     rgb_ycc_tab[i+B_CR_OFF] = (-FIX(0.08131)) * i;
  100.   }
  101. }
  102.  
  103.  
  104. /*
  105.  * Fetch some rows of pixels from get_input_row and convert to the
  106.  * JPEG colorspace.
  107.  */
  108.  
  109. METHODDEF void
  110. get_rgb_ycc_rows (compress_info_ptr cinfo,
  111.           int rows_to_read, JSAMPIMAGE image_data)
  112. {
  113. #ifdef SIXTEEN_BIT_SAMPLES
  114.   register UINT16 r, g, b;
  115. #else
  116.   register int r, g, b;
  117. #endif
  118.   register INT32 * ctab = rgb_ycc_tab;
  119.   register JSAMPROW inptr0, inptr1, inptr2;
  120.   register JSAMPROW outptr0, outptr1, outptr2;
  121.   register long col;
  122.   long width = cinfo->image_width;
  123.   int row;
  124.  
  125.   for (row = 0; row < rows_to_read; row++) {
  126.     /* Read one row from the source file */
  127.     (*cinfo->methods->get_input_row) (cinfo, pixel_row);
  128.     /* Convert colorspace */
  129.     inptr0 = pixel_row[0];
  130.     inptr1 = pixel_row[1];
  131.     inptr2 = pixel_row[2];
  132.     outptr0 = image_data[0][row];
  133.     outptr1 = image_data[1][row];
  134.     outptr2 = image_data[2][row];
  135.     for (col = 0; col < width; col++) {
  136.       r = GETJSAMPLE(inptr0[col]);
  137.       g = GETJSAMPLE(inptr1[col]);
  138.       b = GETJSAMPLE(inptr2[col]);
  139.       /* If the inputs are 0..MAXJSAMPLE, the outputs of these equations
  140.        * must be too; we do not need an explicit range-limiting operation.
  141.        * Hence the value being shifted is never negative, and we don't
  142.        * need the general RIGHT_SHIFT macro.
  143.        */
  144.       /* Y */
  145.       outptr0[col] = (JSAMPLE)
  146.         ((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF])
  147.          >> SCALEBITS);
  148.       /* Cb */
  149.       outptr1[col] = (JSAMPLE)
  150.         ((ctab[r+R_CB_OFF] + ctab[g+G_CB_OFF] + ctab[b+B_CB_OFF])
  151.          >> SCALEBITS);
  152.       /* Cr */
  153.       outptr2[col] = (JSAMPLE)
  154.         ((ctab[r+R_CR_OFF] + ctab[g+G_CR_OFF] + ctab[b+B_CR_OFF])
  155.          >> SCALEBITS);
  156.     }
  157.   }
  158. }
  159.  
  160.  
  161. /**************** Cases other than RGB -> YCbCr **************/
  162.  
  163.  
  164. /*
  165.  * Fetch some rows of pixels from get_input_row and convert to the
  166.  * JPEG colorspace.
  167.  * This version handles RGB->grayscale conversion, which is the same
  168.  * as the RGB->Y portion of RGB->YCbCr.
  169.  * We assume rgb_ycc_init has been called (we only use the Y tables).
  170.  */
  171.  
  172. METHODDEF void
  173. get_rgb_gray_rows (compress_info_ptr cinfo,
  174.            int rows_to_read, JSAMPIMAGE image_data)
  175. {
  176. #ifdef SIXTEEN_BIT_SAMPLES
  177.   register UINT16 r, g, b;
  178. #else
  179.   register int r, g, b;
  180. #endif
  181.   register INT32 * ctab = rgb_ycc_tab;
  182.   register JSAMPROW inptr0, inptr1, inptr2;
  183.   register JSAMPROW outptr;
  184.   register long col;
  185.   long width = cinfo->image_width;
  186.   int row;
  187.  
  188.   for (row = 0; row < rows_to_read; row++) {
  189.     /* Read one row from the source file */
  190.     (*cinfo->methods->get_input_row) (cinfo, pixel_row);
  191.     /* Convert colorspace */
  192.     inptr0 = pixel_row[0];
  193.     inptr1 = pixel_row[1];
  194.     inptr2 = pixel_row[2];
  195.     outptr = image_data[0][row];
  196.     for (col = 0; col < width; col++) {
  197.       r = GETJSAMPLE(inptr0[col]);
  198.       g = GETJSAMPLE(inptr1[col]);
  199.       b = GETJSAMPLE(inptr2[col]);
  200.       /* If the inputs are 0..MAXJSAMPLE, the outputs of these equations
  201.        * must be too; we do not need an explicit range-limiting operation.
  202.        * Hence the value being shifted is never negative, and we don't
  203.        * need the general RIGHT_SHIFT macro.
  204.        */
  205.       /* Y */
  206.       outptr[col] = (JSAMPLE)
  207.         ((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF])
  208.          >> SCALEBITS);
  209.     }
  210.   }
  211. }
  212.  
  213.  
  214. /*
  215.  * Initialize for colorspace conversion.
  216.  */
  217.  
  218. METHODDEF void
  219. colorin_init (compress_info_ptr cinfo)
  220. {
  221.   /* Allocate a workspace for the result of get_input_row. */
  222.   pixel_row = (*cinfo->emethods->alloc_small_sarray)
  223.         (cinfo->image_width, (long) cinfo->input_components);
  224. }
  225.  
  226.  
  227. /*
  228.  * Fetch some rows of pixels from get_input_row and convert to the
  229.  * JPEG colorspace.
  230.  * This version handles grayscale output with no conversion.
  231.  * The source can be either plain grayscale or YCbCr (since Y == gray).
  232.  */
  233.  
  234. METHODDEF void
  235. get_grayscale_rows (compress_info_ptr cinfo,
  236.             int rows_to_read, JSAMPIMAGE image_data)
  237. {
  238.   int row;
  239.  
  240.   for (row = 0; row < rows_to_read; row++) {
  241.     /* Read one row from the source file */
  242.     (*cinfo->methods->get_input_row) (cinfo, pixel_row);
  243.     /* Convert colorspace (gamma mapping needed here) */
  244.     jcopy_sample_rows(pixel_row, 0, image_data[0], row,
  245.               1, cinfo->image_width);
  246.   }
  247. }
  248.  
  249.  
  250. /*
  251.  * Fetch some rows of pixels from get_input_row and convert to the
  252.  * JPEG colorspace.
  253.  * This version handles multi-component colorspaces without conversion.
  254.  */
  255.  
  256. METHODDEF void
  257. get_noconvert_rows (compress_info_ptr cinfo,
  258.             int rows_to_read, JSAMPIMAGE image_data)
  259. {
  260.   int row, ci;
  261.  
  262.   for (row = 0; row < rows_to_read; row++) {
  263.     /* Read one row from the source file */
  264.     (*cinfo->methods->get_input_row) (cinfo, pixel_row);
  265.     /* Convert colorspace (gamma mapping needed here) */
  266.     for (ci = 0; ci < cinfo->input_components; ci++) {
  267.       jcopy_sample_rows(pixel_row, ci, image_data[ci], row,
  268.             1, cinfo->image_width);
  269.     }
  270.   }
  271. }
  272.  
  273.  
  274. /*
  275.  * Finish up at the end of the file.
  276.  */
  277.  
  278. METHODDEF void
  279. colorin_term (compress_info_ptr cinfo)
  280. {
  281.   /* no work (we let free_all release the workspace) */
  282. }
  283.  
  284.  
  285. /*
  286.  * The method selection routine for input colorspace conversion.
  287.  */
  288.  
  289. GLOBAL void
  290. jselccolor (compress_info_ptr cinfo)
  291. {
  292.   /* Make sure input_components agrees with in_color_space */
  293.   switch (cinfo->in_color_space) {
  294.   case CS_GRAYSCALE:
  295.     if (cinfo->input_components != 1)
  296.       ERREXIT(cinfo->emethods, "Bogus input colorspace");
  297.     break;
  298.  
  299.   case CS_RGB:
  300.   case CS_YCbCr:
  301.   case CS_YIQ:
  302.     if (cinfo->input_components != 3)
  303.       ERREXIT(cinfo->emethods, "Bogus input colorspace");
  304.     break;
  305.  
  306.   case CS_CMYK:
  307.     if (cinfo->input_components != 4)
  308.       ERREXIT(cinfo->emethods, "Bogus input colorspace");
  309.     break;
  310.  
  311.   default:
  312.     ERREXIT(cinfo->emethods, "Unsupported input colorspace");
  313.     break;
  314.   }
  315.  
  316.   /* Standard init/term methods (may override below) */
  317.   cinfo->methods->colorin_init = colorin_init;
  318.   cinfo->methods->colorin_term = colorin_term;
  319.  
  320.   /* Check num_components, set conversion method based on requested space */
  321.   switch (cinfo->jpeg_color_space) {
  322.   case CS_GRAYSCALE:
  323.     if (cinfo->num_components != 1)
  324.       ERREXIT(cinfo->emethods, "Bogus JPEG colorspace");
  325.     if (cinfo->in_color_space == CS_GRAYSCALE)
  326.       cinfo->methods->get_sample_rows = get_grayscale_rows;
  327.     else if (cinfo->in_color_space == CS_RGB) {
  328.       cinfo->methods->colorin_init = rgb_ycc_init;
  329.       cinfo->methods->get_sample_rows = get_rgb_gray_rows;
  330.     } else if (cinfo->in_color_space == CS_YCbCr)
  331.       cinfo->methods->get_sample_rows = get_grayscale_rows;
  332.     else
  333.       ERREXIT(cinfo->emethods, "Unsupported color conversion request");
  334.     break;
  335.  
  336.   case CS_YCbCr:
  337.     if (cinfo->num_components != 3)
  338.       ERREXIT(cinfo->emethods, "Bogus JPEG colorspace");
  339.     if (cinfo->in_color_space == CS_RGB) {
  340.       cinfo->methods->colorin_init = rgb_ycc_init;
  341.       cinfo->methods->get_sample_rows = get_rgb_ycc_rows;
  342.     } else if (cinfo->in_color_space == CS_YCbCr)
  343.       cinfo->methods->get_sample_rows = get_noconvert_rows;
  344.     else
  345.       ERREXIT(cinfo->emethods, "Unsupported color conversion request");
  346.     break;
  347.  
  348.   case CS_CMYK:
  349.     if (cinfo->num_components != 4)
  350.       ERREXIT(cinfo->emethods, "Bogus JPEG colorspace");
  351.     if (cinfo->in_color_space == CS_CMYK)
  352.       cinfo->methods->get_sample_rows = get_noconvert_rows;
  353.     else
  354.       ERREXIT(cinfo->emethods, "Unsupported color conversion request");
  355.     break;
  356.  
  357.   default:
  358.     ERREXIT(cinfo->emethods, "Unsupported JPEG colorspace");
  359.     break;
  360.   }
  361. }
  362.