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
00169 extern unsigned short int *jpeg_out_buffer_pos;
00170
00171 METHODDEF(void)
00172 ycc_rgb565_convert (j_decompress_ptr cinfo,
00173 JSAMPIMAGE input_buf, JDIMENSION input_row,
00174 JSAMPARRAY output_buf, int num_rows)
00175 {
00176 my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
00177 register int y, cb, cr;
00178
00179 register JSAMPROW inptr0, inptr1, inptr2;
00180 register JDIMENSION col;
00181 JDIMENSION num_cols = cinfo->output_width;
00182
00183 register JSAMPLE * range_limit = cinfo->sample_range_limit;
00184 register int * Crrtab = cconvert->Cr_r_tab;
00185 register int * Cbbtab = cconvert->Cb_b_tab;
00186 register INT32 * Crgtab = cconvert->Cr_g_tab;
00187 register INT32 * Cbgtab = cconvert->Cb_g_tab;
00188 SHIFT_TEMPS
00189 JSAMPLE red, green, blue;
00190
00191 while (--num_rows >= 0) {
00192 inptr0 = input_buf[0][input_row];
00193 inptr1 = input_buf[1][input_row];
00194 inptr2 = input_buf[2][input_row];
00195 input_row++;
00196
00197 for (col = 0; col < num_cols; col++) {
00198 y = GETJSAMPLE(inptr0[col]);
00199 cb = GETJSAMPLE(inptr1[col]);
00200 cr = GETJSAMPLE(inptr2[col]);
00201
00202 red = range_limit[y + Crrtab[cr]];
00203 green = range_limit[y + ((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS))];
00204 blue = range_limit[y + Cbbtab[cb]];
00205 *jpeg_out_buffer_pos = ((red >> 3) & 0x1F) << 11
00206 | (((green >> 2) & 0x3F) << 5)
00207 | ((blue >> 3) & 0x1F);
00208
00209
00210
00211
00212
00213
00214
00215 jpeg_out_buffer_pos++;
00216 }
00217 }
00218 }
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228 METHODDEF(void)
00229 null_convert (j_decompress_ptr cinfo,
00230 JSAMPIMAGE input_buf, JDIMENSION input_row,
00231 JSAMPARRAY output_buf, int num_rows)
00232 {
00233 register JSAMPROW inptr, outptr;
00234 register JDIMENSION count;
00235 register int num_components = cinfo->num_components;
00236 JDIMENSION num_cols = cinfo->output_width;
00237 int ci;
00238
00239 while (--num_rows >= 0) {
00240 for (ci = 0; ci < num_components; ci++) {
00241 inptr = input_buf[ci][input_row];
00242 outptr = output_buf[0] + ci;
00243 for (count = num_cols; count > 0; count--) {
00244 *outptr = *inptr++;
00245 outptr += num_components;
00246 }
00247 }
00248 input_row++;
00249 output_buf++;
00250 }
00251 }
00252
00253
00254
00255
00256
00257
00258
00259
00260 METHODDEF(void)
00261 grayscale_convert (j_decompress_ptr cinfo,
00262 JSAMPIMAGE input_buf, JDIMENSION input_row,
00263 JSAMPARRAY output_buf, int num_rows)
00264 {
00265 jcopy_sample_rows(input_buf[0], (int) input_row, output_buf, 0,
00266 num_rows, cinfo->output_width);
00267 }
00268
00269
00270
00271
00272
00273
00274
00275
00276 METHODDEF(void)
00277 gray_rgb_convert (j_decompress_ptr cinfo,
00278 JSAMPIMAGE input_buf, JDIMENSION input_row,
00279 JSAMPARRAY output_buf, int num_rows)
00280 {
00281 register JSAMPROW inptr, outptr;
00282 register JDIMENSION col;
00283 JDIMENSION num_cols = cinfo->output_width;
00284
00285 while (--num_rows >= 0) {
00286 inptr = input_buf[0][input_row++];
00287 outptr = *output_buf++;
00288 for (col = 0; col < num_cols; col++) {
00289
00290 outptr[RGB_RED] = outptr[RGB_GREEN] = outptr[RGB_BLUE] = inptr[col];
00291 outptr += RGB_PIXELSIZE;
00292 }
00293 }
00294 }
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304 METHODDEF(void)
00305 ycck_cmyk_convert (j_decompress_ptr cinfo,
00306 JSAMPIMAGE input_buf, JDIMENSION input_row,
00307 JSAMPARRAY output_buf, int num_rows)
00308 {
00309 my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
00310 register int y, cb, cr;
00311 register JSAMPROW outptr;
00312 register JSAMPROW inptr0, inptr1, inptr2, inptr3;
00313 register JDIMENSION col;
00314 JDIMENSION num_cols = cinfo->output_width;
00315
00316 register JSAMPLE * range_limit = cinfo->sample_range_limit;
00317 register int * Crrtab = cconvert->Cr_r_tab;
00318 register int * Cbbtab = cconvert->Cb_b_tab;
00319 register INT32 * Crgtab = cconvert->Cr_g_tab;
00320 register INT32 * Cbgtab = cconvert->Cb_g_tab;
00321 SHIFT_TEMPS
00322
00323 while (--num_rows >= 0) {
00324 inptr0 = input_buf[0][input_row];
00325 inptr1 = input_buf[1][input_row];
00326 inptr2 = input_buf[2][input_row];
00327 inptr3 = input_buf[3][input_row];
00328 input_row++;
00329 outptr = *output_buf++;
00330 for (col = 0; col < num_cols; col++) {
00331 y = GETJSAMPLE(inptr0[col]);
00332 cb = GETJSAMPLE(inptr1[col]);
00333 cr = GETJSAMPLE(inptr2[col]);
00334
00335 outptr[0] = range_limit[MAXJSAMPLE - (y + Crrtab[cr])];
00336 outptr[1] = range_limit[MAXJSAMPLE - (y +
00337 ((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
00338 SCALEBITS)))];
00339 outptr[2] = range_limit[MAXJSAMPLE - (y + Cbbtab[cb])];
00340
00341 outptr[3] = inptr3[col];
00342 outptr += 4;
00343 }
00344 }
00345 }
00346
00347
00348
00349
00350
00351
00352 METHODDEF(void)
00353 start_pass_dcolor (j_decompress_ptr cinfo)
00354 {
00355
00356 }
00357
00358
00359
00360
00361
00362
00363 GLOBAL(void)
00364 jinit_color_deconverter (j_decompress_ptr cinfo)
00365 {
00366 my_cconvert_ptr cconvert;
00367 int ci;
00368
00369 cconvert = (my_cconvert_ptr)
00370 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00371 SIZEOF(my_color_deconverter));
00372 cinfo->cconvert = (struct jpeg_color_deconverter *) cconvert;
00373 cconvert->pub.start_pass = start_pass_dcolor;
00374
00375
00376 switch (cinfo->jpeg_color_space) {
00377 case JCS_GRAYSCALE:
00378 if (cinfo->num_components != 1)
00379 ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
00380 break;
00381
00382 case JCS_RGB:
00383 case JCS_RGB565:
00384 case JCS_YCbCr:
00385 if (cinfo->num_components != 3)
00386 ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
00387 break;
00388
00389 case JCS_CMYK:
00390 case JCS_YCCK:
00391 if (cinfo->num_components != 4)
00392 ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
00393 break;
00394
00395 default:
00396 if (cinfo->num_components < 1)
00397 ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
00398 break;
00399 }
00400
00401
00402
00403
00404
00405
00406 switch (cinfo->out_color_space) {
00407 case JCS_GRAYSCALE:
00408 cinfo->out_color_components = 1;
00409 if (cinfo->jpeg_color_space == JCS_GRAYSCALE ||
00410 cinfo->jpeg_color_space == JCS_YCbCr) {
00411 cconvert->pub.color_convert = grayscale_convert;
00412
00413 for (ci = 1; ci < cinfo->num_components; ci++)
00414 cinfo->comp_info[ci].component_needed = FALSE;
00415 } else
00416 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
00417 break;
00418
00419 case JCS_RGB:
00420 cinfo->out_color_components = RGB_PIXELSIZE;
00421 if (cinfo->jpeg_color_space == JCS_YCbCr) {
00422 cconvert->pub.color_convert = ycc_rgb_convert;
00423 build_ycc_rgb_table(cinfo);
00424 } else if (cinfo->jpeg_color_space == JCS_GRAYSCALE) {
00425 cconvert->pub.color_convert = gray_rgb_convert;
00426 } else if (cinfo->jpeg_color_space == JCS_RGB && RGB_PIXELSIZE == 3) {
00427 cconvert->pub.color_convert = null_convert;
00428 } else
00429 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
00430 break;
00431
00432 case JCS_RGB565:
00433 cinfo->out_color_components = RGB_PIXELSIZE;
00434 if(cinfo->jpeg_color_space == JCS_YCbCr)
00435 {
00436 cconvert->pub.color_convert = ycc_rgb565_convert;
00437 build_ycc_rgb_table(cinfo);
00438 }
00439 else
00440 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
00441 break;
00442
00443 case JCS_CMYK:
00444 cinfo->out_color_components = 4;
00445 if (cinfo->jpeg_color_space == JCS_YCCK) {
00446 cconvert->pub.color_convert = ycck_cmyk_convert;
00447 build_ycc_rgb_table(cinfo);
00448 } else if (cinfo->jpeg_color_space == JCS_CMYK) {
00449 cconvert->pub.color_convert = null_convert;
00450 } else
00451 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
00452 break;
00453
00454 default:
00455
00456 if (cinfo->out_color_space == cinfo->jpeg_color_space) {
00457 cinfo->out_color_components = cinfo->num_components;
00458 cconvert->pub.color_convert = null_convert;
00459 } else
00460 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
00461 break;
00462 }
00463
00464 if (cinfo->quantize_colors)
00465 cinfo->output_components = 1;
00466 else
00467 cinfo->output_components = cinfo->out_color_components;
00468 }