Doxygen Source Code Documentation
        
Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Search   
jccolor.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_converter pub; 
00020 
00021   
00022   INT32 * rgb_ycc_tab;          
00023 } my_color_converter;
00024 
00025 typedef my_color_converter * my_cconvert_ptr;
00026 
00027 
00028 
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 #define SCALEBITS       16      
00059 #define CBCR_OFFSET     ((INT32) CENTERJSAMPLE << SCALEBITS)
00060 #define ONE_HALF        ((INT32) 1 << (SCALEBITS-1))
00061 #define FIX(x)          ((INT32) ((x) * (1L<<SCALEBITS) + 0.5))
00062 
00063 
00064 
00065 
00066 
00067 
00068 
00069 #define R_Y_OFF         0                       
00070 #define G_Y_OFF         (1*(MAXJSAMPLE+1))      
00071 #define B_Y_OFF         (2*(MAXJSAMPLE+1))      
00072 #define R_CB_OFF        (3*(MAXJSAMPLE+1))
00073 #define G_CB_OFF        (4*(MAXJSAMPLE+1))
00074 #define B_CB_OFF        (5*(MAXJSAMPLE+1))
00075 #define R_CR_OFF        B_CB_OFF                
00076 #define G_CR_OFF        (6*(MAXJSAMPLE+1))
00077 #define B_CR_OFF        (7*(MAXJSAMPLE+1))
00078 #define TABLE_SIZE      (8*(MAXJSAMPLE+1))
00079 
00080 
00081 
00082 
00083 
00084 
00085 METHODDEF(void)
00086 rgb_ycc_start (j_compress_ptr cinfo)
00087 {
00088   my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
00089   INT32 * rgb_ycc_tab;
00090   INT32 i;
00091 
00092   
00093   cconvert->rgb_ycc_tab = rgb_ycc_tab = (INT32 *)
00094     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00095                                 (TABLE_SIZE * SIZEOF(INT32)));
00096 
00097   for (i = 0; i <= MAXJSAMPLE; i++) {
00098     rgb_ycc_tab[i+R_Y_OFF] = FIX(0.29900) * i;
00099     rgb_ycc_tab[i+G_Y_OFF] = FIX(0.58700) * i;
00100     rgb_ycc_tab[i+B_Y_OFF] = FIX(0.11400) * i     + ONE_HALF;
00101     rgb_ycc_tab[i+R_CB_OFF] = (-FIX(0.16874)) * i;
00102     rgb_ycc_tab[i+G_CB_OFF] = (-FIX(0.33126)) * i;
00103     
00104 
00105 
00106 
00107     rgb_ycc_tab[i+B_CB_OFF] = FIX(0.50000) * i    + CBCR_OFFSET + ONE_HALF-1;
00108 
00109 
00110 
00111     rgb_ycc_tab[i+G_CR_OFF] = (-FIX(0.41869)) * i;
00112     rgb_ycc_tab[i+B_CR_OFF] = (-FIX(0.08131)) * i;
00113   }
00114 }
00115 
00116 
00117 
00118 
00119 
00120 
00121 
00122 
00123 
00124 
00125 
00126 
00127 
00128 
00129 METHODDEF(void)
00130 rgb_ycc_convert (j_compress_ptr cinfo,
00131                  JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
00132                  JDIMENSION output_row, int num_rows)
00133 {
00134   my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
00135   register int r, g, b;
00136   register INT32 * ctab = cconvert->rgb_ycc_tab;
00137   register JSAMPROW inptr;
00138   register JSAMPROW outptr0, outptr1, outptr2;
00139   register JDIMENSION col;
00140   JDIMENSION num_cols = cinfo->image_width;
00141 
00142   while (--num_rows >= 0) {
00143     inptr = *input_buf++;
00144     outptr0 = output_buf[0][output_row];
00145     outptr1 = output_buf[1][output_row];
00146     outptr2 = output_buf[2][output_row];
00147     output_row++;
00148     for (col = 0; col < num_cols; col++) {
00149       r = GETJSAMPLE(inptr[RGB_RED]);
00150       g = GETJSAMPLE(inptr[RGB_GREEN]);
00151       b = GETJSAMPLE(inptr[RGB_BLUE]);
00152       inptr += RGB_PIXELSIZE;
00153       
00154 
00155 
00156 
00157 
00158       
00159       outptr0[col] = (JSAMPLE)
00160                 ((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF])
00161                  >> SCALEBITS);
00162       
00163       outptr1[col] = (JSAMPLE)
00164                 ((ctab[r+R_CB_OFF] + ctab[g+G_CB_OFF] + ctab[b+B_CB_OFF])
00165                  >> SCALEBITS);
00166       
00167       outptr2[col] = (JSAMPLE)
00168                 ((ctab[r+R_CR_OFF] + ctab[g+G_CR_OFF] + ctab[b+B_CR_OFF])
00169                  >> SCALEBITS);
00170     }
00171   }
00172 }
00173 
00174 
00175 
00176 
00177 
00178 
00179 
00180 
00181 
00182 
00183 
00184 
00185 METHODDEF(void)
00186 rgb_gray_convert (j_compress_ptr cinfo,
00187                   JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
00188                   JDIMENSION output_row, int num_rows)
00189 {
00190   my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
00191   register int r, g, b;
00192   register INT32 * ctab = cconvert->rgb_ycc_tab;
00193   register JSAMPROW inptr;
00194   register JSAMPROW outptr;
00195   register JDIMENSION col;
00196   JDIMENSION num_cols = cinfo->image_width;
00197 
00198   while (--num_rows >= 0) {
00199     inptr = *input_buf++;
00200     outptr = output_buf[0][output_row];
00201     output_row++;
00202     for (col = 0; col < num_cols; col++) {
00203       r = GETJSAMPLE(inptr[RGB_RED]);
00204       g = GETJSAMPLE(inptr[RGB_GREEN]);
00205       b = GETJSAMPLE(inptr[RGB_BLUE]);
00206       inptr += RGB_PIXELSIZE;
00207       
00208       outptr[col] = (JSAMPLE)
00209                 ((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF])
00210                  >> SCALEBITS);
00211     }
00212   }
00213 }
00214 
00215 
00216 
00217 
00218 
00219 
00220 
00221 
00222 
00223 
00224 METHODDEF(void)
00225 cmyk_ycck_convert (j_compress_ptr cinfo,
00226                    JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
00227                    JDIMENSION output_row, int num_rows)
00228 {
00229   my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
00230   register int r, g, b;
00231   register INT32 * ctab = cconvert->rgb_ycc_tab;
00232   register JSAMPROW inptr;
00233   register JSAMPROW outptr0, outptr1, outptr2, outptr3;
00234   register JDIMENSION col;
00235   JDIMENSION num_cols = cinfo->image_width;
00236 
00237   while (--num_rows >= 0) {
00238     inptr = *input_buf++;
00239     outptr0 = output_buf[0][output_row];
00240     outptr1 = output_buf[1][output_row];
00241     outptr2 = output_buf[2][output_row];
00242     outptr3 = output_buf[3][output_row];
00243     output_row++;
00244     for (col = 0; col < num_cols; col++) {
00245       r = MAXJSAMPLE - GETJSAMPLE(inptr[0]);
00246       g = MAXJSAMPLE - GETJSAMPLE(inptr[1]);
00247       b = MAXJSAMPLE - GETJSAMPLE(inptr[2]);
00248       
00249       outptr3[col] = inptr[3];  
00250       inptr += 4;
00251       
00252 
00253 
00254 
00255 
00256       
00257       outptr0[col] = (JSAMPLE)
00258                 ((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF])
00259                  >> SCALEBITS);
00260       
00261       outptr1[col] = (JSAMPLE)
00262                 ((ctab[r+R_CB_OFF] + ctab[g+G_CB_OFF] + ctab[b+B_CB_OFF])
00263                  >> SCALEBITS);
00264       
00265       outptr2[col] = (JSAMPLE)
00266                 ((ctab[r+R_CR_OFF] + ctab[g+G_CR_OFF] + ctab[b+B_CR_OFF])
00267                  >> SCALEBITS);
00268     }
00269   }
00270 }
00271 
00272 
00273 
00274 
00275 
00276 
00277 
00278 
00279 METHODDEF(void)
00280 grayscale_convert (j_compress_ptr cinfo,
00281                    JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
00282                    JDIMENSION output_row, int num_rows)
00283 {
00284   register JSAMPROW inptr;
00285   register JSAMPROW outptr;
00286   register JDIMENSION col;
00287   JDIMENSION num_cols = cinfo->image_width;
00288   int instride = cinfo->input_components;
00289 
00290   while (--num_rows >= 0) {
00291     inptr = *input_buf++;
00292     outptr = output_buf[0][output_row];
00293     output_row++;
00294     for (col = 0; col < num_cols; col++) {
00295       outptr[col] = inptr[0];   
00296       inptr += instride;
00297     }
00298   }
00299 }
00300 
00301 
00302 
00303 
00304 
00305 
00306 
00307 
00308 METHODDEF(void)
00309 null_convert (j_compress_ptr cinfo,
00310               JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
00311               JDIMENSION output_row, int num_rows)
00312 {
00313   register JSAMPROW inptr;
00314   register JSAMPROW outptr;
00315   register JDIMENSION col;
00316   register int ci;
00317   int nc = cinfo->num_components;
00318   JDIMENSION num_cols = cinfo->image_width;
00319 
00320   while (--num_rows >= 0) {
00321     
00322     for (ci = 0; ci < nc; ci++) {
00323       inptr = *input_buf;
00324       outptr = output_buf[ci][output_row];
00325       for (col = 0; col < num_cols; col++) {
00326         outptr[col] = inptr[ci]; 
00327         inptr += nc;
00328       }
00329     }
00330     input_buf++;
00331     output_row++;
00332   }
00333 }
00334 
00335 
00336 
00337 
00338 
00339 
00340 METHODDEF(void)
00341 null_method (j_compress_ptr cinfo)
00342 {
00343   
00344 }
00345 
00346 
00347 
00348 
00349 
00350 
00351 GLOBAL(void)
00352 jinit_color_converter (j_compress_ptr cinfo)
00353 {
00354   my_cconvert_ptr cconvert;
00355 
00356   cconvert = (my_cconvert_ptr)
00357     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00358                                 SIZEOF(my_color_converter));
00359   cinfo->cconvert = (struct jpeg_color_converter *) cconvert;
00360   
00361   cconvert->pub.start_pass = null_method;
00362 
00363   
00364   switch (cinfo->in_color_space) {
00365   case JCS_GRAYSCALE:
00366     if (cinfo->input_components != 1)
00367       ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
00368     break;
00369 
00370   case JCS_RGB:
00371 #if RGB_PIXELSIZE != 3
00372     if (cinfo->input_components != RGB_PIXELSIZE)
00373       ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
00374     break;
00375 #endif 
00376 
00377   case JCS_YCbCr:
00378     if (cinfo->input_components != 3)
00379       ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
00380     break;
00381 
00382   case JCS_CMYK:
00383   case JCS_YCCK:
00384     if (cinfo->input_components != 4)
00385       ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
00386     break;
00387 
00388   default:                      
00389     if (cinfo->input_components < 1)
00390       ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
00391     break;
00392   }
00393 
00394   
00395   switch (cinfo->jpeg_color_space) {
00396   case JCS_GRAYSCALE:
00397     if (cinfo->num_components != 1)
00398       ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
00399     if (cinfo->in_color_space == JCS_GRAYSCALE)
00400       cconvert->pub.color_convert = grayscale_convert;
00401     else if (cinfo->in_color_space == JCS_RGB) {
00402       cconvert->pub.start_pass = rgb_ycc_start;
00403       cconvert->pub.color_convert = rgb_gray_convert;
00404     } else if (cinfo->in_color_space == JCS_YCbCr)
00405       cconvert->pub.color_convert = grayscale_convert;
00406     else
00407       ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
00408     break;
00409 
00410   case JCS_RGB:
00411     if (cinfo->num_components != 3)
00412       ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
00413     if (cinfo->in_color_space == JCS_RGB && RGB_PIXELSIZE == 3)
00414       cconvert->pub.color_convert = null_convert;
00415     else
00416       ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
00417     break;
00418 
00419   case JCS_YCbCr:
00420     if (cinfo->num_components != 3)
00421       ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
00422     if (cinfo->in_color_space == JCS_RGB) {
00423       cconvert->pub.start_pass = rgb_ycc_start;
00424       cconvert->pub.color_convert = rgb_ycc_convert;
00425     } else if (cinfo->in_color_space == JCS_YCbCr)
00426       cconvert->pub.color_convert = null_convert;
00427     else
00428       ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
00429     break;
00430 
00431   case JCS_CMYK:
00432     if (cinfo->num_components != 4)
00433       ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
00434     if (cinfo->in_color_space == JCS_CMYK)
00435       cconvert->pub.color_convert = null_convert;
00436     else
00437       ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
00438     break;
00439 
00440   case JCS_YCCK:
00441     if (cinfo->num_components != 4)
00442       ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
00443     if (cinfo->in_color_space == JCS_CMYK) {
00444       cconvert->pub.start_pass = rgb_ycc_start;
00445       cconvert->pub.color_convert = cmyk_ycck_convert;
00446     } else if (cinfo->in_color_space == JCS_YCCK)
00447       cconvert->pub.color_convert = null_convert;
00448     else
00449       ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
00450     break;
00451 
00452   default:                      
00453     if (cinfo->jpeg_color_space != cinfo->in_color_space ||
00454         cinfo->num_components != cinfo->input_components)
00455       ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
00456     cconvert->pub.color_convert = null_convert;
00457     break;
00458   }
00459 }