summaryrefslogtreecommitdiff
path: root/gdk-pixbuf/io-png.c
diff options
context:
space:
mode:
authorMark Crichton <crichton@src.gnome.org>1999-06-30 15:28:43 +0000
committerMark Crichton <crichton@src.gnome.org>1999-06-30 15:28:43 +0000
commitfeb9789e643e419247bf3a6d0e5876e188ec5a11 (patch)
tree143c18978ac90c6a05e42b8e23aceeef3d96a946 /gdk-pixbuf/io-png.c
parenta0b1a437cc85c638100517aa6037786d3c0e65e7 (diff)
downloadgtk+-feb9789e643e419247bf3a6d0e5876e188ec5a11.tar.gz
io-gif.c, io-png.c: Actually put the licencing terms in the code now...
io-gif.c, io-png.c: Actually put the licencing terms in the code now... io-xpm.c: XPM parser baed off of gdk's, but this does something with the transparent colors.
Diffstat (limited to 'gdk-pixbuf/io-png.c')
-rw-r--r--gdk-pixbuf/io-png.c235
1 files changed, 122 insertions, 113 deletions
diff --git a/gdk-pixbuf/io-png.c b/gdk-pixbuf/io-png.c
index 789a086454..443010cdcc 100644
--- a/gdk-pixbuf/io-png.c
+++ b/gdk-pixbuf/io-png.c
@@ -1,8 +1,21 @@
/*
* io-png.c: GdkPixBuf I/O for PNG files.
+ * Copyright (C) 1999 Mark Crichton
+ * Author: Mark Crichton <crichton@gimp.org>
*
- * Author:
- * Mark Crichton <crichton@gimp.org>
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Cambridge, MA 02139, USA.
*
*/
#include <config.h>
@@ -15,137 +28,133 @@
/* Shared library entry point */
GdkPixBuf *image_load(FILE * f)
{
- png_structp png_ptr;
- png_infop info_ptr, end_info;
- gint i, depth, ctype, inttype, passes, bpp; /* bpp = BYTES/pixel */
- png_uint_32 w, h, x, y;
- png_bytepp rows;
- art_u8 *pixels, *temp, *rowdata;
- GdkPixBuf *pixbuf;
-
- g_return_val_if_fail (f != NULL, NULL);
-
- png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, NULL,
- NULL);
-
- info_ptr = png_create_info_struct (png_ptr);
- if (!info_ptr) {
- png_destroy_read_struct(&png_ptr, NULL, NULL);
- return NULL;
- }
+ png_structp png_ptr;
+ png_infop info_ptr, end_info;
+ gint i, depth, ctype, inttype, passes, bpp; /* bpp = BYTES/pixel */
+ png_uint_32 w, h, x, y;
+ png_bytepp rows;
+ art_u8 *pixels, *temp, *rowdata;
+ GdkPixBuf *pixbuf;
+
+ g_return_val_if_fail(f != NULL, NULL);
+
+ png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL,
+ NULL);
+
+ info_ptr = png_create_info_struct(png_ptr);
+ if (!info_ptr) {
+ png_destroy_read_struct(&png_ptr, NULL, NULL);
+ return NULL;
+ }
+ end_info = png_create_info_struct(png_ptr);
+ if (!end_info) {
+ png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
+ return NULL;
+ }
+ if (setjmp(png_ptr->jmpbuf)) {
+ png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
+ return NULL;
+ }
+ png_init_io(png_ptr, f);
+ png_read_info(png_ptr, info_ptr);
- end_info = png_create_info_struct (png_ptr);
- if (!end_info) {
- png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
- return NULL;
- }
+ png_get_IHDR(png_ptr, info_ptr, &w, &h, &depth, &ctype, &inttype,
+ NULL, NULL);
- if (setjmp(png_ptr->jmpbuf)) {
- png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
- return NULL;
- }
+ /* Ok, we want to work with 24 bit images.
+ * However, PNG can vary depth per channel.
+ * So, we use the png_set_expand function to expand
+ * everything into a format libart expects.
+ * We also use png_set_strip_16 to reduce down to 8 bit/chan.
+ */
- png_init_io(png_ptr, f);
- png_read_info(png_ptr, info_ptr);
+ if (ctype == PNG_COLOR_TYPE_PALETTE && depth <= 8)
+ png_set_expand(png_ptr);
- png_get_IHDR(png_ptr, info_ptr, &w, &h, &depth, &ctype, &inttype,
- NULL, NULL);
+ if (ctype == PNG_COLOR_TYPE_GRAY && depth < 8)
+ png_set_expand(png_ptr);
- /* Ok, we want to work with 24 bit images.
- * However, PNG can vary depth per channel.
- * So, we use the png_set_expand function to expand
- * everything into a format libart expects.
- * We also use png_set_strip_16 to reduce down to 8 bit/chan.
- */
+ if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
+ png_set_expand(png_ptr);
- if (ctype == PNG_COLOR_TYPE_PALETTE && depth <= 8)
- png_set_expand(png_ptr);
+ if (depth == 16)
+ png_set_strip_16(png_ptr);
- if (ctype == PNG_COLOR_TYPE_GRAY && depth < 8)
- png_set_expand(png_ptr);
+ /* We also have png "packing" bits into bytes if < 8 */
+ if (depth < 8)
+ png_set_packing(png_ptr);
- if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
- png_set_expand(png_ptr);
+ /* Lastly, if the PNG is greyscale, convert to RGB */
+ if (ctype == PNG_COLOR_TYPE_GRAY || ctype == PNG_COLOR_TYPE_GRAY_ALPHA)
+ png_set_gray_to_rgb(png_ptr);
- if (depth == 16)
- png_set_strip_16(png_ptr);
+ /* ...and if we're interlaced... */
+ passes = png_set_interlace_handling(png_ptr);
- /* We also have png "packing" bits into bytes if < 8 */
- if (depth < 8)
- png_set_packing(png_ptr);
+ /* Update our info structs */
+ png_read_update_info(png_ptr, info_ptr);
- /* Lastly, if the PNG is greyscale, convert to RGB */
- if (ctype == PNG_COLOR_TYPE_GRAY || ctype == PNG_COLOR_TYPE_GRAY_ALPHA)
- png_set_gray_to_rgb(png_ptr);
+ /* Allocate some memory and set up row array */
+ /* This "inhales vigirously"... */
+ if (ctype & PNG_COLOR_MASK_ALPHA)
+ bpp = 4;
+ else
+ bpp = 3;
- /* ...and if we're interlaced... */
- passes = png_set_interlace_handling(png_ptr);
+ pixels = art_alloc(w * h * bpp);
+ rows = g_malloc(h * sizeof(png_bytep));
- /* Update our info structs */
- png_read_update_info(png_ptr, info_ptr);
+ if ((!pixels) || (!rows)) {
+ png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
+ return NULL;
+ }
+ /* Icky code, but it has to be done... */
+ for (i = 0; i < h; i++) {
+ if ((rows[i] = g_malloc(w * sizeof(art_u8) * bpp)) == NULL) {
+ int n;
+ for (n = 0; n < i; n++)
+ g_free(rows[i]);
+ g_free(rows);
+ png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
+ return NULL;
+ }
+ }
- /* Allocate some memory and set up row array */
- /* This "inhales vigirously"... */
- if (ctype & PNG_COLOR_MASK_ALPHA)
- bpp = 4;
- else
- bpp = 3;
+ /* And we FINALLY get here... */
+ png_read_image(png_ptr, rows);
+ png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
- pixels = art_alloc(w*h*bpp);
- rows = g_malloc(h*sizeof(png_bytep));
+ /* Now stuff the bytes into pixels & free rows[y] */
- if ((!pixels) || (!rows)) {
- png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
- return NULL;
- }
+ temp = pixels;
- /* Icky code, but it has to be done... */
- for (i = 0; i < h; i++) {
- if ((rows[i] = g_malloc(w*sizeof(art_u8)*bpp)) == NULL) {
- int n;
- for (n = 0; n < i; n++)
- g_free(rows[i]);
- g_free(rows);
- png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
- return NULL;
- }
- }
-
- /* And we FINALLY get here... */
- png_read_image(png_ptr, rows);
- png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
-
- /* Now stuff the bytes into pixels & free rows[y] */
-
- temp = pixels;
-
- for (y = 0; y < h; y++) {
- (png_bytep)rowdata = rows[y];
- for (x = 0; x < w; x++) {
- temp[0] = rowdata[(x*bpp)];
- temp[1] = rowdata[(x*bpp)+1];
- temp[2] = rowdata[(x*bpp)+2];
- if (bpp == 4)
- temp[3] = rowdata[(x*bpp)+3];
- temp += bpp;
- }
- g_free(rows[y]);
+ for (y = 0; y < h; y++) {
+ (png_bytep) rowdata = rows[y];
+ for (x = 0; x < w; x++) {
+ temp[0] = rowdata[(x * bpp)];
+ temp[1] = rowdata[(x * bpp) + 1];
+ temp[2] = rowdata[(x * bpp) + 2];
+ if (bpp == 4)
+ temp[3] = rowdata[(x * bpp) + 3];
+ temp += bpp;
}
- g_free(rows);
+ g_free(rows[y]);
+ }
+ g_free(rows);
- /* Return the GdkPixBuf */
- pixbuf = g_new(GdkPixBuf, 1);
+ /* Return the GdkPixBuf */
+ pixbuf = g_new(GdkPixBuf, 1);
- if (ctype & PNG_COLOR_MASK_ALPHA)
- pixbuf->art_pixbuf = art_pixbuf_new_rgba (pixels, w, h, (w*4));
- else
- pixbuf->art_pixbuf = art_pixbuf_new_rgb (pixels, w, h, (w*3));
+ if (ctype & PNG_COLOR_MASK_ALPHA)
+ pixbuf->art_pixbuf = art_pixbuf_new_rgba(pixels, w, h, (w * 4));
+ else
+ pixbuf->art_pixbuf = art_pixbuf_new_rgb(pixels, w, h, (w * 3));
- /* Ok, I'm anal...shoot me */
- if (!(pixbuf->art_pixbuf))
- return NULL;
- pixbuf->ref_count = 0;
- pixbuf->unref_func = NULL;
+ /* Ok, I'm anal...shoot me */
+ if (!(pixbuf->art_pixbuf))
+ return NULL;
+ pixbuf->ref_count = 0;
+ pixbuf->unref_func = NULL;
- return pixbuf;
+ return pixbuf;
}