| 
					
				 | 
			
			
				@@ -22,12 +22,13 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include <stdlib.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include <png.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include "const.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 int 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 read_png(const char *filename, int *width, int *height, unsigned char **rgb,  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				      unsigned char **alpha) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    FILE *infile = fopen(filename, "rb"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    int ret = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     png_structp png_ptr; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     png_infop info_ptr; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -38,31 +39,27 @@ read_png(const char *filename, int *width, int *height, unsigned char **rgb, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     int bit_depth, color_type, interlace_type; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     int i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    FILE *infile = fopen(filename, "rb"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (infile == NULL) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        fprintf(stderr, "Can not fopen file: %s\n",filename); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return ret; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                      (png_voidp) NULL,  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                      (png_error_ptr) NULL,  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                      (png_error_ptr) NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (!png_ptr)  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        fclose(infile); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return(0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (!png_ptr) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        goto file_close; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     info_ptr = png_create_info_struct(png_ptr); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (!info_ptr) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (!info_ptr) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         png_destroy_read_struct(&png_ptr, (png_infopp) NULL,  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                 (png_infopp) NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        fclose(infile); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return(0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (setjmp(png_ptr->jmpbuf)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        fclose(infile); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return(0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        goto png_destroy; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     png_init_io(png_ptr, infile); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     png_read_info(png_ptr, info_ptr); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -70,18 +67,23 @@ read_png(const char *filename, int *width, int *height, unsigned char **rgb, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     png_get_IHDR(png_ptr, info_ptr, &w, &h, &bit_depth, &color_type, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                  &interlace_type, (int *) NULL, (int *) NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /* Prevent against integer overflow */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(w >= MAX_DIMENSION || h >= MAX_DIMENSION) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        fprintf(stderr, "Unreasonable dimension found in file: %s\n",filename); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        goto png_destroy; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     *width = (int) w; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     *height = (int) h; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				      
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (color_type == PNG_COLOR_TYPE_RGB_ALPHA 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    alpha[0] = malloc(*width * *height); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (alpha[0] == NULL) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        fprintf(stderr, "Can't allocate memory for alpha channel in PNG file.\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return(0);  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        alpha[0] = malloc(*width * *height); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (alpha[0] == NULL) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            fprintf(stderr, "Can't allocate memory for alpha channel in PNG file.\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            goto png_destroy; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     /* Change a paletted/grayscale image to RGB */ 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -94,68 +96,70 @@ read_png(const char *filename, int *width, int *height, unsigned char **rgb, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         png_set_gray_to_rgb(png_ptr); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     /* If the PNG file has 16 bits per channel, strip them down to 8 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (bit_depth == 16) png_set_strip_16(png_ptr); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (bit_depth == 16) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        png_set_strip_16(png_ptr); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     /* use 1 byte per pixel */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     png_set_packing(png_ptr); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     row_pointers = malloc(*height * sizeof(png_bytep)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (row_pointers == NULL) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (row_pointers == NULL) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         fprintf(stderr, "Can't allocate memory for PNG file.\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return(0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        goto png_destroy; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    for (i = 0; i < *height; i++) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for (i = 0; i < *height; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         row_pointers[i] = malloc(4 * *width); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (row_pointers == NULL) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (row_pointers == NULL) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             fprintf(stderr, "Can't allocate memory for PNG line.\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            return(0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            goto rows_free; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     png_read_image(png_ptr, row_pointers); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     rgb[0] = malloc(3 * *width * *height); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (rgb[0] == NULL) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (rgb[0] == NULL) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         fprintf(stderr, "Can't allocate memory for PNG file.\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return(0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        goto rows_free; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (alpha[0] == NULL) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    ptr = rgb[0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    for (i = 0; i < *height; i++) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        memcpy(ptr, row_pointers[i], 3 * *width); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ptr += 3 * *width; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    int j; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    ptr = rgb[0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    for (i = 0; i < *height; i++) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        int ipos = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        for (j = 0; j < *width; j++) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        *ptr++ = row_pointers[i][ipos++]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        *ptr++ = row_pointers[i][ipos++]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        *ptr++ = row_pointers[i][ipos++]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        alpha[0][i * *width + j] = row_pointers[i][ipos++]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ptr = rgb[0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for (i = 0; i < *height; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            memcpy(ptr, row_pointers[i], 3 * *width); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ptr += 3 * *width; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        int j; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ptr = rgb[0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for (i = 0; i < *height; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            int ipos = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            for (j = 0; j < *width; j++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                *ptr++ = row_pointers[i][ipos++]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                *ptr++ = row_pointers[i][ipos++]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                *ptr++ = row_pointers[i][ipos++]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                alpha[0][i * *width + j] = row_pointers[i][ipos++]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ret = 1; /* data reading is OK */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+rows_free: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for (i = 0; i < *height; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (row_pointers[i] != NULL ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            free(row_pointers[i]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    for (i = 0; i < *height; i++) free(row_pointers[i]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     free(row_pointers); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+png_destroy: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+file_close: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     fclose(infile); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return(1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return(ret); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 |