GRASS Programmer's Manual  6.4.2(2012)
read_png.c
Go to the documentation of this file.
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 }
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines