00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "cdjpeg.h"
00022
00023 #ifdef PPM_SUPPORTED
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 #ifdef HAVE_UNSIGNED_CHAR
00042 typedef unsigned char U_CHAR;
00043 #define UCH(x) ((int) (x))
00044 #else
00045 #ifdef CHAR_IS_UNSIGNED
00046 typedef char U_CHAR;
00047 #define UCH(x) ((int) (x))
00048 #else
00049 typedef char U_CHAR;
00050 #define UCH(x) ((int) (x) & 0xFF)
00051 #endif
00052 #endif
00053
00054
00055 #define ReadOK(file,buffer,len) (JFREAD(file,buffer,len) == ((size_t) (len)))
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071 typedef struct {
00072 struct cjpeg_source_struct pub;
00073
00074 U_CHAR *iobuffer;
00075 JSAMPROW pixrow;
00076 size_t buffer_width;
00077 JSAMPLE *rescale;
00078 } ppm_source_struct;
00079
00080 typedef ppm_source_struct * ppm_source_ptr;
00081
00082
00083 LOCAL(int)
00084 pbm_getc (FILE * infile)
00085
00086
00087 {
00088 register int ch;
00089
00090 ch = getc(infile);
00091 if (ch == '#') {
00092 do {
00093 ch = getc(infile);
00094 } while (ch != '\n' && ch != EOF);
00095 }
00096 return ch;
00097 }
00098
00099
00100 LOCAL(unsigned int)
00101 read_pbm_integer (j_compress_ptr cinfo, FILE * infile)
00102
00103
00104
00105
00106 {
00107 register int ch;
00108 register unsigned int val;
00109
00110
00111 do {
00112 ch = pbm_getc(infile);
00113 if (ch == EOF)
00114 ERREXIT(cinfo, JERR_INPUT_EOF);
00115 } while (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r');
00116
00117 if (ch < '0' || ch > '9')
00118 ERREXIT(cinfo, JERR_PPM_NONNUMERIC);
00119
00120 val = ch - '0';
00121 while ((ch = pbm_getc(infile)) >= '0' && ch <= '9') {
00122 val *= 10;
00123 val += ch - '0';
00124 }
00125 return val;
00126 }
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140 METHODDEF(JDIMENSION)
00141 get_text_gray_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
00142
00143 {
00144 ppm_source_ptr source = (ppm_source_ptr) sinfo;
00145 FILE * infile = source->pub.input_file;
00146 register JSAMPROW ptr;
00147 register JSAMPLE *rescale = source->rescale;
00148 JDIMENSION col;
00149
00150 ptr = source->pub.buffer[0];
00151 for (col = cinfo->image_width; col > 0; col--) {
00152 *ptr++ = rescale[read_pbm_integer(cinfo, infile)];
00153 }
00154 return 1;
00155 }
00156
00157
00158 METHODDEF(JDIMENSION)
00159 get_text_rgb_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
00160
00161 {
00162 ppm_source_ptr source = (ppm_source_ptr) sinfo;
00163 FILE * infile = source->pub.input_file;
00164 register JSAMPROW ptr;
00165 register JSAMPLE *rescale = source->rescale;
00166 JDIMENSION col;
00167
00168 ptr = source->pub.buffer[0];
00169 for (col = cinfo->image_width; col > 0; col--) {
00170 *ptr++ = rescale[read_pbm_integer(cinfo, infile)];
00171 *ptr++ = rescale[read_pbm_integer(cinfo, infile)];
00172 *ptr++ = rescale[read_pbm_integer(cinfo, infile)];
00173 }
00174 return 1;
00175 }
00176
00177
00178 METHODDEF(JDIMENSION)
00179 get_scaled_gray_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
00180
00181 {
00182 ppm_source_ptr source = (ppm_source_ptr) sinfo;
00183 register JSAMPROW ptr;
00184 register U_CHAR * bufferptr;
00185 register JSAMPLE *rescale = source->rescale;
00186 JDIMENSION col;
00187
00188 if (! ReadOK(source->pub.input_file, source->iobuffer, source->buffer_width))
00189 ERREXIT(cinfo, JERR_INPUT_EOF);
00190 ptr = source->pub.buffer[0];
00191 bufferptr = source->iobuffer;
00192 for (col = cinfo->image_width; col > 0; col--) {
00193 *ptr++ = rescale[UCH(*bufferptr++)];
00194 }
00195 return 1;
00196 }
00197
00198
00199 METHODDEF(JDIMENSION)
00200 get_scaled_rgb_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
00201
00202 {
00203 ppm_source_ptr source = (ppm_source_ptr) sinfo;
00204 register JSAMPROW ptr;
00205 register U_CHAR * bufferptr;
00206 register JSAMPLE *rescale = source->rescale;
00207 JDIMENSION col;
00208
00209 if (! ReadOK(source->pub.input_file, source->iobuffer, source->buffer_width))
00210 ERREXIT(cinfo, JERR_INPUT_EOF);
00211 ptr = source->pub.buffer[0];
00212 bufferptr = source->iobuffer;
00213 for (col = cinfo->image_width; col > 0; col--) {
00214 *ptr++ = rescale[UCH(*bufferptr++)];
00215 *ptr++ = rescale[UCH(*bufferptr++)];
00216 *ptr++ = rescale[UCH(*bufferptr++)];
00217 }
00218 return 1;
00219 }
00220
00221
00222 METHODDEF(JDIMENSION)
00223 get_raw_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
00224
00225
00226
00227
00228 {
00229 ppm_source_ptr source = (ppm_source_ptr) sinfo;
00230
00231 if (! ReadOK(source->pub.input_file, source->iobuffer, source->buffer_width))
00232 ERREXIT(cinfo, JERR_INPUT_EOF);
00233 return 1;
00234 }
00235
00236
00237 METHODDEF(JDIMENSION)
00238 get_word_gray_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
00239
00240 {
00241 ppm_source_ptr source = (ppm_source_ptr) sinfo;
00242 register JSAMPROW ptr;
00243 register U_CHAR * bufferptr;
00244 register JSAMPLE *rescale = source->rescale;
00245 JDIMENSION col;
00246
00247 if (! ReadOK(source->pub.input_file, source->iobuffer, source->buffer_width))
00248 ERREXIT(cinfo, JERR_INPUT_EOF);
00249 ptr = source->pub.buffer[0];
00250 bufferptr = source->iobuffer;
00251 for (col = cinfo->image_width; col > 0; col--) {
00252 register int temp;
00253 temp = UCH(*bufferptr++);
00254 temp |= UCH(*bufferptr++) << 8;
00255 *ptr++ = rescale[temp];
00256 }
00257 return 1;
00258 }
00259
00260
00261 METHODDEF(JDIMENSION)
00262 get_word_rgb_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
00263
00264 {
00265 ppm_source_ptr source = (ppm_source_ptr) sinfo;
00266 register JSAMPROW ptr;
00267 register U_CHAR * bufferptr;
00268 register JSAMPLE *rescale = source->rescale;
00269 JDIMENSION col;
00270
00271 if (! ReadOK(source->pub.input_file, source->iobuffer, source->buffer_width))
00272 ERREXIT(cinfo, JERR_INPUT_EOF);
00273 ptr = source->pub.buffer[0];
00274 bufferptr = source->iobuffer;
00275 for (col = cinfo->image_width; col > 0; col--) {
00276 register int temp;
00277 temp = UCH(*bufferptr++);
00278 temp |= UCH(*bufferptr++) << 8;
00279 *ptr++ = rescale[temp];
00280 temp = UCH(*bufferptr++);
00281 temp |= UCH(*bufferptr++) << 8;
00282 *ptr++ = rescale[temp];
00283 temp = UCH(*bufferptr++);
00284 temp |= UCH(*bufferptr++) << 8;
00285 *ptr++ = rescale[temp];
00286 }
00287 return 1;
00288 }
00289
00290
00291
00292
00293
00294
00295 METHODDEF(void)
00296 start_input_ppm (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
00297 {
00298 ppm_source_ptr source = (ppm_source_ptr) sinfo;
00299 int c;
00300 unsigned int w, h, maxval;
00301 boolean need_iobuffer, use_raw_buffer, need_rescale;
00302
00303 if (getc(source->pub.input_file) != 'P')
00304 ERREXIT(cinfo, JERR_PPM_NOT);
00305
00306 c = getc(source->pub.input_file);
00307
00308
00309 switch (c) {
00310 case '2':
00311 case '3':
00312 case '5':
00313 case '6':
00314 break;
00315 default:
00316 ERREXIT(cinfo, JERR_PPM_NOT);
00317 break;
00318 }
00319
00320
00321 w = read_pbm_integer(cinfo, source->pub.input_file);
00322 h = read_pbm_integer(cinfo, source->pub.input_file);
00323 maxval = read_pbm_integer(cinfo, source->pub.input_file);
00324
00325 if (w <= 0 || h <= 0 || maxval <= 0)
00326 ERREXIT(cinfo, JERR_PPM_NOT);
00327
00328 cinfo->data_precision = BITS_IN_JSAMPLE;
00329 cinfo->image_width = (JDIMENSION) w;
00330 cinfo->image_height = (JDIMENSION) h;
00331
00332
00333 need_iobuffer = TRUE;
00334 use_raw_buffer = FALSE;
00335 need_rescale = TRUE;
00336
00337 switch (c) {
00338 case '2':
00339 cinfo->input_components = 1;
00340 cinfo->in_color_space = JCS_GRAYSCALE;
00341 TRACEMS2(cinfo, 1, JTRC_PGM_TEXT, w, h);
00342 source->pub.get_pixel_rows = get_text_gray_row;
00343 need_iobuffer = FALSE;
00344 break;
00345
00346 case '3':
00347 cinfo->input_components = 3;
00348 cinfo->in_color_space = JCS_RGB;
00349 TRACEMS2(cinfo, 1, JTRC_PPM_TEXT, w, h);
00350 source->pub.get_pixel_rows = get_text_rgb_row;
00351 need_iobuffer = FALSE;
00352 break;
00353
00354 case '5':
00355 cinfo->input_components = 1;
00356 cinfo->in_color_space = JCS_GRAYSCALE;
00357 TRACEMS2(cinfo, 1, JTRC_PGM, w, h);
00358 if (maxval > 255) {
00359 source->pub.get_pixel_rows = get_word_gray_row;
00360 } else if (maxval == MAXJSAMPLE && SIZEOF(JSAMPLE) == SIZEOF(U_CHAR)) {
00361 source->pub.get_pixel_rows = get_raw_row;
00362 use_raw_buffer = TRUE;
00363 need_rescale = FALSE;
00364 } else {
00365 source->pub.get_pixel_rows = get_scaled_gray_row;
00366 }
00367 break;
00368
00369 case '6':
00370 cinfo->input_components = 3;
00371 cinfo->in_color_space = JCS_RGB;
00372 TRACEMS2(cinfo, 1, JTRC_PPM, w, h);
00373 if (maxval > 255) {
00374 source->pub.get_pixel_rows = get_word_rgb_row;
00375 } else if (maxval == MAXJSAMPLE && SIZEOF(JSAMPLE) == SIZEOF(U_CHAR)) {
00376 source->pub.get_pixel_rows = get_raw_row;
00377 use_raw_buffer = TRUE;
00378 need_rescale = FALSE;
00379 } else {
00380 source->pub.get_pixel_rows = get_scaled_rgb_row;
00381 }
00382 break;
00383 }
00384
00385
00386 if (need_iobuffer) {
00387 source->buffer_width = (size_t) w * cinfo->input_components *
00388 ((maxval<=255) ? SIZEOF(U_CHAR) : (2*SIZEOF(U_CHAR)));
00389 source->iobuffer = (U_CHAR *)
00390 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00391 source->buffer_width);
00392 }
00393
00394
00395 if (use_raw_buffer) {
00396
00397
00398
00399 source->pixrow = (JSAMPROW) source->iobuffer;
00400 source->pub.buffer = & source->pixrow;
00401 source->pub.buffer_height = 1;
00402 } else {
00403
00404 source->pub.buffer = (*cinfo->mem->alloc_sarray)
00405 ((j_common_ptr) cinfo, JPOOL_IMAGE,
00406 (JDIMENSION) w * cinfo->input_components, (JDIMENSION) 1);
00407 source->pub.buffer_height = 1;
00408 }
00409
00410
00411 if (need_rescale) {
00412 INT32 val, half_maxval;
00413
00414
00415 source->rescale = (JSAMPLE *)
00416 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00417 (size_t) (((long) maxval + 1L) * SIZEOF(JSAMPLE)));
00418 half_maxval = maxval / 2;
00419 for (val = 0; val <= (INT32) maxval; val++) {
00420
00421 source->rescale[val] = (JSAMPLE) ((val*MAXJSAMPLE + half_maxval)/maxval);
00422 }
00423 }
00424 }
00425
00426
00427
00428
00429
00430
00431 METHODDEF(void)
00432 finish_input_ppm (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
00433 {
00434
00435 }
00436
00437
00438
00439
00440
00441
00442 GLOBAL(cjpeg_source_ptr)
00443 jinit_read_ppm (j_compress_ptr cinfo)
00444 {
00445 ppm_source_ptr source;
00446
00447
00448 source = (ppm_source_ptr)
00449 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00450 SIZEOF(ppm_source_struct));
00451
00452 source->pub.start_input = start_input_ppm;
00453 source->pub.finish_input = finish_input_ppm;
00454
00455 return (cjpeg_source_ptr) source;
00456 }
00457
00458 #endif