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 }