Chameleon

Chameleon Svn Source Tree

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

Archive Download this file

Revision: 2182