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