--- CV/CV.xs 2015/07/04 05:31:17 1.46 +++ CV/CV.xs 2017/05/24 05:00:57 1.48 @@ -40,12 +40,18 @@ static void cv_error_exit (j_common_ptr cinfo) { + cinfo->err->output_message (cinfo); longjmp (((struct jpg_err_mgr *)cinfo->err)->setjmp_buffer, 99); } static void cv_error_output (j_common_ptr cinfo) { + char msg[JMSG_LENGTH_MAX]; + + cinfo->err->format_message (cinfo, msg); + + fprintf (stderr, "JPEG decoding error: %s\n", msg); return; } @@ -313,7 +319,7 @@ RETVAL GdkPixbuf_noinc * -load_jpeg (SV *path, int thumbnail=0) +load_jpeg (SV *path, int thumbnail = 0, int iw = 0, int ih = 0) CODE: { struct jpeg_decompress_struct cinfo; @@ -371,24 +377,30 @@ cinfo.do_fancy_upsampling = FALSE; while (cinfo.scale_denom < 8 - && cinfo.output_width >= IW*4 - && cinfo.output_height >= IH*4) + && cinfo.output_width >= iw*4 + && cinfo.output_height >= ih*4) { cinfo.scale_denom <<= 1; jpeg_calc_output_dimensions (&cinfo); } } - pb = RETVAL = gdk_pixbuf_new (GDK_COLORSPACE_RGB, 0, 8, cinfo.output_width, cinfo.output_height); + if (cinfo.output_components != 3) + longjmp (jerr.setjmp_buffer, 3); + + if (cinfo.jpeg_color_space == JCS_YCCK || cinfo.jpeg_color_space == JCS_CMYK) + { + cinfo.out_color_space = JCS_CMYK; + cinfo.output_components = 4; + } + + pb = RETVAL = gdk_pixbuf_new (GDK_COLORSPACE_RGB, cinfo.output_components == 4, 8, cinfo.output_width, cinfo.output_height); if (!RETVAL) longjmp (jerr.setjmp_buffer, 2); data = gdk_pixbuf_get_pixels (RETVAL); rs = gdk_pixbuf_get_rowstride (RETVAL); - if (cinfo.output_components != 3) - longjmp (jerr.setjmp_buffer, 3); - jpeg_start_decompress (&cinfo); while (cinfo.output_scanline < cinfo.output_height) @@ -404,6 +416,26 @@ jpeg_read_scanlines (&cinfo, rp, remaining < 4 ? remaining : 4); } + if (cinfo.out_color_space == JCS_CMYK) + { + guchar *end = data + cinfo.output_height * rs; + + while (data < end) + { + U32 c = data [0]; + U32 m = data [1]; + U32 y = data [2]; + U32 k = data [3]; + + data [0] = c * k / 255; + data [1] = m * k / 255; + data [2] = y * k / 255; + data [3] = 255; + + data += 4; + } + } + jpeg_finish_decompress (&cinfo); fclose (fp); jpeg_destroy_decompress (&cinfo);