Doxygen Source Code Documentation
        
Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Search   
jdcolor.c
Go to the documentation of this file.00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 #define JPEG_INTERNALS
00012 #include "jinclude.h"
00013 #include "jpeglib.h"
00014 
00015 
00016 
00017 
00018 typedef struct {
00019   struct jpeg_color_deconverter pub; 
00020 
00021   
00022   int * Cr_r_tab;               
00023   int * Cb_b_tab;               
00024   INT32 * Cr_g_tab;             
00025   INT32 * Cb_g_tab;             
00026 } my_color_deconverter;
00027 
00028 typedef my_color_deconverter * my_cconvert_ptr;
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 
00042 
00043 
00044 
00045 
00046 
00047 
00048 
00049 
00050 
00051 
00052 
00053 
00054 
00055 
00056 
00057 
00058 
00059 
00060 #define SCALEBITS       16      
00061 #define ONE_HALF        ((INT32) 1 << (SCALEBITS-1))
00062 #define FIX(x)          ((INT32) ((x) * (1L<<SCALEBITS) + 0.5))
00063 
00064 
00065 
00066 
00067 
00068 
00069 LOCAL(void)
00070 build_ycc_rgb_table (j_decompress_ptr cinfo)
00071 {
00072   my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
00073   int i;
00074   INT32 x;
00075   SHIFT_TEMPS
00076 
00077   cconvert->Cr_r_tab = (int *)
00078     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00079                                 (MAXJSAMPLE+1) * SIZEOF(int));
00080   cconvert->Cb_b_tab = (int *)
00081     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00082                                 (MAXJSAMPLE+1) * SIZEOF(int));
00083   cconvert->Cr_g_tab = (INT32 *)
00084     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00085                                 (MAXJSAMPLE+1) * SIZEOF(INT32));
00086   cconvert->Cb_g_tab = (INT32 *)
00087     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00088                                 (MAXJSAMPLE+1) * SIZEOF(INT32));
00089 
00090   for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {
00091     
00092     
00093     
00094     cconvert->Cr_r_tab[i] = (int)
00095                     RIGHT_SHIFT(FIX(1.40200) * x + ONE_HALF, SCALEBITS);
00096     
00097     cconvert->Cb_b_tab[i] = (int)
00098                     RIGHT_SHIFT(FIX(1.77200) * x + ONE_HALF, SCALEBITS);
00099     
00100     cconvert->Cr_g_tab[i] = (- FIX(0.71414)) * x;
00101     
00102     
00103     cconvert->Cb_g_tab[i] = (- FIX(0.34414)) * x + ONE_HALF;
00104   }
00105 }
00106 
00107 
00108 
00109 
00110 
00111 
00112 
00113 
00114 
00115 
00116 
00117 
00118 
00119 METHODDEF(void)
00120 ycc_rgb_convert (j_decompress_ptr cinfo,
00121                  JSAMPIMAGE input_buf, JDIMENSION input_row,
00122                  JSAMPARRAY output_buf, int num_rows)
00123 {
00124   my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
00125   register int y, cb, cr;
00126   register JSAMPROW outptr;
00127   register JSAMPROW inptr0, inptr1, inptr2;
00128   register JDIMENSION col;
00129   JDIMENSION num_cols = cinfo->output_width;
00130   
00131   register JSAMPLE * range_limit = cinfo->sample_range_limit;
00132   register int * Crrtab = cconvert->Cr_r_tab;
00133   register int * Cbbtab = cconvert->Cb_b_tab;
00134   register INT32 * Crgtab = cconvert->Cr_g_tab;
00135   register INT32 * Cbgtab = cconvert->Cb_g_tab;
00136   SHIFT_TEMPS
00137 
00138   while (--num_rows >= 0) {
00139     inptr0 = input_buf[0][input_row];
00140     inptr1 = input_buf[1][input_row];
00141     inptr2 = input_buf[2][input_row];
00142     input_row++;
00143     outptr = *output_buf++;
00144     for (col = 0; col < num_cols; col++) {
00145       y  = GETJSAMPLE(inptr0[col]);
00146       cb = GETJSAMPLE(inptr1[col]);
00147       cr = GETJSAMPLE(inptr2[col]);
00148       
00149       outptr[RGB_RED] =   range_limit[y + Crrtab[cr]];
00150       outptr[RGB_GREEN] = range_limit[y +
00151                               ((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
00152                                                  SCALEBITS))];
00153       outptr[RGB_BLUE] =  range_limit[y + Cbbtab[cb]];
00154       outptr += RGB_PIXELSIZE;
00155     }
00156   }
00157 }
00158 
00159 
00160 
00161 
00162 
00163 
00164 
00165 
00166 
00167 
00168 METHODDEF(void)
00169 null_convert (j_decompress_ptr cinfo,
00170               JSAMPIMAGE input_buf, JDIMENSION input_row,
00171               JSAMPARRAY output_buf, int num_rows)
00172 {
00173   register JSAMPROW inptr, outptr;
00174   register JDIMENSION count;
00175   register int num_components = cinfo->num_components;
00176   JDIMENSION num_cols = cinfo->output_width;
00177   int ci;
00178 
00179   while (--num_rows >= 0) {
00180     for (ci = 0; ci < num_components; ci++) {
00181       inptr = input_buf[ci][input_row];
00182       outptr = output_buf[0] + ci;
00183       for (count = num_cols; count > 0; count--) {
00184         *outptr = *inptr++;     
00185         outptr += num_components;
00186       }
00187     }
00188     input_row++;
00189     output_buf++;
00190   }
00191 }
00192 
00193 
00194 
00195 
00196 
00197 
00198 
00199 
00200 METHODDEF(void)
00201 grayscale_convert (j_decompress_ptr cinfo,
00202                    JSAMPIMAGE input_buf, JDIMENSION input_row,
00203                    JSAMPARRAY output_buf, int num_rows)
00204 {
00205   jcopy_sample_rows(input_buf[0], (int) input_row, output_buf, 0,
00206                     num_rows, cinfo->output_width);
00207 }
00208 
00209 
00210 
00211 
00212 
00213 
00214 
00215 
00216 METHODDEF(void)
00217 gray_rgb_convert (j_decompress_ptr cinfo,
00218                   JSAMPIMAGE input_buf, JDIMENSION input_row,
00219                   JSAMPARRAY output_buf, int num_rows)
00220 {
00221   register JSAMPROW inptr, outptr;
00222   register JDIMENSION col;
00223   JDIMENSION num_cols = cinfo->output_width;
00224 
00225   while (--num_rows >= 0) {
00226     inptr = input_buf[0][input_row++];
00227     outptr = *output_buf++;
00228     for (col = 0; col < num_cols; col++) {
00229       
00230       outptr[RGB_RED] = outptr[RGB_GREEN] = outptr[RGB_BLUE] = inptr[col];
00231       outptr += RGB_PIXELSIZE;
00232     }
00233   }
00234 }
00235 
00236 
00237 
00238 
00239 
00240 
00241 
00242 
00243 
00244 METHODDEF(void)
00245 ycck_cmyk_convert (j_decompress_ptr cinfo,
00246                    JSAMPIMAGE input_buf, JDIMENSION input_row,
00247                    JSAMPARRAY output_buf, int num_rows)
00248 {
00249   my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
00250   register int y, cb, cr;
00251   register JSAMPROW outptr;
00252   register JSAMPROW inptr0, inptr1, inptr2, inptr3;
00253   register JDIMENSION col;
00254   JDIMENSION num_cols = cinfo->output_width;
00255   
00256   register JSAMPLE * range_limit = cinfo->sample_range_limit;
00257   register int * Crrtab = cconvert->Cr_r_tab;
00258   register int * Cbbtab = cconvert->Cb_b_tab;
00259   register INT32 * Crgtab = cconvert->Cr_g_tab;
00260   register INT32 * Cbgtab = cconvert->Cb_g_tab;
00261   SHIFT_TEMPS
00262 
00263   while (--num_rows >= 0) {
00264     inptr0 = input_buf[0][input_row];
00265     inptr1 = input_buf[1][input_row];
00266     inptr2 = input_buf[2][input_row];
00267     inptr3 = input_buf[3][input_row];
00268     input_row++;
00269     outptr = *output_buf++;
00270     for (col = 0; col < num_cols; col++) {
00271       y  = GETJSAMPLE(inptr0[col]);
00272       cb = GETJSAMPLE(inptr1[col]);
00273       cr = GETJSAMPLE(inptr2[col]);
00274       
00275       outptr[0] = range_limit[MAXJSAMPLE - (y + Crrtab[cr])];   
00276       outptr[1] = range_limit[MAXJSAMPLE - (y +                 
00277                               ((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
00278                                                  SCALEBITS)))];
00279       outptr[2] = range_limit[MAXJSAMPLE - (y + Cbbtab[cb])];   
00280       
00281       outptr[3] = inptr3[col];  
00282       outptr += 4;
00283     }
00284   }
00285 }
00286 
00287 
00288 
00289 
00290 
00291 
00292 METHODDEF(void)
00293 start_pass_dcolor (j_decompress_ptr cinfo)
00294 {
00295   
00296 }
00297 
00298 
00299 
00300 
00301 
00302 
00303 GLOBAL(void)
00304 jinit_color_deconverter (j_decompress_ptr cinfo)
00305 {
00306   my_cconvert_ptr cconvert;
00307   int ci;
00308 
00309   cconvert = (my_cconvert_ptr)
00310     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00311                                 SIZEOF(my_color_deconverter));
00312   cinfo->cconvert = (struct jpeg_color_deconverter *) cconvert;
00313   cconvert->pub.start_pass = start_pass_dcolor;
00314 
00315   
00316   switch (cinfo->jpeg_color_space) {
00317   case JCS_GRAYSCALE:
00318     if (cinfo->num_components != 1)
00319       ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
00320     break;
00321 
00322   case JCS_RGB:
00323   case JCS_YCbCr:
00324     if (cinfo->num_components != 3)
00325       ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
00326     break;
00327 
00328   case JCS_CMYK:
00329   case JCS_YCCK:
00330     if (cinfo->num_components != 4)
00331       ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
00332     break;
00333 
00334   default:                      
00335     if (cinfo->num_components < 1)
00336       ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
00337     break;
00338   }
00339 
00340   
00341 
00342 
00343 
00344 
00345   switch (cinfo->out_color_space) {
00346   case JCS_GRAYSCALE:
00347     cinfo->out_color_components = 1;
00348     if (cinfo->jpeg_color_space == JCS_GRAYSCALE ||
00349         cinfo->jpeg_color_space == JCS_YCbCr) {
00350       cconvert->pub.color_convert = grayscale_convert;
00351       
00352       for (ci = 1; ci < cinfo->num_components; ci++)
00353         cinfo->comp_info[ci].component_needed = FALSE;
00354     } else
00355       ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
00356     break;
00357 
00358   case JCS_RGB:
00359     cinfo->out_color_components = RGB_PIXELSIZE;
00360     if (cinfo->jpeg_color_space == JCS_YCbCr) {
00361       cconvert->pub.color_convert = ycc_rgb_convert;
00362       build_ycc_rgb_table(cinfo);
00363     } else if (cinfo->jpeg_color_space == JCS_GRAYSCALE) {
00364       cconvert->pub.color_convert = gray_rgb_convert;
00365     } else if (cinfo->jpeg_color_space == JCS_RGB && RGB_PIXELSIZE == 3) {
00366       cconvert->pub.color_convert = null_convert;
00367     } else
00368       ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
00369     break;
00370 
00371   case JCS_CMYK:
00372     cinfo->out_color_components = 4;
00373     if (cinfo->jpeg_color_space == JCS_YCCK) {
00374       cconvert->pub.color_convert = ycck_cmyk_convert;
00375       build_ycc_rgb_table(cinfo);
00376     } else if (cinfo->jpeg_color_space == JCS_CMYK) {
00377       cconvert->pub.color_convert = null_convert;
00378     } else
00379       ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
00380     break;
00381 
00382   default:
00383     
00384     if (cinfo->out_color_space == cinfo->jpeg_color_space) {
00385       cinfo->out_color_components = cinfo->num_components;
00386       cconvert->pub.color_convert = null_convert;
00387     } else                      
00388       ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
00389     break;
00390   }
00391 
00392   if (cinfo->quantize_colors)
00393     cinfo->output_components = 1; 
00394   else
00395     cinfo->output_components = cinfo->out_color_components;
00396 }