void read_bmp(void) { char header[HEADER_SIZE]; FILE *input; int x, y; unsigned int *p; if (!png.true_color) G_fatal_error("PNG: cannot use BMP with indexed color"); input = fopen(png.file_name, "rb"); if (!input) G_fatal_error("PNG: couldn't open input file %s", png.file_name); if (fread(header, sizeof(header), 1, input) != 1) G_fatal_error("PNG: invalid input file %s", png.file_name); if (!read_bmp_header(header)) G_fatal_error("PNG: invalid BMP header for %s", png.file_name); for (y = 0, p = png.grid; y < png.height; y++) { for (x = 0; x < png.width; x++, p++) { int b = fgetc(input); int g = fgetc(input); int r = fgetc(input); int a = fgetc(input); unsigned int c = png_get_color(r, g, b, a); *p = c; } } fclose(input); }
void read_pgm(void) { char *mask_name = G_store(png.file_name); FILE *input; int x, y; int i_width, i_height, maxval; unsigned int rgb_mask = png_get_color(255, 255, 255, 0); unsigned int *p; if (!png.true_color) G_fatal_error("PNG: cannot use PPM/PGM with indexed color"); mask_name[strlen(mask_name) - 2] = 'g'; input = fopen(mask_name, "rb"); if (!input) G_fatal_error("PNG: couldn't open input mask file %s", mask_name); if (fscanf(input, "P5 %d %d %d", &i_width, &i_height, &maxval) != 3) G_fatal_error("PNG: invalid input mask file %s", mask_name); fgetc(input); if (i_width != png.width || i_height != png.height) G_fatal_error ("PNG: input mask file has incorrect dimensions: expected: %dx%d got: %dx%d", png.width, png.height, i_width, i_height); G_free(mask_name); for (y = 0, p = png.grid; y < png.height; y++) { for (x = 0; x < png.width; x++, p++) { unsigned int c = *p; int k = fgetc(input); k = k * 255 / maxval; c &= rgb_mask; c |= png_get_color(0, 0, 0, 255 - k); *p = c; } } fclose(input); }
void read_ppm(void) { FILE *input; int x, y; int i_width, i_height, maxval; unsigned int rgb_mask = png_get_color(255, 255, 255, 0); unsigned int *p; if (!png.true_color) G_fatal_error("PNG: cannot use PPM/PGM with indexed color"); input = fopen(png.file_name, "rb"); if (!input) G_fatal_error("PNG: couldn't open input file %s", png.file_name); if (fscanf(input, "P6 %d %d %d", &i_width, &i_height, &maxval) != 3) G_fatal_error("PNG: invalid input file %s", png.file_name); fgetc(input); if (i_width != png.width || i_height != png.height) G_fatal_error ("PNG: input file has incorrect dimensions: expected: %dx%d got: %dx%d", png.width, png.height, i_width, i_height); for (y = 0, p = png.grid; y < png.height; y++) { for (x = 0; x < png.width; x++, p++) { unsigned int c = *p; int r = fgetc(input); int g = fgetc(input); int b = fgetc(input); r = r * 255 / maxval; g = g * 255 / maxval; b = b * 255 / maxval; c &= ~rgb_mask; c |= png_get_color(r, g, b, 0); *p = c; } } fclose(input); }
/*! \brief Draw raster row \param n number of cells \param row raster row (starts at 0) \param red,grn,blu,nul red,green,blue and null value \return next row */ int PNG_raster(int n, int row, const unsigned char *red, const unsigned char *grn, const unsigned char *blu, const unsigned char *nul) { int d_y0 = scale_fwd_y(row + 0); int d_y1 = scale_fwd_y(row + 1); int d_rows = d_y1 - d_y0; int x0 = max(png.clip_left - dst[0][0], 0); int x1 = min(png.clip_rite - dst[0][0], ncols); int y0 = max(png.clip_top - d_y0, 0); int y1 = min(png.clip_bot - d_y0, d_rows); int x, y; if (y1 <= y0) return next_row(row, d_y1); for (x = x0; x < x1; x++) { int xx = dst[0][0] + x; int j = trans[x]; int c; if (masked && nul && nul[j]) continue; c = png_get_color(red[j], grn[j], blu[j], 0); for (y = y0; y < y1; y++) { int yy = d_y0 + y; png.grid[yy * png.width + xx] = c; } } png.modified = 1; return next_row(row, d_y1); }
void read_png(void) { static jmp_buf jbuf; static png_struct *png_ptr; static png_info *info_ptr; FILE *input; int x, y; unsigned int *p; png_bytep line; png_uint_32 i_width, i_height; int depth, color_type; png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, &jbuf, NULL, NULL); if (!png_ptr) G_fatal_error("PNG: couldn't allocate PNG structure"); info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) G_fatal_error("PNG: couldn't allocate PNG structure"); if (setjmp(png_jmpbuf(png_ptr))) G_fatal_error("error reading PNG file"); input = fopen(png.file_name, "rb"); if (!input) G_fatal_error("PNG: couldn't open output file %s", png.file_name); png_init_io(png_ptr, input); png_read_info(png_ptr, info_ptr); png_get_IHDR(png_ptr, info_ptr, &i_width, &i_height, &depth, &color_type, NULL, NULL, NULL); if (depth != 8) G_fatal_error("PNG: input file is not 8-bit"); if (i_width != png.width || i_height != png.height) G_fatal_error ("PNG: input file has incorrect dimensions: expected: %dx%d got: %lux%lu", png.width, png.height, (unsigned long) i_width, (unsigned long) i_height); if (png.true_color) { if (color_type != PNG_COLOR_TYPE_RGB_ALPHA) G_fatal_error("PNG: input file is not RGBA"); } else { if (color_type != PNG_COLOR_TYPE_PALETTE) G_fatal_error("PNG: input file is not indexed color"); } if (!png.true_color && png.has_alpha) { png_bytep trans; int num_trans; png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, NULL); if (num_trans != 1 || trans[0] != 0) G_fatal_error("PNG: input file has invalid palette"); } if (png.true_color) png_set_invert_alpha(png_ptr); else { png_colorp png_pal; int num_palette; int i; png_get_PLTE(png_ptr, info_ptr, &png_pal, &num_palette); if (num_palette > 256) num_palette = 256; for (i = 0; i < num_palette; i++) { png.palette[i][0] = png_pal[i].red; png.palette[i][1] = png_pal[i].green; png.palette[i][2] = png_pal[i].blue; } } line = G_malloc(png.width * 4); for (y = 0, p = png.grid; y < png.height; y++) { png_bytep q = line; png_read_row(png_ptr, q, NULL); if (png.true_color) for (x = 0; x < png.width; x++, p++) { int r = *q++; int g = *q++; int b = *q++; int a = *q++; unsigned int c = png_get_color(r, g, b, a); *p = c; } else for (x = 0; x < png.width; x++, p++, q++) *p = (png_byte) * q; } G_free(line); png_read_end(png_ptr, NULL); png_destroy_read_struct(&png_ptr, &info_ptr, NULL); fclose(input); }
int PNG_Graph_set(void) { unsigned int red, grn, blu; int do_read = 0; int do_map = 0; char *p; G_gisinit("PNG driver"); p = getenv("GRASS_PNGFILE"); if (!p || strlen(p) == 0) p = FILE_NAME; png.file_name = p; p = getenv("GRASS_TRUECOLOR"); png.true_color = !p || strcmp(p, "FALSE") != 0; G_verbose_message(_("png: truecolor status %s"), png.true_color ? _("enabled") : _("disabled")); p = getenv("GRASS_PNG_MAPPED"); do_map = p && strcmp(p, "TRUE") == 0; if (do_map) { char *ext = png.file_name + strlen(png.file_name) - 4; if (G_strcasecmp(ext, ".bmp") != 0) do_map = 0; } p = getenv("GRASS_PNG_READ"); do_read = p && strcmp(p, "TRUE") == 0; if (do_read && access(png.file_name, 0) != 0) do_read = 0; png.width = screen_width; png.height = screen_height; png.clip_top = 0; png.clip_bot = png.height; png.clip_left = 0; png.clip_rite = png.width; p = getenv("GRASS_TRANSPARENT"); png.has_alpha = p && strcmp(p, "TRUE") == 0; png_init_color_table(); p = getenv("GRASS_BACKGROUNDCOLOR"); if (p && *p && (sscanf(p, "%02x%02x%02x", &red, &grn, &blu) == 3 || G_str_to_color(p, (int *)&red, (int *)&grn, (int *)&blu) == 1)) { png.background = png_get_color(red, grn, blu, png.has_alpha ? 255 : 0); } else { /* 0xffffff = white, 0x000000 = black */ if (strcmp(DEFAULT_FG_COLOR, "white") == 0) /* foreground: white, background: black */ png.background = png_get_color(0, 0, 0, png.has_alpha ? 255 : 0); else /* foreground: black, background: white */ png.background = png_get_color(255, 255, 255, png.has_alpha ? 255 : 0); } G_verbose_message(_("png: collecting to file '%s'"), png.file_name); G_verbose_message(_("png: image size %dx%d"), png.width, png.height); if (do_read && do_map) map_file(); if (!png.mapped) png.grid = G_malloc(png.width * png.height * sizeof(unsigned int)); if (!do_read) { PNG_Erase(); png.modified = 1; } if (do_read && !png.mapped) read_image(); if (do_map && !png.mapped) { write_image(); map_file(); } return 0; }