Input of Raster Bitmaps
Bill Brown
brown at gis.uiuc.edu
Fri Oct 20 08:00:00 EDT 1995
>
>I am loocking for a tool to import TIFF or PBM Bitmap Images into
>GRASS.
>
>Using r.in.ppm I need a ppm-file which is 24 times larger
>than the bitmap file. This is a problem using images of about
>12000 by 12000 pixels. To use r.in.sunrast i have to convert to
>sun-rasterfile. I got the same problem (r.in.sunrast dont accept
>images with 1 bit depth) and in addition, my converting tool
>(pnm-tools) got out of memory, because it tried to allocate
>memory for the whole image.
>
Wilhelm,
Here's my version of r.in.ppm.c which should read pbm files (either
ascii or raw) as well as ppm. Just replace the file in
src.contrib/SCS/raster/r.ppm/cmd with this one and recompile by
running gmake4.1 in that directory.
- Bill Brown
------------------------------ cut here -------------------------
#include <stdio.h>
#include "gis.h"
#include <ctype.h>
#define MAXCOLOR 32768
struct mycolor {
int red;
int grn;
int blu;
} ppm_color[MAXCOLOR];
main(argc,argv) char *argv[];
{
FILE *infp;
CELL *cell,*cellptr;
char *name, *mapset;
int outfp;
int row,col;
int nrows, ncols;
int x, i, c,c1, do_pbm;
int ch;
int have_cell;
int n;
char fmt[20];
struct Colors colors, *pcolr;
int red,grn,blu,num_colors;
struct Option *inopt, *outopt;
struct Flag *vflag;
int Verbose = 0;
int ppm_height, ppm_width, ppm_maxval, ppm_magic, ppm_head;
struct Cell_head cellhd;
long ppm_pos;
pcolr = &colors;
G_gisinit (argv[0]);
inopt = G_define_option();
outopt = G_define_option();
inopt->key = "input";
inopt->type = TYPE_STRING;
inopt->required = YES;
inopt->description = "Name of existing PPM file.";
outopt->key = "output";
outopt->type = TYPE_STRING;
outopt->required = YES;
outopt->gisprompt = "new,cell,raster";
outopt->description = "Name of new raster file.";
vflag = G_define_flag();
vflag->key = 'v';
vflag->description = "Verbose mode on.";
if(G_parser(argc, argv))
exit(-1);
Verbose = vflag->answer;
if((infp = fopen(inopt->answer, "r")) == NULL)
G_fatal_error("Can't open PPM file for read.");
name = outopt->answer;
G_init_colors(pcolr);
ppm_height = ppm_width = ppm_maxval = ppm_magic = ppm_head = 0;
while((c = fgetc(infp)) != EOF && !ppm_head){
switch (c){
case 'P':
ppm_magic = fgetc(infp);
do_pbm = (ppm_magic == '1' || ppm_magic == '4');
if (Verbose)
printf("Magic = P%c\n", (char)ppm_magic);
break;
case '#':
if (Verbose) printf("Comment = #");
while((c1 = fgetc(infp)) != EOF && c1 != '\n')
if (Verbose)
putchar(c1);
putchar('\n');
break;
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case '0':
if (!ppm_width || !ppm_height || (!do_pbm && !ppm_maxva
l))
ungetc(c, infp);
if (!ppm_width){
fscanf(infp, "%d", &ppm_width);
if (Verbose)
printf("Width = %d\n", ppm_width);
break;
}
if (!ppm_height){
fscanf(infp, "%d", &ppm_height);
if (Verbose)
printf("Height = %d\n", ppm_height);
if(do_pbm) ppm_head = 1;
break;
}
if (!do_pbm && !ppm_maxval){
fscanf(infp, "%d", &ppm_maxval);
if (Verbose)
printf("Maxval = %d\n", ppm_maxval);
ppm_head = 1;
break;
}
break;
default:
break;
}
}
ppm_pos = ftell(infp);
num_colors = get_ppm_colors(infp, ppm_width * ppm_height, ppm_magic);
if (Verbose)printf("Total colors = %d\n", num_colors);
fseek(infp, ppm_pos, 0); /* get back where we were */
nrows = cellhd.rows = ppm_height;
ncols = cellhd.cols = ppm_width;
cellhd.proj = G_projection();
cellhd.zone = G_zone();
cellhd.ew_res = cellhd.ns_res = 1.0;
cellhd.north = (double) ppm_height;
cellhd.east = (double) ppm_width;
cellhd.west = cellhd.south = 0.0;
G_set_window(&cellhd);
/*
G_set_cell_format(0);
*/
if((outfp = G_open_cell_new (name)) < 0)
G_fatal_error("Can't open new raster file.");
cell = G_allocate_cell_buf();
if (Verbose) fprintf(stderr, "Percent Complete: ");
for (row = 0; row < nrows; row++)
{
cellptr = cell;
if(Verbose) G_percent(row, nrows, 5);
for (col = 0; col < ncols; col++){
switch (ppm_magic){
case '1': /* ascii bitmap */
fscanf(infp, "%d", &x);
if(x == 1)
*cellptr++ = 1;
else if (x == 0)
*cellptr++ = 0;
/* otherwise got junk */
break;
case '4': /* raw bitmap */
for(x=0; col < ncols; col++, x++){
x &= 7;
if(!x){
ch = fgetc(infp);
}
*cellptr++ = (ch&0x80) ? 1 : 0;
ch = ch << 1;
}
break;
case '6':
red = fgetc(infp);
grn = fgetc(infp);
blu = fgetc(infp);
*cellptr++ = lookup_color(red,grn,blu,num_color
s);
break;
case '3':
fscanf(infp, "%d %d %d", &red, &grn, &blu);
*cellptr++ = lookup_color(red,grn,blu,num_color
s);
break;
}
}
if (G_put_map_row(outfp, cell) < 0 )
G_fatal_error("Can't write new raster row!!");
}
if(Verbose) G_percent(row,nrows, 5);
G_close_cell(outfp);
/*G_put_cellhd(outopt->answer, &cellhd);*/
if (Verbose)
printf("Writing color table for %d values", num_colors);
for(x=0;x<num_colors;x++){
G_set_color((CELL)x, ppm_color[x].red, ppm_color[x].grn,
ppm_color[x].blu, pcolr);
}
if(G_write_colors(outopt->answer, G_mapset(), pcolr) < 0)
G_fatal_error("Can't write color table!!");
exit(0);
}
get_ppm_colors(infp, pixels, ppm_magic)
FILE *infp;
int pixels,ppm_magic;
{
int count,x,maxcolor,match;
int red, grn, blu;
long pos;
char buf[100];
match = maxcolor = 0;
if (ppm_magic == '1' || ppm_magic == '4'){ /* pixmap */
ppm_color[0].red = 255;
ppm_color[0].grn = 255;
ppm_color[0].blu = 255;
ppm_color[1].red = 0;
ppm_color[1].grn = 0;
ppm_color[1].blu = 0;
return(2);
}
for (count=0; count < pixels; count++){
match = 0;
switch (ppm_magic){
case '6':
red = fgetc(infp);
grn = fgetc(infp);
blu = fgetc(infp);
break;
case '3':
fscanf(infp, "%d %d %d", &red, &grn, &blu);
break;
default:
G_fatal_error("Unknown ppm magic number!!");
break;
}
for (x=0;x<maxcolor;x++){
if (ppm_color[x].red == red &&
ppm_color[x].grn == grn &&
ppm_color[x].blu == blu){
match = 1;
break;
}
}
if (match == 0){
ppm_color[maxcolor].red = red;
ppm_color[maxcolor].grn = grn;
ppm_color[maxcolor].blu = blu;
maxcolor++;
if (maxcolor == MAXCOLOR)
G_fatal_error("Exceeded maximum colors!!");
}
}
return(maxcolor);
}
CELL
lookup_color(r,g,b,num)
int r,g,b,num;
{
int x;
for (x=0;x<num;x++){
if (ppm_color[x].red == r &&
ppm_color[x].grn == g &&
ppm_color[x].blu == b){
break;
}
}
return((CELL)x);
}
More information about the grass-user
mailing list