1 #include <stdlib.h>
2 #include <math.h>
3 #include "png/png.h"
4 #include "hpng.h"
5
6 char PngErrorMessage[1024];
7
my_png_error(png_structp png_ptr,png_const_charp message)8 void my_png_error(png_structp png_ptr, png_const_charp message) {
9 strcpy(PngErrorMessage,message);
10 }
11
12 // Load a PNG image -------------------------------------------
13
LoadPngImage(PNG_IMAGE * d)14 int LoadPngImage(PNG_IMAGE *d) {
15
16 png_structp png;
17 png_infop info;
18 png_infop endinfo;
19 png_bytep data;
20 png_bytep *row_p;
21 double fileGamma;
22 png_uint_32 width, height;
23 int depth, color, bpp;
24 png_uint_32 i,j;
25
26 // ------------- Open the file
27
28 FILE *fp = fopen(d->FileName, "rb");
29
30 if (fp == NULL) {
31 sprintf(PngErrorMessage,"Unable to open the file %s.",d->FileName);
32 return 0;
33 }
34
35 // ---------------- Create PNG handle
36
37 png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
38 if( png==NULL ) {
39 sprintf(PngErrorMessage,"Failed to create the PNG handle.");
40 return 0;
41 }
42 info = png_create_info_struct(png);
43 endinfo = png_create_info_struct(png);
44
45 // ---------------- Error handling
46
47 png_set_error_fn(png,NULL,my_png_error,NULL);
48 if (setjmp(png->jmpbuf)) {
49 png_destroy_read_struct(&png, &info, &endinfo);
50 return 0;
51 }
52
53 // ----------------- Read the image
54
55 png_init_io(png, fp);
56 png_read_info(png, info);
57 png_get_IHDR(png, info, &width, &height, &depth, &color, NULL, NULL, NULL);
58
59 d->width = width;
60 d->height = height;
61
62 if (color == PNG_COLOR_TYPE_GRAY || color == PNG_COLOR_TYPE_GRAY_ALPHA)
63 png_set_gray_to_rgb(png);
64
65 /*
66 if (color&PNG_COLOR_MASK_ALPHA && trans != PNG_ALPHA) {
67 png_set_strip_alpha(png);
68 color &= ~PNG_COLOR_MASK_ALPHA;
69 }
70 */
71
72 if (color == PNG_COLOR_TYPE_PALETTE)
73 png_set_expand(png);
74
75
76 if (png_get_gAMA(png, info, &fileGamma))
77 png_set_gamma(png, 2.2/1.0, fileGamma);
78 else
79 png_set_gamma(png, 2.2/1.0, 1.0/2.2);
80
81 png_read_update_info(png, info);
82
83
84 bpp = png_get_rowbytes(png, info)/width;
85 data = (png_bytep) malloc(png_get_rowbytes(png, info)*height);
86 row_p = (png_bytep *) malloc(sizeof(png_bytep)*height);
87
88 for (i = 0; i < height; i++) {
89 // row_p[height - 1 - i] = &data[png_get_rowbytes(png, info)*i];
90 row_p[i] = &data[png_get_rowbytes(png, info)*i];
91 }
92
93 png_read_image(png, row_p);
94 free(row_p);
95
96 png_read_end(png, endinfo);
97 png_destroy_read_struct(&png, &info, &endinfo);
98
99
100 // Convert the image
101 {
102 unsigned char *src = data;
103 unsigned char *dst = (unsigned char *)malloc(width*height*3);
104 d->data = dst;
105 for(i = 0 ; i < height ; i++) {
106 for(j = 0 ; j < width ; j++) {
107 dst[0] = src[2];
108 dst[1] = src[1];
109 dst[2] = src[0];
110 dst+=3;
111 src+=bpp;
112 }
113 }
114 }
115
116 free(data);
117 fclose(fp);
118
119 return 1;
120
121 }
122
123 // ---------------------------------------------------------------------
124
WritePngImage(char * file_name,unsigned long width,unsigned long height,unsigned char * data)125 char *WritePngImage(char *file_name,unsigned long width,unsigned long height,unsigned char *data) {
126
127 FILE *fp;
128 png_structp png_ptr;
129 png_infop info_ptr;
130 png_uint_32 k;
131 png_bytep *row_pointers;
132
133 // ------------- Open the file
134
135 fp = fopen(file_name, "wb");
136 if (fp == NULL) {
137 sprintf(PngErrorMessage,"Unable to open the file %s for writting",file_name);
138 return PngErrorMessage;
139 }
140
141 // ---------------- Create PNG handle
142
143 png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,NULL,NULL,NULL);
144
145 if (png_ptr == NULL)
146 {
147 sprintf(PngErrorMessage,"png_create_write_struct() failed");
148 fclose(fp);
149 return PngErrorMessage;
150 }
151
152 info_ptr = png_create_info_struct(png_ptr);
153 if (info_ptr == NULL)
154 {
155 sprintf(PngErrorMessage,"png_create_info_struct() failed");
156 fclose(fp);
157 png_destroy_write_struct(&png_ptr, png_infopp_NULL);
158 return PngErrorMessage;
159 }
160
161 // ---------------- Error handling
162
163 png_set_error_fn(png_ptr,NULL,my_png_error,NULL);
164
165 if (setjmp(png_jmpbuf(png_ptr)))
166 {
167 fclose(fp);
168 png_destroy_write_struct(&png_ptr, &info_ptr);
169 return PngErrorMessage;
170 }
171
172 // ---------------- Write the file
173
174 png_init_io(png_ptr, fp);
175 png_set_IHDR(png_ptr, info_ptr, width, height, 8, PNG_COLOR_TYPE_RGB,
176 PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
177 png_write_info(png_ptr, info_ptr);
178 png_set_bgr(png_ptr);
179
180 row_pointers = (png_bytep *)malloc(height * sizeof(png_bytep));
181 for (k = 0; k < height; k++)
182 row_pointers[k] = data + (k*width*3);
183
184 png_write_image(png_ptr, row_pointers);
185 png_write_end(png_ptr, info_ptr);
186
187 // Release allocated stuff
188 free(row_pointers);
189 png_destroy_write_struct(&png_ptr, &info_ptr);
190 fclose(fp);
191
192 /* that's it */
193 return NULL;
194
195 }
196