summaryrefslogtreecommitdiff
path: root/gdk-pixbuf
diff options
context:
space:
mode:
authorFederico Mena Quintero <federico@ximian.com>2002-09-26 02:14:43 +0000
committerFederico Mena Quintero <federico@src.gnome.org>2002-09-26 02:14:43 +0000
commite4b64fdcfc07591404aa16b0a4d6b0411e061e5c (patch)
treeccf4f808a1f3a4e739be3ec7ebf43b150662a95a /gdk-pixbuf
parent6fea756129a3a0f8a7817f2d917a0e370e26ccde (diff)
downloadgdk-pixbuf-e4b64fdcfc07591404aa16b0a4d6b0411e061e5c.tar.gz
Merged the CMYK changes from HEAD.
2002-09-25 Federico Mena Quintero <federico@ximian.com> * io-jpeg.c: Merged the CMYK changes from HEAD.
Diffstat (limited to 'gdk-pixbuf')
-rw-r--r--gdk-pixbuf/ChangeLog4
-rw-r--r--gdk-pixbuf/io-jpeg.c145
2 files changed, 115 insertions, 34 deletions
diff --git a/gdk-pixbuf/ChangeLog b/gdk-pixbuf/ChangeLog
index 11a5232ba..ab56576ef 100644
--- a/gdk-pixbuf/ChangeLog
+++ b/gdk-pixbuf/ChangeLog
@@ -1,3 +1,7 @@
+2002-09-25 Federico Mena Quintero <federico@ximian.com>
+
+ * io-jpeg.c: Merged the CMYK changes from HEAD.
+
2002-09-16 Matthias Clasen <maclas@gmx.de>
* test-images.h: line-wrap all images to avoid problems with
diff --git a/gdk-pixbuf/io-jpeg.c b/gdk-pixbuf/io-jpeg.c
index a2b3b7769..ecd650a75 100644
--- a/gdk-pixbuf/io-jpeg.c
+++ b/gdk-pixbuf/io-jpeg.c
@@ -26,21 +26,6 @@
*/
-/*
- Progressive file loading notes (11/03/1999) <drmike@redhat.com>...
-
- These are issues I know of and will be dealing with shortly:
-
- - Currently does not handle progressive jpegs - this
- requires a change in the way image_load_increment () calls
- libjpeg. Progressive jpegs are rarer but I will add this
- support asap.
-
- - error handling is not as good as it should be
-
- */
-
-
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
@@ -150,6 +135,7 @@ explode_gray_into_buf (struct jpeg_decompress_struct *cinfo,
g_return_if_fail (cinfo != NULL);
g_return_if_fail (cinfo->output_components == 1);
+ g_return_if_fail (cinfo->out_color_space == JCS_GRAYSCALE);
/* Expand grey->colour. Expand from the end of the
* memory down, so we can use the same buffer.
@@ -170,6 +156,43 @@ explode_gray_into_buf (struct jpeg_decompress_struct *cinfo,
}
}
+
+static void
+convert_cmyk_to_rgb (struct jpeg_decompress_struct *cinfo,
+ guchar **lines)
+{
+ gint i, j;
+
+ g_return_if_fail (cinfo != NULL);
+ g_return_if_fail (cinfo->output_components == 4);
+ g_return_if_fail (cinfo->out_color_space == JCS_CMYK);
+
+ for (i = cinfo->rec_outbuf_height - 1; i >= 0; i--) {
+ guchar *p;
+
+ p = lines[i];
+ for (j = 0; j < cinfo->image_width; j++) {
+ int c, m, y, k;
+ c = p[0];
+ m = p[1];
+ y = p[2];
+ k = p[3];
+ if (cinfo->saw_Adobe_marker) {
+ p[0] = k*c / 255;
+ p[1] = k*m / 255;
+ p[2] = k*y / 255;
+ }
+ else {
+ p[0] = (255 - k)*(255 - c) / 255;
+ p[1] = (255 - k)*(255 - m) / 255;
+ p[2] = (255 - k)*(255 - y) / 255;
+ }
+ p[3] = 255;
+ p += 4;
+ }
+ }
+}
+
typedef struct {
struct jpeg_source_mgr pub; /* public fields */
@@ -234,6 +257,20 @@ stdio_term_source (j_decompress_ptr cinfo)
{
}
+static gchar *
+colorspace_name (const J_COLOR_SPACE jpeg_color_space)
+{
+ switch (jpeg_color_space) {
+ case JCS_UNKNOWN: return "UNKNOWN";
+ case JCS_GRAYSCALE: return "GRAYSCALE";
+ case JCS_RGB: return "RGB";
+ case JCS_YCbCr: return "YCbCr";
+ case JCS_CMYK: return "CMYK";
+ case JCS_YCCK: return "YCCK";
+ default: return "invalid";
+ }
+}
+
/* Shared library entry point */
static GdkPixbuf *
gdk_pixbuf__jpeg_image_load (FILE *f, GError **error)
@@ -292,8 +329,10 @@ gdk_pixbuf__jpeg_image_load (FILE *f, GError **error)
cinfo.do_fancy_upsampling = FALSE;
cinfo.do_block_smoothing = FALSE;
- pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, cinfo.output_width, cinfo.output_height);
-
+ pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
+ cinfo.out_color_components == 4 ? TRUE : FALSE,
+ 8, cinfo.output_width, cinfo.output_height);
+
if (!pixbuf) {
jpeg_destroy_decompress (&cinfo);
@@ -313,7 +352,6 @@ gdk_pixbuf__jpeg_image_load (FILE *f, GError **error)
dptr = pixbuf->pixels;
/* decompress all the lines, a few at a time */
-
while (cinfo.output_scanline < cinfo.output_height) {
lptr = lines;
for (i = 0; i < cinfo.rec_outbuf_height; i++) {
@@ -323,8 +361,29 @@ gdk_pixbuf__jpeg_image_load (FILE *f, GError **error)
jpeg_read_scanlines (&cinfo, lines, cinfo.rec_outbuf_height);
- if (cinfo.output_components == 1)
- explode_gray_into_buf (&cinfo, lines);
+ switch (cinfo.out_color_space) {
+ case JCS_GRAYSCALE:
+ explode_gray_into_buf (&cinfo, lines);
+ break;
+ case JCS_RGB:
+ /* do nothing */
+ break;
+ case JCS_CMYK:
+ convert_cmyk_to_rgb (&cinfo, lines);
+ break;
+ default:
+ g_object_unref (pixbuf);
+ if (error && *error == NULL) {
+ g_set_error (error,
+ GDK_PIXBUF_ERROR,
+ GDK_PIXBUF_ERROR_UNKNOWN_TYPE,
+ _("Unsupported JPEG color space (%s)"),
+ colorspace_name (cinfo.out_color_space));
+ }
+
+ jpeg_destroy_decompress (&cinfo);
+ return NULL;
+ }
}
jpeg_finish_decompress (&cinfo);
@@ -587,8 +646,17 @@ gdk_pixbuf__jpeg_image_load_increment (gpointer data,
context->got_header = TRUE;
+ } else if (!context->did_prescan) {
+ int rc;
+
+ /* start decompression */
+ cinfo->buffered_image = TRUE;
+ rc = jpeg_start_decompress (cinfo);
+ cinfo->do_fancy_upsampling = FALSE;
+ cinfo->do_block_smoothing = FALSE;
+
context->pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB,
- FALSE,
+ cinfo->output_components == 4 ? TRUE : FALSE,
8,
cinfo->image_width,
cinfo->image_height);
@@ -609,15 +677,6 @@ gdk_pixbuf__jpeg_image_load_increment (gpointer data,
NULL,
context->user_data);
- } else if (!context->did_prescan) {
- int rc;
-
- /* start decompression */
- cinfo->buffered_image = TRUE;
- rc = jpeg_start_decompress (cinfo);
- cinfo->do_fancy_upsampling = FALSE;
- cinfo->do_block_smoothing = FALSE;
-
if (rc == JPEG_SUSPENDED)
continue;
@@ -653,10 +712,28 @@ gdk_pixbuf__jpeg_image_load_increment (gpointer data,
if (nlines == 0)
break;
- /* handle gray */
- if (cinfo->output_components == 1)
- explode_gray_into_buf (cinfo, lines);
-
+ switch (cinfo->out_color_space) {
+ case JCS_GRAYSCALE:
+ explode_gray_into_buf (cinfo, lines);
+ break;
+ case JCS_RGB:
+ /* do nothing */
+ break;
+ case JCS_CMYK:
+ convert_cmyk_to_rgb (cinfo, lines);
+ break;
+ default:
+ if (error && *error == NULL) {
+ g_set_error (error,
+ GDK_PIXBUF_ERROR,
+ GDK_PIXBUF_ERROR_UNKNOWN_TYPE,
+ _("Unsupported JPEG color space (%s)"),
+ colorspace_name (cinfo->out_color_space));
+ }
+
+ return FALSE;
+ }
+
context->dptr += nlines * context->pixbuf->rowstride;
/* send updated signal */