GRASS Programmer's Manual
6.4.2(2012)
|
00001 00002 #include <stdio.h> 00003 #include <stdlib.h> 00004 #include <png.h> 00005 00006 #include <grass/gis.h> 00007 #include "pngdriver.h" 00008 00009 void read_png(void) 00010 { 00011 static jmp_buf jbuf; 00012 static png_struct *png_ptr; 00013 static png_info *info_ptr; 00014 FILE *input; 00015 int x, y; 00016 unsigned int *p; 00017 png_bytep line; 00018 png_uint_32 i_width, i_height; 00019 int depth, color_type; 00020 00021 png_ptr = 00022 png_create_read_struct(PNG_LIBPNG_VER_STRING, &jbuf, NULL, NULL); 00023 if (!png_ptr) 00024 G_fatal_error("PNG: couldn't allocate PNG structure"); 00025 00026 info_ptr = png_create_info_struct(png_ptr); 00027 if (!info_ptr) 00028 G_fatal_error("PNG: couldn't allocate PNG structure"); 00029 00030 if (setjmp(png_jmpbuf(png_ptr))) 00031 G_fatal_error("error reading PNG file"); 00032 00033 input = fopen(file_name, "rb"); 00034 if (!input) 00035 G_fatal_error("PNG: couldn't open output file %s", file_name); 00036 00037 png_init_io(png_ptr, input); 00038 00039 png_read_info(png_ptr, info_ptr); 00040 00041 png_get_IHDR(png_ptr, info_ptr, &i_width, &i_height, 00042 &depth, &color_type, NULL, NULL, NULL); 00043 00044 if (depth != 8) 00045 G_fatal_error("PNG: input file is not 8-bit"); 00046 00047 if (i_width != width || i_height != height) 00048 G_fatal_error 00049 ("PNG: input file has incorrect dimensions: expected: %dx%d got: %lux%lu", 00050 width, height, (unsigned long) i_width, (unsigned long) i_height); 00051 00052 if (true_color) { 00053 if (color_type != PNG_COLOR_TYPE_RGB_ALPHA) 00054 G_fatal_error("PNG: input file is not RGBA"); 00055 } 00056 else { 00057 if (color_type != PNG_COLOR_TYPE_PALETTE) 00058 G_fatal_error("PNG: input file is not indexed color"); 00059 } 00060 00061 if (!true_color && has_alpha) { 00062 png_bytep trans; 00063 int num_trans; 00064 00065 png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, NULL); 00066 00067 if (num_trans != 1 || trans[0] != 0) 00068 G_fatal_error("PNG: input file has invalid palette"); 00069 } 00070 00071 if (true_color) 00072 png_set_invert_alpha(png_ptr); 00073 else { 00074 png_colorp png_pal; 00075 int num_palette; 00076 int i; 00077 00078 png_get_PLTE(png_ptr, info_ptr, &png_pal, &num_palette); 00079 00080 if (num_palette > 256) 00081 num_palette = 256; 00082 00083 for (i = 0; i < num_palette; i++) { 00084 png_palette[i][0] = png_pal[i].red; 00085 png_palette[i][1] = png_pal[i].green; 00086 png_palette[i][2] = png_pal[i].blue; 00087 } 00088 } 00089 00090 line = G_malloc(width * 4); 00091 00092 for (y = 0, p = grid; y < height; y++) { 00093 png_bytep q = line; 00094 00095 png_read_row(png_ptr, q, NULL); 00096 00097 if (true_color) 00098 for (x = 0; x < width; x++, p++) { 00099 int r = *q++; 00100 int g = *q++; 00101 int b = *q++; 00102 int a = *q++; 00103 unsigned int c = get_color(r, g, b, a); 00104 00105 *p = c; 00106 } 00107 else 00108 for (x = 0; x < width; x++, p++, q++) 00109 *p = (png_byte) * q; 00110 } 00111 00112 G_free(line); 00113 00114 png_read_end(png_ptr, NULL); 00115 00116 png_destroy_read_struct(&png_ptr, &info_ptr, NULL); 00117 00118 fclose(input); 00119 }