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 write_png(void) 00010 { 00011 static jmp_buf jbuf; 00012 static png_struct *png_ptr; 00013 static png_info *info_ptr; 00014 FILE *output; 00015 int x, y; 00016 unsigned int *p; 00017 png_bytep line; 00018 const char *str; 00019 int compress; 00020 00021 png_ptr = 00022 png_create_write_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 writing PNG file"); 00032 00033 output = fopen(file_name, "wb"); 00034 if (!output) 00035 G_fatal_error("PNG: couldn't open output file %s", file_name); 00036 00037 png_init_io(png_ptr, output); 00038 00039 png_set_IHDR(png_ptr, info_ptr, 00040 width, height, 8, 00041 true_color ? PNG_COLOR_TYPE_RGB_ALPHA : 00042 PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE, 00043 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); 00044 00045 if (true_color) 00046 png_set_invert_alpha(png_ptr); 00047 else { 00048 png_color png_pal[256]; 00049 int i; 00050 00051 for (i = 0; i < 256; i++) { 00052 png_pal[i].red = png_palette[i][0]; 00053 png_pal[i].green = png_palette[i][1]; 00054 png_pal[i].blue = png_palette[i][2]; 00055 } 00056 00057 png_set_PLTE(png_ptr, info_ptr, png_pal, 256); 00058 00059 if (has_alpha) { 00060 png_byte trans = (png_byte) 0; 00061 00062 png_set_tRNS(png_ptr, info_ptr, &trans, 1, NULL); 00063 } 00064 } 00065 00066 str = getenv("GRASS_PNG_COMPRESSION"); 00067 if (str && sscanf(str, "%d", &compress) == 1) 00068 png_set_compression_level(png_ptr, compress); 00069 00070 png_write_info(png_ptr, info_ptr); 00071 00072 line = G_malloc(width * 4); 00073 00074 for (y = 0, p = grid; y < height; y++) { 00075 png_bytep q = line; 00076 00077 if (true_color) 00078 for (x = 0; x < width; x++, p++) { 00079 unsigned int c = *p; 00080 int r, g, b, a; 00081 00082 get_pixel(c, &r, &g, &b, &a); 00083 *q++ = (png_byte) r; 00084 *q++ = (png_byte) g; 00085 *q++ = (png_byte) b; 00086 *q++ = (png_byte) a; 00087 } 00088 else 00089 for (x = 0; x < width; x++, p++, q++) 00090 *q = (png_byte) * p; 00091 00092 png_write_row(png_ptr, line); 00093 } 00094 00095 G_free(line); 00096 00097 png_write_end(png_ptr, info_ptr); 00098 00099 png_destroy_write_struct(&png_ptr, &info_ptr); 00100 00101 fclose(output); 00102 }