diff options
author | Matthias Clasen <matthiasc@src.gnome.org> | 2002-04-11 21:18:40 +0000 |
---|---|---|
committer | Matthias Clasen <matthiasc@src.gnome.org> | 2002-04-11 21:18:40 +0000 |
commit | 693951085158842b584cfb7289e5ad75d7d6600a (patch) | |
tree | cd98c146d4acb69ddc8cb837ba04b2f6f4af386f /gdk-pixbuf | |
parent | e60568a1da1c38da1793e9eab1364d0c8ddb6fa9 (diff) | |
download | gdk-pixbuf-693951085158842b584cfb7289e5ad75d7d6600a.tar.gz |
More fixes for #77807:
* io-tga.c (get_contiguous_pixbuf): Helper function to create
a pixbuf with a contiguous pixel array while being careful about
overflow.
* io-tga.c (fill_in_context, get_image_pseudocolor,
get_image_truecolor, get_image_grayscale): Use
get_contiguous_pixbuf instead of manually allocating image
storage.
* io-xpm.c (pixbuf_create_from_xpm):
* io-pnm.c (gdk_pixbuf__pnm_image_load):
* io-jpeg.c (gdk_pixbuf__jpeg_image_load): Use gdk_pixbuf_new
instead of manually allocating image storage.
Diffstat (limited to 'gdk-pixbuf')
-rw-r--r-- | gdk-pixbuf/ChangeLog | 18 | ||||
-rw-r--r-- | gdk-pixbuf/io-jpeg.c | 231 | ||||
-rw-r--r-- | gdk-pixbuf/io-pnm.c | 21 | ||||
-rw-r--r-- | gdk-pixbuf/io-tga.c | 87 | ||||
-rw-r--r-- | gdk-pixbuf/io-xpm.c | 23 |
5 files changed, 211 insertions, 169 deletions
diff --git a/gdk-pixbuf/ChangeLog b/gdk-pixbuf/ChangeLog index 6cde6b198..787589267 100644 --- a/gdk-pixbuf/ChangeLog +++ b/gdk-pixbuf/ChangeLog @@ -1,3 +1,21 @@ +2002-04-11 Matthias Clasen <maclas@gmx.de> + + More fixes for #77807: + + * io-tga.c (get_contiguous_pixbuf): Helper function to create + a pixbuf with a contiguous pixel array while being careful about + overflow. + + * io-tga.c (fill_in_context, get_image_pseudocolor, + get_image_truecolor, get_image_grayscale): Use + get_contiguous_pixbuf instead of manually allocating image + storage. + + * io-xpm.c (pixbuf_create_from_xpm): + * io-pnm.c (gdk_pixbuf__pnm_image_load): + * io-jpeg.c (gdk_pixbuf__jpeg_image_load): Use gdk_pixbuf_new + instead of manually allocating image storage. + 2002-04-09 Matthias Clasen <maclas@gmx.de> * gdk-pixbuf-loader.c (gdk_pixbuf_loader_load_module): Use diff --git a/gdk-pixbuf/io-jpeg.c b/gdk-pixbuf/io-jpeg.c index 87bfbe185..a2b3b7769 100644 --- a/gdk-pixbuf/io-jpeg.c +++ b/gdk-pixbuf/io-jpeg.c @@ -58,7 +58,7 @@ /* we are a "source manager" as far as libjpeg is concerned */ -#define JPEG_PROG_BUF_SIZE 4096 +#define JPEG_PROG_BUF_SIZE 65536 typedef struct { struct jpeg_source_mgr pub; /* public fields */ @@ -89,6 +89,7 @@ typedef struct { gboolean did_prescan; /* are we in image data yet? */ gboolean got_header; /* have we loaded jpeg header? */ gboolean src_initialized;/* TRUE when jpeg lib initialized */ + gboolean in_output; /* did we get suspended in an output pass? */ struct jpeg_decompress_struct cinfo; struct error_handler_data jerr; } JpegProgContext; @@ -139,14 +140,6 @@ output_message_handler (j_common_ptr cinfo) /* do nothing */ } -/* Destroy notification function for the pixbuf */ -static void -free_buffer (guchar *pixels, gpointer data) -{ - g_free (pixels); -} - - /* explode gray image data from jpeg library into rgb components in pixbuf */ static void explode_gray_into_buf (struct jpeg_decompress_struct *cinfo, @@ -177,12 +170,76 @@ explode_gray_into_buf (struct jpeg_decompress_struct *cinfo, } } +typedef struct { + struct jpeg_source_mgr pub; /* public fields */ + + FILE * infile; /* source stream */ + JOCTET * buffer; /* start of buffer */ + boolean start_of_file; /* have we gotten any data yet? */ +} stdio_source_mgr; + +typedef stdio_source_mgr * stdio_src_ptr; + +static void +stdio_init_source (j_decompress_ptr cinfo) +{ + stdio_src_ptr src = (stdio_src_ptr)cinfo->src; + src->start_of_file = FALSE; +} + +static boolean +stdio_fill_input_buffer (j_decompress_ptr cinfo) +{ + stdio_src_ptr src = (stdio_src_ptr) cinfo->src; + size_t nbytes; + + nbytes = fread (src->buffer, 1, JPEG_PROG_BUF_SIZE, src->infile); + + if (nbytes <= 0) { +#if 0 + if (src->start_of_file) /* Treat empty input file as fatal error */ + ERREXIT(cinfo, JERR_INPUT_EMPTY); + WARNMS(cinfo, JWRN_JPEG_EOF); +#endif + /* Insert a fake EOI marker */ + src->buffer[0] = (JOCTET) 0xFF; + src->buffer[1] = (JOCTET) JPEG_EOI; + nbytes = 2; + } + + src->pub.next_input_byte = src->buffer; + src->pub.bytes_in_buffer = nbytes; + src->start_of_file = FALSE; + + return TRUE; +} + +static void +stdio_skip_input_data (j_decompress_ptr cinfo, long num_bytes) +{ + stdio_src_ptr src = (stdio_src_ptr) cinfo->src; + + if (num_bytes > 0) { + while (num_bytes > (long) src->pub.bytes_in_buffer) { + num_bytes -= (long) src->pub.bytes_in_buffer; + (void)stdio_fill_input_buffer(cinfo); + } + src->pub.next_input_byte += (size_t) num_bytes; + src->pub.bytes_in_buffer -= (size_t) num_bytes; + } +} + +static void +stdio_term_source (j_decompress_ptr cinfo) +{ +} + /* Shared library entry point */ static GdkPixbuf * gdk_pixbuf__jpeg_image_load (FILE *f, GError **error) { - gint w, h, i; - guchar * volatile pixels = NULL; + gint i; + GdkPixbuf * volatile pixbuf = NULL; guchar *dptr; guchar *lines[4]; /* Used to expand rows, via rec_outbuf_height, * from the header file: @@ -192,6 +249,7 @@ gdk_pixbuf__jpeg_image_load (FILE *f, GError **error) guchar **lptr; struct jpeg_decompress_struct cinfo; struct error_handler_data jerr; + stdio_src_ptr src; /* setup error handler */ cinfo.err = jpeg_std_error (&jerr.pub); @@ -202,8 +260,8 @@ gdk_pixbuf__jpeg_image_load (FILE *f, GError **error) if (sigsetjmp (jerr.setjmp_buffer, 1)) { /* Whoops there was a jpeg error */ - if (pixels) - g_free (pixels); + if (pixbuf) + g_object_unref (pixbuf); jpeg_destroy_decompress (&cinfo); return NULL; @@ -211,17 +269,32 @@ gdk_pixbuf__jpeg_image_load (FILE *f, GError **error) /* load header, setup */ jpeg_create_decompress (&cinfo); - jpeg_stdio_src (&cinfo, f); + + cinfo.src = (struct jpeg_source_mgr *) + (*cinfo.mem->alloc_small) ((j_common_ptr) &cinfo, JPOOL_PERMANENT, + sizeof (stdio_source_mgr)); + src = (stdio_src_ptr) cinfo.src; + src->buffer = (JOCTET *) + (*cinfo.mem->alloc_small) ((j_common_ptr) &cinfo, JPOOL_PERMANENT, + JPEG_PROG_BUF_SIZE * sizeof (JOCTET)); + + src->pub.init_source = stdio_init_source; + src->pub.fill_input_buffer = stdio_fill_input_buffer; + src->pub.skip_input_data = stdio_skip_input_data; + src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */ + src->pub.term_source = stdio_term_source; + src->infile = f; + src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */ + src->pub.next_input_byte = NULL; /* until buffer loaded */ + jpeg_read_header (&cinfo, TRUE); jpeg_start_decompress (&cinfo); cinfo.do_fancy_upsampling = FALSE; cinfo.do_block_smoothing = FALSE; - w = cinfo.output_width; - h = cinfo.output_height; - - pixels = g_try_malloc (h * w * 3); - if (!pixels) { + pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, cinfo.output_width, cinfo.output_height); + + if (!pixbuf) { jpeg_destroy_decompress (&cinfo); /* broken check for *error == NULL for robustness against @@ -237,7 +310,7 @@ gdk_pixbuf__jpeg_image_load (FILE *f, GError **error) return NULL; } - dptr = pixels; + dptr = pixbuf->pixels; /* decompress all the lines, a few at a time */ @@ -245,7 +318,7 @@ gdk_pixbuf__jpeg_image_load (FILE *f, GError **error) lptr = lines; for (i = 0; i < cinfo.rec_outbuf_height; i++) { *lptr++ = dptr; - dptr += w * 3; + dptr += pixbuf->rowstride; } jpeg_read_scanlines (&cinfo, lines, cinfo.rec_outbuf_height); @@ -257,9 +330,7 @@ gdk_pixbuf__jpeg_image_load (FILE *f, GError **error) jpeg_finish_decompress (&cinfo); jpeg_destroy_decompress (&cinfo); - return gdk_pixbuf_new_from_data (pixels, GDK_COLORSPACE_RGB, FALSE, 8, - w, h, w * 3, - free_buffer, NULL); + return pixbuf; } @@ -333,6 +404,7 @@ gdk_pixbuf__jpeg_image_begin_load (ModulePreparedNotifyFunc prepared_func, context->got_header = FALSE; context->did_prescan = FALSE; context->src_initialized = FALSE; + context->in_output = FALSE; /* create libjpeg structures */ jpeg_create_decompress (&context->cinfo); @@ -483,9 +555,6 @@ gdk_pixbuf__jpeg_image_load_increment (gpointer data, num_copy = MIN (JPEG_PROG_BUF_SIZE - src->pub.bytes_in_buffer, num_left); -/* if (num_copy == 0) - g_error ("Buffer overflow!"); -*/ memcpy(src->buffer + src->pub.bytes_in_buffer, bufhd,num_copy); src->pub.next_input_byte = src->buffer; src->pub.bytes_in_buffer += num_copy; @@ -518,13 +587,6 @@ gdk_pixbuf__jpeg_image_load_increment (gpointer data, context->got_header = TRUE; -#if 0 - if (jpeg_has_multiple_scans (cinfo)) { - g_print ("io-jpeg.c: Does not currently " - "support progressive jpeg files.\n"); - return FALSE; - } -#endif context->pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, @@ -549,75 +611,70 @@ gdk_pixbuf__jpeg_image_load_increment (gpointer 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; context->did_prescan = TRUE; } else { - /* we're decompressing so feed jpeg lib scanlines */ guchar *lines[4]; guchar **lptr; guchar *rowptr; gint nlines, i; - gint start_scanline; - - /* keep going until we've done all scanlines */ - while (cinfo->output_scanline < cinfo->output_height) { - start_scanline = cinfo->output_scanline; - lptr = lines; - rowptr = context->dptr; - for (i=0; i < cinfo->rec_outbuf_height; i++) { - *lptr++ = rowptr; - rowptr += context->pixbuf->rowstride; - } - nlines = jpeg_read_scanlines (cinfo, lines, - cinfo->rec_outbuf_height); - if (nlines == 0) + /* keep going until we've done all passes */ + while (!jpeg_input_complete (cinfo)) { + if (!context->in_output) { + if (jpeg_start_output (cinfo, cinfo->input_scan_number)) { + context->in_output = TRUE; + context->dptr = context->pixbuf->pixels; + } + else + break; + } + /* keep going until we've done all scanlines */ + while (cinfo->output_scanline < cinfo->output_height) { + lptr = lines; + rowptr = context->dptr; + for (i=0; i < cinfo->rec_outbuf_height; i++) { + *lptr++ = rowptr; + rowptr += context->pixbuf->rowstride; + } + + nlines = jpeg_read_scanlines (cinfo, lines, + cinfo->rec_outbuf_height); + if (nlines == 0) + break; + + /* handle gray */ + if (cinfo->output_components == 1) + explode_gray_into_buf (cinfo, lines); + + context->dptr += nlines * context->pixbuf->rowstride; + + /* send updated signal */ + (* context->updated_func) (context->pixbuf, + 0, + cinfo->output_scanline-1, + cinfo->image_width, + nlines, + context->user_data); + } + if (cinfo->output_scanline >= cinfo->output_height && + jpeg_finish_output (cinfo)) + context->in_output = FALSE; + else break; - - /* handle gray */ - if (cinfo->output_components == 1) - explode_gray_into_buf (cinfo, lines); - - context->dptr += nlines * context->pixbuf->rowstride; - - /* send updated signal */ - (* context->updated_func) (context->pixbuf, - 0, - cinfo->output_scanline-1, - cinfo->image_width, - nlines, - context->user_data); - -#undef DEBUG_JPEG_PROGRESSIVE -#ifdef DEBUG_JPEG_PROGRESSIVE - - if (start_scanline != cinfo->output_scanline) - g_print("jpeg: Input pass=%2d, next input scanline=%3d," - " emitted %3d - %3d\n", - cinfo->input_scan_number, cinfo->input_iMCU_row * 16, - start_scanline, cinfo->output_scanline - 1); - - - - g_print ("Scanline %d of %d - ", - cinfo->output_scanline, - cinfo->output_height); -/* g_print ("rec_height %d -", cinfo->rec_outbuf_height); */ - g_print ("Processed %d lines - bytes left = %d\n", - nlines, cinfo->src->bytes_in_buffer); -#endif } - /* did entire image */ - if (cinfo->output_scanline >= cinfo->output_height) + if (jpeg_input_complete (cinfo)) + /* did entire image */ return TRUE; else continue; @@ -642,7 +699,7 @@ gdk_pixbuf__jpeg_image_save (FILE *f, guchar *pixels = NULL; JSAMPROW *jbuf; int y = 0; - int quality = 75; /* default; must be between 0 and 100 */ + volatile int quality = 75; /* default; must be between 0 and 100 */ int i, j; int w, h = 0; int rowstride = 0; diff --git a/gdk-pixbuf/io-pnm.c b/gdk-pixbuf/io-pnm.c index adf843f33..797f93717 100644 --- a/gdk-pixbuf/io-pnm.c +++ b/gdk-pixbuf/io-pnm.c @@ -93,13 +93,6 @@ static gboolean gdk_pixbuf__pnm_image_load_increment (gpointer context, static void explode_bitmap_into_buf (PnmLoaderContext *context); static void explode_gray_into_buf (PnmLoaderContext *context); -/* Destroy notification function for the pixbuf */ -static void -free_buffer (guchar *pixels, gpointer data) -{ - g_free (pixels); -} - /* explode bitmap data into rgb components */ /* we need to know what the row so we can */ @@ -764,10 +757,10 @@ gdk_pixbuf__pnm_image_load (FILE *f, GError **error) context.output_row = 0; context.output_col = 0; - context.rowstride = context.width * 3; - context.pixels = g_try_malloc (context.height * context.width * 3); + context.pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, + context.width, context.height); - if (!context.pixels) { + if (!context.pixbuf) { /* Failed to allocate memory */ g_set_error (error, GDK_PIXBUF_ERROR, @@ -775,6 +768,9 @@ gdk_pixbuf__pnm_image_load (FILE *f, GError **error) _("Can't allocate memory for loading PNM image")); return NULL; } + + context.rowstride = context.pixbuf->rowstride; + context.pixels = context.pixbuf->pixels; } /* if we got here we're reading image data */ @@ -797,10 +793,7 @@ gdk_pixbuf__pnm_image_load (FILE *f, GError **error) break; } - return gdk_pixbuf_new_from_data (context.pixels, GDK_COLORSPACE_RGB, FALSE, 8, - context.width, context.height, - context.width * 3, free_buffer, NULL); - + return context.pixbuf; } /* diff --git a/gdk-pixbuf/io-tga.c b/gdk-pixbuf/io-tga.c index 69c55faa8..87a7ea659 100644 --- a/gdk-pixbuf/io-tga.c +++ b/gdk-pixbuf/io-tga.c @@ -242,6 +242,37 @@ static void free_buffer(guchar *pixels, gpointer data) g_free(pixels); } +static GdkPixbuf *get_contiguous_pixbuf (guint width, + guint height, + gboolean has_alpha) +{ + guchar *pixels; + guint channels, rowstride, bytes; + + if (has_alpha) + channels = 4; + else + channels = 3; + + rowstride = width * channels; + + if (rowstride / channels != width) + return NULL; + + bytes = height * rowstride; + + if (bytes / rowstride != height) + return NULL; + + pixels = g_try_malloc (bytes); + + if (!pixels) + return NULL; + + return gdk_pixbuf_new_from_data (pixels, GDK_COLORSPACE_RGB, has_alpha, 8, + width, height, rowstride, free_buffer, NULL); +} + static gboolean fread_check(gpointer dest, size_t size, size_t count, FILE *f, GError **err) @@ -268,7 +299,6 @@ static gboolean fill_in_context(TGAContext *ctx, GError **err) { gboolean alpha; guint w, h; - guchar *pixels; g_return_val_if_fail(ctx != NULL, FALSE); @@ -288,23 +318,14 @@ static gboolean fill_in_context(TGAContext *ctx, GError **err) w = LE16(ctx->hdr->width); h = LE16(ctx->hdr->height); - pixels = g_try_malloc (w * h * (alpha ? 4 : 3)); - - if (!pixels) { - g_set_error(err, GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY, - _("Insufficient memory to load TGA image")); - return FALSE; - } - - ctx->pbuf = gdk_pixbuf_new_from_data (pixels, GDK_COLORSPACE_RGB, alpha, 8, - w, h, w * (alpha ? 4 : 3), - free_buffer, NULL); + ctx->pbuf = get_contiguous_pixbuf (w, h, alpha); if (!ctx->pbuf) { g_set_error(err, GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY, _("Can't allocate new pixbuf")); return FALSE; } + ctx->pbuf_bytes = ctx->pbuf->rowstride * ctx->pbuf->height; ctx->pptr = ctx->pbuf->pixels; @@ -1000,7 +1021,6 @@ static GdkPixbuf *get_image_pseudocolor(FILE *f, TGAHeader *hdr, guchar *p, color, tag; glong n, image_offset; guint count, w, h; - guchar *pixels; gboolean alpha; image_offset = sizeof(TGAHeader) + hdr->infolen; @@ -1023,17 +1043,8 @@ static GdkPixbuf *get_image_pseudocolor(FILE *f, TGAHeader *hdr, alpha = (hdr->cmap_bpp == 32); - pixels = g_try_malloc (w * h * (alpha ? 4 : 3)); + pbuf = get_contiguous_pixbuf (w, h, alpha); - if (!pixels) { - g_set_error(err, GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY, - _("Insufficient memory to load TGA image")); - return FALSE; - } - - pbuf = gdk_pixbuf_new_from_data (pixels, GDK_COLORSPACE_RGB, alpha, 8, - w, h, w * (alpha ? 4 : 3), - free_buffer, NULL); if (!pbuf) { g_set_error(err, GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY, @@ -1120,7 +1131,6 @@ static GdkPixbuf *get_image_truecolor(FILE *f, TGAHeader *hdr, glong n, image_offset; guint32 pixel; guint count, w, h; - guchar *pixels; gboolean alpha; image_offset = sizeof(TGAHeader) + hdr->infolen; @@ -1135,17 +1145,7 @@ static GdkPixbuf *get_image_truecolor(FILE *f, TGAHeader *hdr, alpha = (hdr->bpp == 32); - pixels = g_try_malloc (w * h * (alpha ? 4 : 3)); - - if (!pixels) { - g_set_error(err, GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY, - _("Insufficient memory to load TGA image")); - return FALSE; - } - - pbuf = gdk_pixbuf_new_from_data (pixels, GDK_COLORSPACE_RGB, alpha, 8, - w, h, w * (alpha ? 4 : 3), - free_buffer, NULL); + pbuf = get_contiguous_pixbuf (w, h, alpha); if (!pbuf) { g_set_error(err, GDK_PIXBUF_ERROR, @@ -1153,8 +1153,6 @@ static GdkPixbuf *get_image_truecolor(FILE *f, TGAHeader *hdr, _("Can't allocate pixbuf")); return NULL; } - pbuf->destroy_fn = free_buffer; - pbuf->destroy_fn_data = NULL; p = pbuf->pixels; if (rle) { @@ -1203,7 +1201,6 @@ static GdkPixbuf *get_image_grayscale(FILE *f, TGAHeader *hdr, glong n, image_offset; guchar *p, color[2], tag; guint count, w, h; - guchar *pixels; gboolean alpha; image_offset = sizeof(TGAHeader) + hdr->infolen; @@ -1218,26 +1215,14 @@ static GdkPixbuf *get_image_grayscale(FILE *f, TGAHeader *hdr, alpha = (hdr->bpp == 16); - pixels = g_try_malloc (w * h * (alpha ? 4 : 3)); - - if (!pixels) { - g_set_error(err, GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY, - _("Insufficient memory to load TGA image")); - return FALSE; - } + pbuf = get_contiguous_pixbuf (w, h, alpha); - pbuf = gdk_pixbuf_new_from_data (pixels, GDK_COLORSPACE_RGB, alpha, 8, - w, h, w * (alpha ? 4 : 3), - free_buffer, NULL); - if (!pbuf) { g_set_error(err, GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY, _("Can't allocate pixbuf")); return NULL; } - pbuf->destroy_fn = free_buffer; - pbuf->destroy_fn_data = NULL; p = pbuf->pixels; if (rle) { diff --git a/gdk-pixbuf/io-xpm.c b/gdk-pixbuf/io-xpm.c index 2e6e33aae..3f0472989 100644 --- a/gdk-pixbuf/io-xpm.c +++ b/gdk-pixbuf/io-xpm.c @@ -1203,13 +1203,6 @@ mem_buffer (enum buf_op op, gpointer handle) return NULL; } -/* Destroy notification function for the pixbuf */ -static void -free_buffer (guchar *pixels, gpointer data) -{ - g_free (pixels); -} - /* This function does all the work. */ static GdkPixbuf * pixbuf_create_from_xpm (const gchar * (*get_buf) (enum buf_op op, gpointer handle), gpointer handle, @@ -1223,7 +1216,8 @@ pixbuf_create_from_xpm (const gchar * (*get_buf) (enum buf_op op, gpointer handl gchar pixel_str[32]; GHashTable *color_hash; XPMColor *colors, *color, *fallbackcolor; - guchar *pixels, *pixtmp; + guchar *pixtmp; + GdkPixbuf *pixbuf; fallbackcolor = NULL; @@ -1314,12 +1308,9 @@ pixbuf_create_from_xpm (const gchar * (*get_buf) (enum buf_op op, gpointer handl fallbackcolor = color; } - if (is_trans) - pixels = g_try_malloc (w * h * 4); - else - pixels = g_try_malloc (w * h * 3); + pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, is_trans, 8, w, h); - if (!pixels) { + if (!pixbuf) { g_set_error (error, GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY, @@ -1331,7 +1322,7 @@ pixbuf_create_from_xpm (const gchar * (*get_buf) (enum buf_op op, gpointer handl } wbytes = w * cpp; - pixtmp = pixels; + pixtmp = pixbuf->pixels; for (ycnt = 0; ycnt < h; ycnt++) { buffer = (*get_buf) (op_body, handle); @@ -1364,9 +1355,7 @@ pixbuf_create_from_xpm (const gchar * (*get_buf) (enum buf_op op, gpointer handl g_free (colors); g_free (name_buf); - return gdk_pixbuf_new_from_data (pixels, GDK_COLORSPACE_RGB, is_trans, 8, - w, h, is_trans ? (w * 4) : (w * 3), - free_buffer, NULL); + return pixbuf; } /* Shared library entry point for file loading */ |