269l_int32 cyan, yellow, magenta, black, nwarn;
270l_int32 i, j, k, rval, gval, bval;
271l_int32 nlinesread, abort_on_warning;
272l_int32 w, h, wpl, spp, ncolors, cindex, ycck, cmyk;
274l_uint32 *line, *ppixel;
278struct jpeg_decompress_struct cinfo;
279struct jpeg_error_mgr jerr;
282 if (pnwarn) *pnwarn = 0;
284 return (
PIX *)ERROR_PTR(
"fp not defined", __func__, NULL);
285 if (cmapflag != 0 && cmapflag != 1)
287 if (reduction != 1 && reduction != 2 && reduction != 4 && reduction != 8)
288 return (
PIX *)ERROR_PTR(
"reduction not in {1,2,4,8}", __func__, NULL);
290 if (BITS_IN_JSAMPLE != 8)
291 return (
PIX *)ERROR_PTR(
"BITS_IN_JSAMPLE != 8", __func__, NULL);
298 cinfo.err = jpeg_std_error(&jerr);
300 cinfo.client_data = (
void *)&jmpbuf;
301 if (setjmp(jmpbuf)) {
302 jpeg_destroy_decompress(&cinfo);
304 LEPT_FREE(rowbuffer);
305 return (
PIX *)ERROR_PTR(
"internal jpeg error", __func__, NULL);
309 jpeg_create_decompress(&cinfo);
310 jpeg_stdio_src(&cinfo, fp);
311 jpeg_read_header(&cinfo, TRUE);
312 cinfo.scale_denom = reduction;
314 jpeg_calc_output_dimensions(&cinfo);
316 cinfo.out_color_space = JCS_GRAYSCALE;
318 L_INFO(
"reading luminance channel only\n", __func__);
320 spp = cinfo.out_color_components;
324 w = cinfo.output_width;
325 h = cinfo.output_height;
326 ycck = (cinfo.jpeg_color_space == JCS_YCCK && spp == 4 && cmapflag == 0);
327 cmyk = (cinfo.jpeg_color_space == JCS_CMYK && spp == 4 && cmapflag == 0);
328 if (spp != 1 && spp != 3 && !ycck && !cmyk) {
329 jpeg_destroy_decompress(&cinfo);
330 return (
PIX *)ERROR_PTR(
"spp must be 1 or 3, or YCCK or CMYK",
333 if ((spp == 3 && cmapflag == 0) || ycck || cmyk) {
334 rowbuffer = (JSAMPROW)LEPT_CALLOC(
sizeof(JSAMPLE), (
size_t)spp * w);
335 pix = pixCreate(w, h, 32);
337 rowbuffer = (JSAMPROW)LEPT_CALLOC(
sizeof(JSAMPLE), w);
338 pix = pixCreate(w, h, 8);
340 pixSetInputFormat(pix, IFF_JFIF_JPEG);
341 if (!rowbuffer || !pix) {
342 LEPT_FREE(rowbuffer);
345 jpeg_destroy_decompress(&cinfo);
346 return (
PIX *)ERROR_PTR(
"rowbuffer or pix not made", __func__, NULL);
357 jpeg_start_decompress(&cinfo);
360 cinfo.quantize_colors = FALSE;
361 jpeg_start_decompress(&cinfo);
363 cinfo.quantize_colors = TRUE;
364 cinfo.desired_number_of_colors = 256;
365 jpeg_start_decompress(&cinfo);
368 cmap = pixcmapCreate(8);
369 ncolors = cinfo.actual_number_of_colors;
370 for (cindex = 0; cindex < ncolors; cindex++) {
371 rval = cinfo.colormap[0][cindex];
372 gval = cinfo.colormap[1][cindex];
373 bval = cinfo.colormap[2][cindex];
374 pixcmapAddColor(cmap, rval, gval, bval);
376 pixSetColormap(pix, cmap);
379 wpl = pixGetWpl(pix);
380 data = pixGetData(pix);
392 for (i = 0; i < h; i++) {
393 nlinesread = jpeg_read_scanlines(&cinfo, &rowbuffer, (JDIMENSION)1);
394 nwarn = cinfo.err->num_warnings;
395 if (nlinesread == 0 || (abort_on_warning && nwarn > 0)) {
396 L_ERROR(
"read error at scanline %d; nwarn = %d\n",
399 jpeg_destroy_decompress(&cinfo);
400 LEPT_FREE(rowbuffer);
402 if (pnwarn) *pnwarn = nwarn;
403 return (
PIX *)ERROR_PTR(
"bad data", __func__, NULL);
407 if ((spp == 3 && cmapflag == 0) || ycck || cmyk) {
408 ppixel = data + i * wpl;
410 for (j = k = 0; j < w; j++) {
438 for (j = k = 0; j < w; j++) {
439 cyan = rowbuffer[k++];
440 magenta = rowbuffer[k++];
441 yellow = rowbuffer[k++];
442 black = rowbuffer[k++];
443 if (cinfo.saw_Adobe_marker) {
444 rval = (black * cyan) / 255;
445 gval = (black * magenta) / 255;
446 bval = (black * yellow) / 255;
448 rval = black * (255 - cyan) / 255;
449 gval = black * (255 - magenta) / 255;
450 bval = black * (255 - yellow) / 255;
452 rval = L_MIN(L_MAX(rval, 0), 255);
453 gval = L_MIN(L_MAX(gval, 0), 255);
454 bval = L_MIN(L_MAX(bval, 0), 255);
455 composeRGBPixel(rval, gval, bval, ppixel);
460 line = data + i * wpl;
461 for (j = 0; j < w; j++)
468 if (cinfo.density_unit == 1) {
469 pixSetXRes(pix, cinfo.X_density);
470 pixSetYRes(pix, cinfo.Y_density);
471 }
else if (cinfo.density_unit == 2) {
472 pixSetXRes(pix, (l_int32)((l_float32)cinfo.X_density * 2.54 + 0.5));
473 pixSetYRes(pix, (l_int32)((l_float32)cinfo.Y_density * 2.54 + 0.5));
476 if (cinfo.output_components != spp)
477 lept_stderr(
"output spp = %d, spp = %d\n",
478 cinfo.output_components, spp);
480 jpeg_finish_decompress(&cinfo);
481 jpeg_destroy_decompress(&cinfo);
482 LEPT_FREE(rowbuffer);
484 if (pnwarn) *pnwarn = nwarn;
486 L_WARNING(
"%d warning(s) of bad data\n", __func__, nwarn);
554struct jpeg_decompress_struct cinfo;
555struct jpeg_error_mgr jerr;
561 if (pycck) *pycck = 0;
562 if (pcmyk) *pcmyk = 0;
564 return ERROR_INT(
"stream not defined", __func__, 1);
565 if (!pw && !ph && !pspp && !pycck && !pcmyk)
566 return ERROR_INT(
"no results requested", __func__, 1);
571 cinfo.err = jpeg_std_error(&jerr);
572 cinfo.client_data = (
void *)&jmpbuf;
575 return ERROR_INT(
"internal jpeg error", __func__, 1);
578 jpeg_create_decompress(&cinfo);
579 jpeg_stdio_src(&cinfo, fp);
580 jpeg_read_header(&cinfo, TRUE);
581 jpeg_calc_output_dimensions(&cinfo);
582 spp = cinfo.out_color_components;
583 w = cinfo.output_width;
584 h = cinfo.output_height;
585 if (w < 1 || h < 1 || spp < 1 || spp > 4) {
586 jpeg_destroy_decompress(&cinfo);
588 return ERROR_INT(
"bad jpeg image parameters", __func__, 1);
591 if (pspp) *pspp = spp;
592 if (pw) *pw = cinfo.output_width;
593 if (ph) *ph = cinfo.output_height;
595 (cinfo.jpeg_color_space == JCS_YCCK && spp == 4);
597 (cinfo.jpeg_color_space == JCS_CMYK && spp == 4);
599 jpeg_destroy_decompress(&cinfo);
796l_int32 w, h, d, wpl, spp, colorflag, rowsamples;
797l_uint32 *ppixel, *line, *data;
800struct jpeg_compress_struct cinfo;
801struct jpeg_error_mgr jerr;
806 return ERROR_INT(
"stream not open", __func__, 1);
808 return ERROR_INT(
"pixs not defined", __func__, 1);
809 if (quality <= 0) quality = 75;
811 L_ERROR(
"invalid jpeg quality; setting to 75\n", __func__);
818 pixGetDimensions(pixs, &w, &h, &d);
820 if (pixGetColormap(pixs) != NULL) {
821 L_INFO(
"removing colormap; may be better to compress losslessly\n",
824 }
else if (d >= 8 && d != 16) {
825 pix = pixClone(pixs);
826 }
else if (d < 8 || d == 16) {
827 L_INFO(
"converting from %d to 8 bpp\n", __func__, d);
828 pix = pixConvertTo8(pixs, 0);
830 L_ERROR(
"unknown pix type with d = %d and no cmap\n", __func__, d);
834 return ERROR_INT(
"pix not made", __func__, 1);
835 pixSetPadBits(pix, 0);
841 cinfo.err = jpeg_std_error(&jerr);
842 cinfo.client_data = (
void *)&jmpbuf;
844 if (setjmp(jmpbuf)) {
845 LEPT_FREE(rowbuffer);
847 return ERROR_INT(
"internal jpeg error", __func__, 1);
851 jpeg_create_compress(&cinfo);
852 jpeg_stdio_dest(&cinfo, fp);
853 cinfo.image_width = w;
854 cinfo.image_height = h;
857 d = pixGetDepth(pix);
860 cinfo.input_components = 1;
861 cinfo.in_color_space = JCS_GRAYSCALE;
864 cinfo.input_components = 3;
865 cinfo.in_color_space = JCS_RGB;
868 jpeg_set_defaults(&cinfo);
872 cinfo.optimize_coding = FALSE;
875 xres = pixGetXRes(pix);
876 yres = pixGetYRes(pix);
877 if ((xres != 0) && (yres != 0)) {
878 cinfo.density_unit = 1;
879 cinfo.X_density = xres;
880 cinfo.Y_density = yres;
884 jpeg_set_quality(&cinfo, quality, TRUE);
886 jpeg_simple_progression(&cinfo);
897 cinfo.comp_info[0].h_samp_factor = 1;
898 cinfo.comp_info[0].v_samp_factor = 1;
899 cinfo.comp_info[1].h_samp_factor = 1;
900 cinfo.comp_info[1].v_samp_factor = 1;
901 cinfo.comp_info[2].h_samp_factor = 1;
902 cinfo.comp_info[2].v_samp_factor = 1;
905 jpeg_start_compress(&cinfo, TRUE);
909 if ((text = pixGetText(pix)) != NULL) {
910 if (strlen(text) > 65433) {
911 L_WARNING(
"text is %zu bytes; clipping to 65433\n",
912 __func__, strlen(text));
915 jpeg_write_marker(&cinfo, JPEG_COM, (
const JOCTET *)text, strlen(text));
919 spp = cinfo.input_components;
920 rowsamples = spp * w;
921 if ((rowbuffer = (JSAMPROW)LEPT_CALLOC(
sizeof(JSAMPLE), rowsamples))
924 return ERROR_INT(
"calloc fail for rowbuffer", __func__, 1);
927 data = pixGetData(pix);
928 wpl = pixGetWpl(pix);
929 for (i = 0; i < h; i++) {
930 line = data + i * wpl;
931 if (colorflag == 0) {
932 for (j = 0; j < w; j++)
936 jpeg_write_scanlines(&cinfo, (JSAMPROW *)&line, 1);
939 for (j = k = 0; j < w; j++) {
948 jpeg_write_scanlines(&cinfo, &rowbuffer, 1);
950 jpeg_finish_compress(&cinfo);
953 LEPT_FREE(rowbuffer);
955 jpeg_destroy_compress(&cinfo);