Mercurial > fife-parpg
comparison ext/libpng-1.2.29/contrib/visupng/PngFile.c @ 0:4a0efb7baf70
* Datasets becomes the new trunk and retires after that :-)
author | mvbarracuda@33b003aa-7bff-0310-803a-e67f0ece8222 |
---|---|
date | Sun, 29 Jun 2008 18:44:17 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4a0efb7baf70 |
---|---|
1 //------------------------------------- | |
2 // PNGFILE.C -- Image File Functions | |
3 //------------------------------------- | |
4 | |
5 // Copyright 2000, Willem van Schaik. For conditions of distribution and | |
6 // use, see the copyright/license/disclaimer notice in png.h | |
7 | |
8 #include <windows.h> | |
9 #include <commdlg.h> | |
10 #include <stdio.h> | |
11 #include <stdlib.h> | |
12 | |
13 #include "png.h" | |
14 #include "pngfile.h" | |
15 #include "cexcept.h" | |
16 | |
17 define_exception_type(const char *); | |
18 extern struct exception_context the_exception_context[1]; | |
19 struct exception_context the_exception_context[1]; | |
20 png_const_charp msg; | |
21 | |
22 static OPENFILENAME ofn; | |
23 | |
24 static png_structp png_ptr = NULL; | |
25 static png_infop info_ptr = NULL; | |
26 | |
27 | |
28 // cexcept interface | |
29 | |
30 static void | |
31 png_cexcept_error(png_structp png_ptr, png_const_charp msg) | |
32 { | |
33 if(png_ptr) | |
34 ; | |
35 #ifndef PNG_NO_CONSOLE_IO | |
36 fprintf(stderr, "libpng error: %s\n", msg); | |
37 #endif | |
38 { | |
39 Throw msg; | |
40 } | |
41 } | |
42 | |
43 // Windows open-file functions | |
44 | |
45 void PngFileInitialize (HWND hwnd) | |
46 { | |
47 static TCHAR szFilter[] = TEXT ("PNG Files (*.PNG)\0*.png\0") | |
48 TEXT ("All Files (*.*)\0*.*\0\0"); | |
49 | |
50 ofn.lStructSize = sizeof (OPENFILENAME); | |
51 ofn.hwndOwner = hwnd; | |
52 ofn.hInstance = NULL; | |
53 ofn.lpstrFilter = szFilter; | |
54 ofn.lpstrCustomFilter = NULL; | |
55 ofn.nMaxCustFilter = 0; | |
56 ofn.nFilterIndex = 0; | |
57 ofn.lpstrFile = NULL; // Set in Open and Close functions | |
58 ofn.nMaxFile = MAX_PATH; | |
59 ofn.lpstrFileTitle = NULL; // Set in Open and Close functions | |
60 ofn.nMaxFileTitle = MAX_PATH; | |
61 ofn.lpstrInitialDir = NULL; | |
62 ofn.lpstrTitle = NULL; | |
63 ofn.Flags = 0; // Set in Open and Close functions | |
64 ofn.nFileOffset = 0; | |
65 ofn.nFileExtension = 0; | |
66 ofn.lpstrDefExt = TEXT ("png"); | |
67 ofn.lCustData = 0; | |
68 ofn.lpfnHook = NULL; | |
69 ofn.lpTemplateName = NULL; | |
70 } | |
71 | |
72 BOOL PngFileOpenDlg (HWND hwnd, PTSTR pstrFileName, PTSTR pstrTitleName) | |
73 { | |
74 ofn.hwndOwner = hwnd; | |
75 ofn.lpstrFile = pstrFileName; | |
76 ofn.lpstrFileTitle = pstrTitleName; | |
77 ofn.Flags = OFN_HIDEREADONLY; | |
78 | |
79 return GetOpenFileName (&ofn); | |
80 } | |
81 | |
82 BOOL PngFileSaveDlg (HWND hwnd, PTSTR pstrFileName, PTSTR pstrTitleName) | |
83 { | |
84 ofn.hwndOwner = hwnd; | |
85 ofn.lpstrFile = pstrFileName; | |
86 ofn.lpstrFileTitle = pstrTitleName; | |
87 ofn.Flags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT; | |
88 | |
89 return GetSaveFileName (&ofn); | |
90 } | |
91 | |
92 // PNG image handler functions | |
93 | |
94 BOOL PngLoadImage (PTSTR pstrFileName, png_byte **ppbImageData, | |
95 int *piWidth, int *piHeight, int *piChannels, png_color *pBkgColor) | |
96 { | |
97 static FILE *pfFile; | |
98 png_byte pbSig[8]; | |
99 int iBitDepth; | |
100 int iColorType; | |
101 double dGamma; | |
102 png_color_16 *pBackground; | |
103 png_uint_32 ulChannels; | |
104 png_uint_32 ulRowBytes; | |
105 png_byte *pbImageData = *ppbImageData; | |
106 static png_byte **ppbRowPointers = NULL; | |
107 int i; | |
108 | |
109 // open the PNG input file | |
110 | |
111 if (!pstrFileName) | |
112 { | |
113 *ppbImageData = pbImageData = NULL; | |
114 return FALSE; | |
115 } | |
116 | |
117 if (!(pfFile = fopen(pstrFileName, "rb"))) | |
118 { | |
119 *ppbImageData = pbImageData = NULL; | |
120 return FALSE; | |
121 } | |
122 | |
123 // first check the eight byte PNG signature | |
124 | |
125 fread(pbSig, 1, 8, pfFile); | |
126 if (!png_check_sig(pbSig, 8)) | |
127 { | |
128 *ppbImageData = pbImageData = NULL; | |
129 return FALSE; | |
130 } | |
131 | |
132 // create the two png(-info) structures | |
133 | |
134 png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, | |
135 (png_error_ptr)png_cexcept_error, (png_error_ptr)NULL); | |
136 if (!png_ptr) | |
137 { | |
138 *ppbImageData = pbImageData = NULL; | |
139 return FALSE; | |
140 } | |
141 | |
142 info_ptr = png_create_info_struct(png_ptr); | |
143 if (!info_ptr) | |
144 { | |
145 png_destroy_read_struct(&png_ptr, NULL, NULL); | |
146 *ppbImageData = pbImageData = NULL; | |
147 return FALSE; | |
148 } | |
149 | |
150 Try | |
151 { | |
152 | |
153 // initialize the png structure | |
154 | |
155 #if !defined(PNG_NO_STDIO) | |
156 png_init_io(png_ptr, pfFile); | |
157 #else | |
158 png_set_read_fn(png_ptr, (png_voidp)pfFile, png_read_data); | |
159 #endif | |
160 | |
161 png_set_sig_bytes(png_ptr, 8); | |
162 | |
163 // read all PNG info up to image data | |
164 | |
165 png_read_info(png_ptr, info_ptr); | |
166 | |
167 // get width, height, bit-depth and color-type | |
168 | |
169 png_get_IHDR(png_ptr, info_ptr, piWidth, piHeight, &iBitDepth, | |
170 &iColorType, NULL, NULL, NULL); | |
171 | |
172 // expand images of all color-type and bit-depth to 3x8 bit RGB images | |
173 // let the library process things like alpha, transparency, background | |
174 | |
175 if (iBitDepth == 16) | |
176 png_set_strip_16(png_ptr); | |
177 if (iColorType == PNG_COLOR_TYPE_PALETTE) | |
178 png_set_expand(png_ptr); | |
179 if (iBitDepth < 8) | |
180 png_set_expand(png_ptr); | |
181 if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) | |
182 png_set_expand(png_ptr); | |
183 if (iColorType == PNG_COLOR_TYPE_GRAY || | |
184 iColorType == PNG_COLOR_TYPE_GRAY_ALPHA) | |
185 png_set_gray_to_rgb(png_ptr); | |
186 | |
187 // set the background color to draw transparent and alpha images over. | |
188 if (png_get_bKGD(png_ptr, info_ptr, &pBackground)) | |
189 { | |
190 png_set_background(png_ptr, pBackground, PNG_BACKGROUND_GAMMA_FILE, 1, 1.0); | |
191 pBkgColor->red = (byte) pBackground->red; | |
192 pBkgColor->green = (byte) pBackground->green; | |
193 pBkgColor->blue = (byte) pBackground->blue; | |
194 } | |
195 else | |
196 { | |
197 pBkgColor = NULL; | |
198 } | |
199 | |
200 // if required set gamma conversion | |
201 if (png_get_gAMA(png_ptr, info_ptr, &dGamma)) | |
202 png_set_gamma(png_ptr, (double) 2.2, dGamma); | |
203 | |
204 // after the transformations have been registered update info_ptr data | |
205 | |
206 png_read_update_info(png_ptr, info_ptr); | |
207 | |
208 // get again width, height and the new bit-depth and color-type | |
209 | |
210 png_get_IHDR(png_ptr, info_ptr, piWidth, piHeight, &iBitDepth, | |
211 &iColorType, NULL, NULL, NULL); | |
212 | |
213 | |
214 // row_bytes is the width x number of channels | |
215 | |
216 ulRowBytes = png_get_rowbytes(png_ptr, info_ptr); | |
217 ulChannels = png_get_channels(png_ptr, info_ptr); | |
218 | |
219 *piChannels = ulChannels; | |
220 | |
221 // now we can allocate memory to store the image | |
222 | |
223 if (pbImageData) | |
224 { | |
225 free (pbImageData); | |
226 pbImageData = NULL; | |
227 } | |
228 if ((pbImageData = (png_byte *) malloc(ulRowBytes * (*piHeight) | |
229 * sizeof(png_byte))) == NULL) | |
230 { | |
231 png_error(png_ptr, "Visual PNG: out of memory"); | |
232 } | |
233 *ppbImageData = pbImageData; | |
234 | |
235 // and allocate memory for an array of row-pointers | |
236 | |
237 if ((ppbRowPointers = (png_bytepp) malloc((*piHeight) | |
238 * sizeof(png_bytep))) == NULL) | |
239 { | |
240 png_error(png_ptr, "Visual PNG: out of memory"); | |
241 } | |
242 | |
243 // set the individual row-pointers to point at the correct offsets | |
244 | |
245 for (i = 0; i < (*piHeight); i++) | |
246 ppbRowPointers[i] = pbImageData + i * ulRowBytes; | |
247 | |
248 // now we can go ahead and just read the whole image | |
249 | |
250 png_read_image(png_ptr, ppbRowPointers); | |
251 | |
252 // read the additional chunks in the PNG file (not really needed) | |
253 | |
254 png_read_end(png_ptr, NULL); | |
255 | |
256 // and we're done | |
257 | |
258 free (ppbRowPointers); | |
259 ppbRowPointers = NULL; | |
260 | |
261 // yepp, done | |
262 } | |
263 | |
264 Catch (msg) | |
265 { | |
266 png_destroy_read_struct(&png_ptr, &info_ptr, NULL); | |
267 | |
268 *ppbImageData = pbImageData = NULL; | |
269 | |
270 if(ppbRowPointers) | |
271 free (ppbRowPointers); | |
272 | |
273 fclose(pfFile); | |
274 | |
275 return FALSE; | |
276 } | |
277 | |
278 fclose (pfFile); | |
279 | |
280 return TRUE; | |
281 } | |
282 | |
283 | |
284 BOOL PngSaveImage (PTSTR pstrFileName, png_byte *pDiData, | |
285 int iWidth, int iHeight, png_color bkgColor) | |
286 { | |
287 const int ciBitDepth = 8; | |
288 const int ciChannels = 3; | |
289 | |
290 static FILE *pfFile; | |
291 png_uint_32 ulRowBytes; | |
292 static png_byte **ppbRowPointers = NULL; | |
293 int i; | |
294 | |
295 // open the PNG output file | |
296 | |
297 if (!pstrFileName) | |
298 return FALSE; | |
299 | |
300 if (!(pfFile = fopen(pstrFileName, "wb"))) | |
301 return FALSE; | |
302 | |
303 // prepare the standard PNG structures | |
304 | |
305 png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, | |
306 (png_error_ptr)png_cexcept_error, (png_error_ptr)NULL); | |
307 if (!png_ptr) | |
308 { | |
309 fclose(pfFile); | |
310 return FALSE; | |
311 } | |
312 | |
313 info_ptr = png_create_info_struct(png_ptr); | |
314 if (!info_ptr) { | |
315 fclose(pfFile); | |
316 png_destroy_write_struct(&png_ptr, (png_infopp) NULL); | |
317 return FALSE; | |
318 } | |
319 | |
320 Try | |
321 { | |
322 // initialize the png structure | |
323 | |
324 #if !defined(PNG_NO_STDIO) | |
325 png_init_io(png_ptr, pfFile); | |
326 #else | |
327 png_set_write_fn(png_ptr, (png_voidp)pfFile, png_write_data, png_flush); | |
328 #endif | |
329 | |
330 // we're going to write a very simple 3x8 bit RGB image | |
331 | |
332 png_set_IHDR(png_ptr, info_ptr, iWidth, iHeight, ciBitDepth, | |
333 PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, | |
334 PNG_FILTER_TYPE_BASE); | |
335 | |
336 // write the file header information | |
337 | |
338 png_write_info(png_ptr, info_ptr); | |
339 | |
340 // swap the BGR pixels in the DiData structure to RGB | |
341 | |
342 png_set_bgr(png_ptr); | |
343 | |
344 // row_bytes is the width x number of channels | |
345 | |
346 ulRowBytes = iWidth * ciChannels; | |
347 | |
348 // we can allocate memory for an array of row-pointers | |
349 | |
350 if ((ppbRowPointers = (png_bytepp) malloc(iHeight * sizeof(png_bytep))) == NULL) | |
351 Throw "Visualpng: Out of memory"; | |
352 | |
353 // set the individual row-pointers to point at the correct offsets | |
354 | |
355 for (i = 0; i < iHeight; i++) | |
356 ppbRowPointers[i] = pDiData + i * (((ulRowBytes + 3) >> 2) << 2); | |
357 | |
358 // write out the entire image data in one call | |
359 | |
360 png_write_image (png_ptr, ppbRowPointers); | |
361 | |
362 // write the additional chunks to the PNG file (not really needed) | |
363 | |
364 png_write_end(png_ptr, info_ptr); | |
365 | |
366 // and we're done | |
367 | |
368 free (ppbRowPointers); | |
369 ppbRowPointers = NULL; | |
370 | |
371 // clean up after the write, and free any memory allocated | |
372 | |
373 png_destroy_write_struct(&png_ptr, (png_infopp) NULL); | |
374 | |
375 // yepp, done | |
376 } | |
377 | |
378 Catch (msg) | |
379 { | |
380 png_destroy_write_struct(&png_ptr, (png_infopp) NULL); | |
381 | |
382 if(ppbRowPointers) | |
383 free (ppbRowPointers); | |
384 | |
385 fclose(pfFile); | |
386 | |
387 return FALSE; | |
388 } | |
389 | |
390 fclose (pfFile); | |
391 | |
392 return TRUE; | |
393 } | |
394 | |
395 #ifdef PNG_NO_STDIO | |
396 | |
397 static void | |
398 png_read_data(png_structp png_ptr, png_bytep data, png_size_t length) | |
399 { | |
400 png_size_t check; | |
401 | |
402 /* fread() returns 0 on error, so it is OK to store this in a png_size_t | |
403 * instead of an int, which is what fread() actually returns. | |
404 */ | |
405 check = (png_size_t)fread(data, (png_size_t)1, length, | |
406 (FILE *)png_ptr->io_ptr); | |
407 | |
408 if (check != length) | |
409 { | |
410 png_error(png_ptr, "Read Error"); | |
411 } | |
412 } | |
413 | |
414 static void | |
415 png_write_data(png_structp png_ptr, png_bytep data, png_size_t length) | |
416 { | |
417 png_uint_32 check; | |
418 | |
419 check = fwrite(data, 1, length, (FILE *)(png_ptr->io_ptr)); | |
420 if (check != length) | |
421 { | |
422 png_error(png_ptr, "Write Error"); | |
423 } | |
424 } | |
425 | |
426 static void | |
427 png_flush(png_structp png_ptr) | |
428 { | |
429 FILE *io_ptr; | |
430 io_ptr = (FILE *)CVT_PTR((png_ptr->io_ptr)); | |
431 if (io_ptr != NULL) | |
432 fflush(io_ptr); | |
433 } | |
434 | |
435 #endif | |
436 | |
437 //----------------- | |
438 // end of source | |
439 //----------------- |