1b0f75944c46221c73b3e37d720eacc39ccd7001
[summerhack] / src / 3dengfx / src / gfx / image_png.c
1 /*
2 Copyright 2004 John Tsiombikas <nuclear@siggraph.org>
3
4 This is a small image library.
5
6 This library is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this library; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 */
20
21 /* png support
22  * 
23  * author: John Tsiombikas 2003
24  * modified: John Tsiombikas 2004
25  */
26
27 #include "3dengfx_config.h"
28 #include "image.h"
29 #include <stdio.h>
30 #include <string.h>
31
32 #ifdef IMGLIB_USE_PNG
33
34 #include <stdlib.h>
35 #include <png.h>
36 #include "color_bits.h"
37 #include "common/types.h"
38
39 #define FILE_SIG_BYTES  8
40
41 int check_png(FILE *fp) {
42         unsigned char sig[FILE_SIG_BYTES];
43
44         fread(sig, 1, FILE_SIG_BYTES, fp);
45
46         return png_sig_cmp(sig, 0, FILE_SIG_BYTES) == 0 ? 1 : 0;
47 }
48
49 void *load_png(FILE *fp, unsigned long *xsz, unsigned long *ysz) {
50         png_struct *png_ptr;
51         png_info *info_ptr;
52         int i;
53         uint32_t **lineptr, *pixels;
54         int channel_bits, color_type, ilace_type, compression, filtering;
55         
56         if(!(png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0))) {
57                 fclose(fp);
58                 return 0;
59         }
60         
61         if(!(info_ptr = png_create_info_struct(png_ptr))) {
62                 png_destroy_read_struct(&png_ptr, 0, 0);
63                 fclose(fp);
64                 return 0;
65         }
66         
67         if(setjmp(png_jmpbuf(png_ptr))) {               
68                 png_destroy_read_struct(&png_ptr, &info_ptr, 0);
69                 fclose(fp);
70                 return 0;
71         }
72         
73         png_init_io(png_ptr, fp);       
74         png_set_sig_bytes(png_ptr, FILE_SIG_BYTES);
75         
76         png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_BGR, 0);
77                 
78         png_get_IHDR(png_ptr, info_ptr, xsz, ysz, &channel_bits, &color_type, &ilace_type, &compression, &filtering);
79         pixels = malloc(*xsz * *ysz * sizeof(uint32_t));
80         
81         lineptr = (uint32_t**)png_get_rows(png_ptr, info_ptr);
82         
83         for(i=0; i<*ysz; i++) {
84                 
85                 switch(color_type) {
86                 case PNG_COLOR_TYPE_RGB:
87                         {
88                                 int j;
89                                 unsigned char *ptr = (unsigned char*)lineptr[i];
90                                 for(j=0; j<*xsz; j++) {
91                         
92                                         uint32_t pixel;
93                                         pixel = PACK_COLOR24(*(ptr+2), *(ptr+1), *ptr);
94                                         ptr+=3;
95                                         pixels[i * *xsz + j] = pixel;                   
96                                 }
97                         }
98                         break;
99                         
100                 case PNG_COLOR_TYPE_RGB_ALPHA:
101                         memcpy(&pixels[i * *xsz], lineptr[i], *xsz * sizeof(uint32_t));
102                         break;
103                         
104                 default:
105                         png_destroy_read_struct(&png_ptr, &info_ptr, 0);
106                         fclose(fp);
107                         return 0;
108                 }
109                                 
110         }
111         
112         png_destroy_read_struct(&png_ptr, &info_ptr, 0);
113         fclose(fp);
114         
115         return pixels;
116 }
117
118 /* TODO: implement this */
119 int save_png(FILE *fp, void *pixels, unsigned long xsz, unsigned long ysz) {
120         fprintf(stderr, "saving png files is not implemented yet");
121         return -1;
122 }
123
124 #endif  /* IMGLIB_USE_PNG */