A little comment about a compilation matter: -lungif parameter is not usually correct...
[fbv.git] / png.c
blob52b6797b478660a2d8cd50b08917b0afdcf5daeb
1 /*
2 fbv -- simple image viewer for the linux framebuffer
3 Copyright (C) 2000, 2001, 2003 Mateusz Golicz
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #include "config.h"
21 #ifdef FBV_SUPPORT_PNG
22 #include <png.h>
23 #include "fbv.h"
24 #include <sys/types.h>
25 #include <sys/stat.h>
26 #include <fcntl.h>
27 #include <unistd.h>
28 #include <stdlib.h>
29 #include <string.h>
31 #define PNG_BYTES_TO_CHECK 4
32 #ifndef min
33 #define min(x,y) ((x) < (y) ? (x) : (y))
34 #endif
36 int fh_png_id(char *name)
38 int fd;
39 char id[4];
40 fd=open(name,O_RDONLY); if(fd==-1) return(0);
41 read(fd,id,4);
42 close(fd);
43 if(id[1]=='P' && id[2]=='N' && id[3]=='G') return(1);
44 return(0);
48 int fh_png_load(char *name,unsigned char *buffer, unsigned char ** alpha,int x,int y)
50 png_structp png_ptr;
51 png_infop info_ptr;
52 png_uint_32 width, height;
53 int i;
54 int bit_depth, color_type, interlace_type;
55 int number_passes,pass, trans = 0;
56 char *rp;
57 png_bytep rptr[2];
58 char *fbptr;
59 FILE *fh;
61 if(!(fh=fopen(name,"rb"))) return(FH_ERROR_FILE);
63 png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,NULL,NULL,NULL);
64 if (png_ptr == NULL) return(FH_ERROR_FORMAT);
65 info_ptr = png_create_info_struct(png_ptr);
66 if (info_ptr == NULL)
68 png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
69 fclose(fh); return(FH_ERROR_FORMAT);
71 rp=0;
72 if (setjmp(png_jmpbuf(png_ptr)))
74 png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
75 if(rp) free(rp);
76 fclose(fh); return(FH_ERROR_FORMAT);
79 png_init_io(png_ptr,fh);
81 png_read_info(png_ptr, info_ptr);
82 png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,&interlace_type, NULL, NULL);
83 if (color_type == PNG_COLOR_TYPE_PALETTE) png_set_expand(png_ptr);
84 if (bit_depth < 8) png_set_packing(png_ptr);
85 if (color_type == PNG_COLOR_TYPE_GRAY || color_type== PNG_COLOR_TYPE_GRAY_ALPHA) png_set_gray_to_rgb(png_ptr);
86 if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
88 trans = 1;
89 png_set_tRNS_to_alpha(png_ptr);
92 if(bit_depth == 16) png_set_strip_16(png_ptr);
93 number_passes = png_set_interlace_handling(png_ptr);
94 png_read_update_info(png_ptr,info_ptr);
96 if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA || color_type == PNG_COLOR_TYPE_RGB_ALPHA || trans)
98 unsigned char * alpha_buffer = (unsigned char*) malloc(width * height);
99 unsigned char * aptr;
101 rp = (char*) malloc(width * 4);
102 rptr[0] = (png_bytep) rp;
104 *alpha = alpha_buffer;
106 for (pass = 0; pass < number_passes; pass++)
108 fbptr = (char *)buffer;
109 aptr = alpha_buffer;
111 for(i=0; i<height; i++)
113 int n;
114 unsigned char *trp = (unsigned char *)rp;
116 png_read_rows(png_ptr, rptr, NULL, 1);
118 for(n = 0; n < width; n++, fbptr += 3, trp += 4)
120 memcpy(fbptr, trp, 3);
121 *(aptr++) = trp[3];
125 free(rp);
127 else
129 for (pass = 0; pass < number_passes; pass++)
131 fbptr = (char *)buffer;
132 for(i=0; i<height; i++, fbptr += width*3)
134 rptr[0] = (png_bytep) fbptr;
135 png_read_rows(png_ptr, rptr, NULL, 1);
139 png_read_end(png_ptr, info_ptr);
140 png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
141 fclose(fh);
142 return(FH_ERROR_OK);
144 int fh_png_getsize(char *name,int *x,int *y)
146 png_structp png_ptr;
147 png_infop info_ptr;
148 png_uint_32 width, height;
149 int bit_depth, color_type, interlace_type;
150 char *rp;
151 FILE *fh;
153 if(!(fh=fopen(name,"rb"))) return(FH_ERROR_FILE);
155 png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,NULL,NULL,NULL);
156 if (png_ptr == NULL) return(FH_ERROR_FORMAT);
157 info_ptr = png_create_info_struct(png_ptr);
158 if (info_ptr == NULL)
160 png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
161 fclose(fh); return(FH_ERROR_FORMAT);
163 rp=0;
164 if (setjmp(png_jmpbuf(png_ptr)))
166 png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
167 if(rp) free(rp);
168 fclose(fh); return(FH_ERROR_FORMAT);
171 png_init_io(png_ptr,fh);
172 png_read_info(png_ptr, info_ptr);
173 png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,&interlace_type, NULL, NULL);
174 png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
175 *x=width;
176 *y=height;
177 fclose(fh);
178 return(FH_ERROR_OK);
180 #endif