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

Archive Download this file

Revision: 2182