Chameleon

Chameleon Svn Source Tree

Root/branches/cparm/i386/modules/Libpng/PngFile.c

  • Property svn:executable set to *
1/*-------------------------------------
2 * PNGFILE.C -- Image File Functions
3 *-------------------------------------
4 *
5 * Copyright 2000, Willem van Schaik.
6 *
7 * This code is released under the libpng license.
8 * For conditions of distribution and use, see the disclaimer
9 * and license in png.h
10 */
11
12#include "libsaio.h"
13#include "stdio.h"
14
15#include "png.h"
16#include "pngfile.h"
17#include "modules.h"
18
19png_const_charp msg;
20
21static png_structp png_ptr = NULL;
22static png_infop info_ptr = NULL;
23
24void png_file_init(void);
25void png_file_init(void){}
26
27static bool PngHandleFile (FILE *pfFile , unsigned char **ppbImageData,
28 int *piWidth, int *piHeight, int *piChannels, void *BkgColor);
29/* cexcept interface */
30
31static void
32png_cexcept_error(png_structp png_ptr, png_const_charp msg)
33{
34 if(png_ptr)
35 ;
36 printf("libpng error: %s\n", msg);
37 {
38 Throw (-1);
39 }
40}
41
42#ifndef PNG_STDIO_SUPPORTED
43typedef FILE * png_FILE_p;
44static void PNGCBAPI
45png_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
46{
47png_size_t check = 0;
48png_voidp io_ptr;
49
50/* fread() returns 0 on error, so it is OK to store this in a png_size_t
51 * instead of an int, which is what fread() actually returns.
52 */
53io_ptr = png_get_io_ptr(png_ptr);
54if (io_ptr != NULL)
55{
56check = fread(data, 1, length, (png_FILE_p)io_ptr);
57}
58
59if (check != length)
60{
61png_error(png_ptr, "Read Error");
62}
63
64}
65
66#endif
67
68/* PNG image handler functions */
69
70static bool PngHandleFile (FILE *pfFile , unsigned char **ppbImageData,
71 int *piWidth, int *piHeight, int *piChannels, void *BkgColor)
72{
73 png_byte pbSig[8];
74 int iBitDepth;
75 int iColorType;
76#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
77#ifdef PNG_FLOATING_POINT_SUPPORTED
78 double dGamma;
79 png_color_16 *pBackground;
80 png_color *pBkgColor = (png_color *)BkgColor;
81#endif
82#endif
83 png_uint_32 ulChannels;
84 png_uint_32 ulRowBytes;
85 png_byte *pbImageData = *ppbImageData;
86 static png_byte **ppbRowPointers = NULL;
87 int i;
88
89 /* first check the eight byte PNG signature */
90
91 fread(pbSig, 1, 8, pfFile);
92
93 if (png_sig_cmp(pbSig, 0, 8))
94 {
95 *ppbImageData = pbImageData = NULL;
96 return false;
97 }
98
99 /* create the two png(-info) structures */
100
101 png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL,
102 (png_error_ptr)png_cexcept_error, (png_error_ptr)NULL);
103 if (!png_ptr)
104 {
105 *ppbImageData = pbImageData = NULL;
106 return false;
107 }
108
109 info_ptr = png_create_info_struct(png_ptr);
110 if (!info_ptr)
111 {
112 png_destroy_read_struct(&png_ptr, NULL, NULL);
113 *ppbImageData = pbImageData = NULL;
114 return false;
115 }
116
117 CEXCEPTION_T e = CEXCEPTION_NONE;
118
119 Try
120 {
121
122 /* initialize the png structure */
123
124#ifdef PNG_STDIO_SUPPORTED
125 png_init_io(png_ptr, pfFile);
126#else
127 png_set_read_fn(png_ptr, (png_voidp)pfFile, png_read_data);
128#endif
129
130 png_set_sig_bytes(png_ptr, 8);
131
132 /* read all PNG info up to image data */
133
134 png_read_info(png_ptr, info_ptr);
135
136 /* get width, height, bit-depth and color-type */
137
138 png_get_IHDR(png_ptr, info_ptr, (png_uint_32*)piWidth, (png_uint_32*)piHeight, &iBitDepth,
139 &iColorType, NULL, NULL, NULL);
140
141 /* expand images of all color-type and bit-depth to 3x8-bit RGB */
142 /* let the library process alpha, transparency, background, etc. */
143
144#ifdef PNG_READ_16_TO_8_SUPPORTED
145 if (iBitDepth == 16)
146# ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
147 png_set_scale_16(png_ptr);
148# else
149 png_set_strip_16(png_ptr);
150# endif
151#endif
152 if (iColorType == PNG_COLOR_TYPE_PALETTE)
153 png_set_expand(png_ptr);
154 if (iBitDepth < 8)
155 png_set_expand(png_ptr);
156 if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
157 png_set_expand(png_ptr);
158 if (iColorType == PNG_COLOR_TYPE_GRAY ||
159 iColorType == PNG_COLOR_TYPE_GRAY_ALPHA)
160 png_set_gray_to_rgb(png_ptr);
161#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
162#ifdef PNG_FLOATING_POINT_SUPPORTED
163 /* set the background color to draw transparent and alpha images over */
164 if (png_get_bKGD(png_ptr, info_ptr, &pBackground))
165 {
166 png_set_background(png_ptr, pBackground, PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
167 pBkgColor->red = (png_byte) pBackground->red;
168 pBkgColor->green = (png_byte) pBackground->green;
169 pBkgColor->blue = (png_byte) pBackground->blue;
170 }
171 else
172 {
173 pBkgColor = NULL;
174 }
175
176 /* if required set gamma conversion */
177 if (png_get_gAMA(png_ptr, info_ptr, &dGamma))
178 png_set_gamma(png_ptr, (double) 2.2, dGamma);
179#endif
180#endif
181
182 /* after the transformations are registered, update info_ptr data */
183
184 png_read_update_info(png_ptr, info_ptr);
185
186 /* get again width, height and the new bit-depth and color-type */
187
188 png_get_IHDR(png_ptr, info_ptr, (png_uint_32*)piWidth, (png_uint_32*)piHeight, &iBitDepth,
189 &iColorType, NULL, NULL, NULL);
190
191
192 /* row_bytes is the width x number of channels */
193
194 ulRowBytes = png_get_rowbytes(png_ptr, info_ptr);
195 ulChannels = png_get_channels(png_ptr, info_ptr);
196
197 *piChannels = ulChannels;
198
199 /* now we can allocate memory to store the image */
200
201 if (pbImageData)
202 {
203 free (pbImageData);
204 pbImageData = NULL;
205 }
206 if ((pbImageData = (png_byte *) malloc(ulRowBytes * (*piHeight)
207 * sizeof(png_byte))) == NULL)
208 {
209 png_error(png_ptr, "Visual PNG: out of memory");
210 }
211 *ppbImageData = pbImageData;
212
213 /* and allocate memory for an array of row-pointers */
214
215 if ((ppbRowPointers = (png_bytepp) malloc((*piHeight)
216 * sizeof(png_bytep))) == NULL)
217 {
218 png_error(png_ptr, "Visual PNG: out of memory");
219 }
220
221 /* set the individual row-pointers to point at the correct offsets */
222
223 for (i = 0; i < (*piHeight); i++)
224 ppbRowPointers[i] = pbImageData + i * ulRowBytes;
225
226 /* now we can go ahead and just read the whole image */
227
228 png_read_image(png_ptr, ppbRowPointers);
229
230 /* read the additional chunks in the PNG file (not really needed) */
231
232 png_read_end(png_ptr, NULL);
233
234 /* and we're done */
235
236 free (ppbRowPointers);
237 ppbRowPointers = NULL;
238
239 /* yepp, done */
240 }
241
242 Catch (e)
243 {
244 png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
245
246 *ppbImageData = pbImageData = NULL;
247
248 if(ppbRowPointers)
249 free (ppbRowPointers);
250
251
252 return false;
253 }
254
255
256 return true;
257}
258
259bool PngLoadImage (const char* pstrFileName, unsigned char **ppbImageData,
260 int *piWidth, int *piHeight, int *piChannels, void *BkgColor)
261{
262 static FILE *pfFile;
263 png_byte *pbImageData = *ppbImageData;
264 bool ret;
265 /* open the PNG input file */
266
267 if (!pstrFileName)
268 {
269 *ppbImageData = pbImageData = NULL;
270 return false;
271 }
272
273 if (!(pfFile = fopen(pstrFileName, "rb")))
274 {
275 *ppbImageData = pbImageData = NULL;
276 return false;
277 }
278 ret = PngHandleFile(pfFile, ppbImageData,
279 piWidth, piHeight, piChannels, BkgColor);
280
281 fclose (pfFile);
282
283 return ret;
284}
285
286bool PngLoadData(unsigned char *pngData, int pngSize, int *piWidth,
287 int *piHeight, unsigned char **ppbImageData, int *piChannels, void *BkgColor)
288{
289
290 static FILE *pfFile;
291 png_byte *pbImageData = *ppbImageData;
292 bool ret;
293 int fd ;
294 /* open the PNG input file */
295
296 if (!pngData)
297 {
298 *ppbImageData = pbImageData = NULL;
299 return false;
300 }
301
302 if ((fd = openmem((char*)pngData, pngSize)) < 0)
303 {
304 *ppbImageData = pbImageData = NULL;
305 return false;
306 }
307
308 if (!(pfFile = fdopen(fd, "rb")))
309 {
310 *ppbImageData = pbImageData = NULL;
311 return false;
312 }
313 ret = PngHandleFile(pfFile, ppbImageData,
314 piWidth, piHeight, piChannels, BkgColor);
315
316 fclose (pfFile);
317
318 return ret;
319}
320
321void PngLoadImage_hook(void* arg1, void* arg2, void* arg3, void* arg4, void* arg5, void* arg6)
322{
323 void *BkgColor = NULL;
324 const char*pstrFileName = (const char*)arg1;
325 int *piWidth = (int *)arg3;
326 int *piHeight = (int *)arg4;
327 unsigned char **ppbImageData = (unsigned char **)arg5;
328 int *piChannels = (int *)arg6;
329 bool ret ;
330 ret = PngLoadImage (pstrFileName, ppbImageData,
331 piWidth, piHeight, piChannels, BkgColor);
332
333 if (ret == false) {
334 *piHeight =0;
335 *piWidth = 0;
336 *ppbImageData = NULL;
337 *piChannels = 0;
338 }
339}
340
341void PngLoadData_hook(void* arg1, void* arg2, void* arg3, void* arg4, void* arg5, void* arg6)
342{
343 void *BkgColor = NULL;
344 unsigned char *pngData = (unsigned char *)arg1;
345 int pngSize = *(int*)arg2;
346 int *piWidth = (int *)arg3;
347 int *piHeight = (int *)arg4;
348 unsigned char **ppbImageData = (unsigned char **)arg5;
349 int *piChannels = (int *)arg6;
350 bool ret ;
351
352
353 ret = PngLoadData(pngData, pngSize, piWidth,
354 piHeight, ppbImageData, piChannels, BkgColor);
355
356 if (ret == false) {
357 *piHeight =0;
358 *piWidth = 0;
359 *ppbImageData = NULL;
360 *piChannels = 0;
361 }
362}
363
364void Libpng_start(void);
365void Libpng_start(void)
366{
367register_hook_callback("PngLoadData", &PngLoadData_hook);
368 register_hook_callback("PngLoadImage", &PngLoadImage_hook);
369
370
371}
372
373/*-----------------
374 * end of source
375 *-----------------
376 */
377

Archive Download this file

Revision: 2154