1 
2 /* PNG file module for IIViewer. */
3 
4 #ifdef INCLUDE_PNG
5 
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <unistd.h>
9 #include <png.h>
10 
11 #include "modules.h"
12 #include "png.h"
13 
14 static FILE *pngfile;
15 static int readsuccessful;
16 static int width,height;
17 
18 static png_bytep *row_pointers;
19 
PNG_OpenFile(const char * filename,const char * imgdir,unsigned int owidth,unsigned int oheight)20 int PNG_OpenFile(const char *filename,const char *imgdir,
21     unsigned int owidth, unsigned int oheight) {
22 
23 	unsigned char testbuf[8];
24 	png_structp png_ptr;
25 	png_infop info_ptr;
26 	int i,rowbytes,color_type,bit_depth;
27 
28 	UNUSED(imgdir); UNUSED(owidth); UNUSED(oheight);
29 
30 	readsuccessful=0;
31 	row_pointers=NULL;
32 
33 	if (filename==NULL) {
34 #ifdef DEBUG
35 		fprintf(stderr,"PNG: Filename is NULL\n");
36 #endif
37 		return 0;
38 	}
39 
40 	pngfile=NULL;
41 	if ((pngfile=fopen(filename,"r"))==NULL) {
42 #ifdef DEBUG
43 		fprintf(stderr,"PNG: File '%s' not found (in: '%s').\n",filename,
44 		    getcwd(NULL,256));
45 #endif
46 		return 0;
47 	}
48 
49 	fread(testbuf,1,4,pngfile);
50 	if (png_sig_cmp(testbuf,0,4)) {
51 #ifdef DEBUG
52 		fprintf(stderr,"PNG: header not valid.\n");
53 #endif
54 		return 0;
55 	}
56 
57 	png_ptr = png_create_read_struct
58 	    (PNG_LIBPNG_VER_STRING,NULL,NULL,NULL);
59 	if (!png_ptr) {
60 		fprintf(stderr,"PNG: png_create_read_struct failed.\n");
61 		return 0;
62 	}
63 
64 	info_ptr = png_create_info_struct(png_ptr);
65 	if (!info_ptr)
66 	{
67 		png_destroy_read_struct(&png_ptr,
68 		    (png_infopp)NULL, (png_infopp)NULL);
69 		fprintf(stderr,"PNG: png_create_info_struct failed.\n");
70 		return 0;
71 	}
72 
73 	png_init_io(png_ptr,pngfile);
74 	png_set_sig_bytes(png_ptr,4);
75 
76 	png_read_info(png_ptr, info_ptr);
77 	if ((width=png_get_image_width(png_ptr,info_ptr))==0) {
78 		fprintf(stderr,"PNG: Image width needed.\n");
79 		return 0;
80 	}
81 	if ((height=png_get_image_height(png_ptr,info_ptr))==0) {
82 		fprintf(stderr,"PNG: Image width needed.\n");
83 		return 0;
84 	}
85 
86 	if ((bit_depth=png_get_bit_depth(png_ptr,info_ptr))==16) {
87 		png_set_strip_16(png_ptr);
88 	}
89 
90 	color_type=png_get_color_type(png_ptr,info_ptr);
91 
92 	if (color_type == PNG_COLOR_TYPE_PALETTE)
93 		png_set_palette_to_rgb(png_ptr);
94 
95 	if (color_type == PNG_COLOR_TYPE_GRAY ||
96 	    color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
97 		png_set_gray_to_rgb(png_ptr);
98 
99 	if (color_type & PNG_COLOR_MASK_ALPHA)
100 		png_set_strip_alpha(png_ptr);
101 
102 	png_read_update_info(png_ptr, info_ptr);
103 
104 	rowbytes = png_get_rowbytes(png_ptr, info_ptr);
105 
106 #ifdef DEBUG
107 	fprintf(stderr,"PNG: Allocating memory (image size: %dx%d) (rowbytes: %d).\n",
108 	    width,height,rowbytes);
109 #endif
110 
111 	if ((row_pointers=malloc(sizeof(png_bytep)*height))==NULL) {
112 		fprintf(stderr,"PNG: Out of memory\n");
113 		return 0;
114 	}
115 	for (i=0;i<height;i++) {
116 		if ((row_pointers[i]=malloc((unsigned int)rowbytes))==NULL) {
117 			fprintf(stderr,"PNG: Out of memory\n");
118 			return 0;
119 		}
120 	}
121 
122 #ifdef DEBUG
123 	fprintf(stderr,"PNG: Allocation done, reading image...\n");
124 #endif
125 
126 	png_read_image(png_ptr, row_pointers);
127 
128 #ifdef DEBUG
129 	fprintf(stderr,"PNG: Completed.\n");
130 #endif
131 
132 	readsuccessful=1;
133 
134 	fclose(pngfile);
135 	pngfile=NULL;
136 	return 1;
137 }
138 
PNG_CloseFile(void)139 void PNG_CloseFile(void) {
140 
141 	int i;
142 
143 	if (row_pointers!=NULL) {
144 		for (i=0;i<height;i++) {
145 			if (row_pointers[i]!=NULL) free(row_pointers[i]);
146 		}
147 
148 		free(row_pointers);
149 	}
150 
151 	if (pngfile!=NULL) fclose(pngfile);
152 	pngfile=NULL;
153 }
154 
PNG_GetPixel(int x,int y,int color)155 unsigned int PNG_GetPixel(int x,int y,int color) {
156 
157 	unsigned char *p;
158 
159 	UNUSED(color);
160 
161 	if (!readsuccessful || x<0 || x>=width || y<0 || y>=height) {
162 		return 0x000000;
163 	}
164 
165 	p=(unsigned char *)row_pointers[y]+x*3;
166 
167 	return ((int)*p<<16)|((int)*(p+1)<<8)|(*(p+2));
168 }
169 
PNG_GetWidth(void)170 int PNG_GetWidth(void) {
171 	return width;
172 }
173 
PNG_GetHeight(void)174 int PNG_GetHeight(void) {
175 	return height;
176 }
177 
178 #endif
179