[mapserver-users] 2 Color(1 bit) tiff files

Alfred Kleva alfred.kleva at siol.net
Wed Aug 15 09:43:44 PDT 2001


Hi folks !

I have the same problem like Hana. I have tested ms 3.5 on RH7.9 with this
options :

1. ./configure --with-tiff --with-gdal ...
this options do not support classes

2. ./configure --without-tiff --with-gdal ...
this options (use gdal tiff) support classes, but same images do not display
correctly

3. I have added "new" code in "static int drawTIFF" of mapraster.c (see
"case PHOTOMETRIC_MINISWHITE:").
Options are ./configure --with-tiff --with-gdal ...
In my tests it's works OK.

****** TOP ********
static int drawTIFF(mapObj *map, layerObj *layer, gdImagePtr img, char
*filename)
{
#ifdef USE_TIFF
  int i,j; /* loop counters */

  double x,y;
  TIFF *tif=NULL;
  unsigned char *buf;
  long w, h;
  short type, nbits;
  unsigned short compression;
  unsigned short *red, *green, *blue;
  int cmap[MAXCOLORS];

  int startx, starty; /* this is where we start out reading */
  int st,strip;  /* current strip */
  int xi,yi,startj,endj,boffset,vv;

  double ulx, uly; /* upper left-hand coordinates */
  double skipx,skipy; /* skip factors (x and y) */
  double cx,cy; /* cell sizes (x and y) */
  long rowsPerStrip;

  TIFFSetWarningHandler(NULL); /* can these be directed to the mapserver
error functions... */
  TIFFSetErrorHandler(NULL);

  tif = TIFFOpen(filename, "rb");
  if(!tif) {
    msSetError(MS_IMGERR, "Error loading TIFF image.", "drawTIFF()");
    return(-1);
  }

  if(readGEOTiff(tif, &ulx, &uly, &cx, &cy) != 0) {
    if(readWorldFile(filename, &ulx, &uly, &cx, &cy) != 0) {
      TIFFClose(tif);
      return(-1);
    }
  }

  skipx = map->cellsize/cx;
  skipy = map->cellsize/cy;
  startx = (map->extent.minx - ulx)/cx;
  starty = (uly - map->extent.maxy)/cy;

  TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &w);
  TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h);

  TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &nbits);
  if(nbits != 8 && nbits != 4 && nbits != 1) {
    msSetError(MS_IMGERR, "Only 1, 4, and 8-bit images are supported.",
"drawTIFF()");
    TIFFClose(tif);
    return(-1);
  }

  TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &rowsPerStrip);
  TIFFGetField(tif, TIFFTAG_COMPRESSION, &compression);

  TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &type); /* check image type */
  switch(type) {
  case(PHOTOMETRIC_PALETTE):
    TIFFGetField(tif, TIFFTAG_COLORMAP, &red, &green, &blue);
    if(layer->numclasses > 0) {
      char tmpstr[3];
      int c;

      for(i=0; i<MAXCOLORS; i++) {
 if(i != layer->offsite) {
   sprintf(tmpstr,"%d", i);
   c = getClass(layer, tmpstr);

   if(c == -1) /* doesn't belong to any class, so handle like offsite */
     cmap[i] = -1;
   else {
     if(layer->class[c].color == -1) /* use raster color */
       cmap[i] = add_color(map,img, CVT(red[i]), CVT(green[i]),
CVT(blue[i]));
     else
       if(layer->class[c].color == -255) /* make transparent */
  cmap[i] = -1;
       else
  cmap[i] = layer->class[c].color; /* use class color */
   }
 } else
   cmap[i] = -1;
      }
    } else {
      for(i=0; i<MAXCOLORS; i++) {
 if(i != layer->offsite)
   cmap[i] = add_color(map,img, CVT(red[i]), CVT(green[i]), CVT(blue[i]));
        else
   cmap[i] = -1;
      }
    }
    break;
  case PHOTOMETRIC_MINISBLACK: /* classes are NOT honored for
non-colormapped data */
    if (nbits==1) {
      if(layer->offsite >= 0)
 cmap[layer->offsite] = -1;
      if(layer->offsite != 0)
 cmap[0]=add_color(map,img,0,0,0);
      if(layer->offsite != 1)
 cmap[1]=add_color(map,img,255,255,255);
    } else {
      if (nbits==4) {
 for (i=0; i<16; i++) {
   if(i != layer->offsite)
     cmap[i]=add_color(map,img,i*17,i*17,i*17);
   else
     cmap[i] = -1;
 }
      } else { /* 8-bit */
 for (i=0; i<256; i++) {
   if(i != layer->offsite)
     cmap[i]=add_color(map,img,(i>>4)*17,(i>>4)*17,(i>>4)*17);
   else
     cmap[i] = -1;
 }
      }
    }
    break;
  case PHOTOMETRIC_MINISWHITE: /* classes are NOT honored for
non-colormapped data */
/* ORIGINAL COMENTED
    if (nbits==1) {
      if(layer->offsite >= 0)
 cmap[layer->offsite] = -1;
      if(layer->offsite != 0)
 cmap[0]=add_color(map,img,255,255,255);
      if(layer->offsite != 1)
 cmap[1]=add_color(map,img,0,0,0);
    }
    else {
      msSetError(MS_IMGERR,"Can't do inverted grayscale
images","drawTIFF()");
      TIFFClose(tif);
      return(-1);
    }
*/
    /* COPYED FROM 'case(PHOTOMETRIC_PALETTE)' and 'case
PHOTOMETRIC_MINISWHITE' */
    if (nbits==1) {
      TIFFGetField(tif, TIFFTAG_COLORMAP, &red, &green, &blue);
      if(layer->numclasses > 0) {
        char tmpstr[3];
        int c;

        for(i=0; i<MAXCOLORS; i++) {
   if(i != layer->offsite) {
     sprintf(tmpstr,"%d", i);
     c = getClass(layer, tmpstr);

     if(c == -1) /* doesn't belong to any class, so handle like offsite */
       cmap[i] = -1;
     else {
       if(layer->class[c].color == -1) /* use raster color */
         cmap[i] = add_color(map,img, CVT(red[i]), CVT(green[i]),
CVT(blue[i]));
       else
         if(layer->class[c].color == -255) /* make transparent */
    cmap[i] = -1;
         else
    cmap[i] = layer->class[c].color; /* use class color */
     }
   } else
     cmap[i] = -1;
        }
      } else {
        if(layer->offsite >= 0)
   cmap[layer->offsite] = -1;
        if(layer->offsite != 0)
   cmap[0]=add_color(map,img,255,255,255);
        if(layer->offsite != 1)
   cmap[1]=add_color(map,img,0,0,0);
 /*
        for(i=0; i<MAXCOLORS; i++) {
   if(i != layer->offsite)
     cmap[i] = add_color(map,img, CVT(red[i]), CVT(green[i]), CVT(blue[i]));
          else
     cmap[i] = -1;
        }
 */
      }
    }
    else {
      msSetError(MS_IMGERR,"Can't do inverted grayscale
images","drawTIFF()");
      TIFFClose(tif);
      return(-1);
    }
    break;
  default:
    msSetError(MS_IMGERR, "Only colormapped and grayscale images are
supported.", "drawTIFF()");
    TIFFClose(tif);
    return(-1);
  }

  buf = (unsigned char *)_TIFFmalloc(TIFFStripSize(tif)); /* allocate strip
buffer */

  /*
  ** some set-up;  the startx calculation is problematical analytically so
we
  ** find it iteratively
  */
  x=startx;
  for (j=0; j<img->sx && MS_NINT(x)<0; j++) x+=skipx;
  startx=x; startj=j;
  for (j=startj; j<img->sx && MS_NINT(x)<w; j++) x+=skipx;
  endj=j;
  y=starty;
  strip=-1;
  for(i=0; i<img->sy; i++) { /* for each row */
    yi=MS_NINT(y);
    if((yi >= 0) && (yi < h)) {
      st=TIFFComputeStrip(tif,yi,0);
      if (st!=strip) {
        TIFFReadEncodedStrip(tif, st, buf, TIFFStripSize(tif));
        strip=st;
      }
      x = startx;

      switch (nbits) {
      case 8:
        boffset=(yi % rowsPerStrip) * w;
        for(j=startj; j<endj; j++) {
   xi=MS_NINT(x);
   vv=buf[xi+boffset];

   if (cmap[vv] != -1)
     img->pixels[i][j] = cmap[vv];

   x+=skipx;
        }
        break;
      case 4:
        boffset=(yi % rowsPerStrip) * ((w+1) >> 1);
        for(j=startj; j<endj; j++) {
          xi=MS_NINT(x);
          vv=(buf[(xi >> 1) + boffset] >> (4*((yi+1) & 1))) & 15;

   if (cmap[vv] != -1)
     img->pixels[i][j] = cmap[vv];

   x+=skipx;
 }
        break;
      case 1:
        boffset=(yi % rowsPerStrip) * ((w+7) >> 3);
        for(j=startj; j<endj; j++) {
          xi=MS_NINT(x);
          vv=(buf[(xi >> 3) + boffset] >> (7-(xi & 7))) & 1;

   if (cmap[vv] != -1)
     img->pixels[i][j] = cmap[vv];

   x+=skipx;
 }
        break;
      }
    }
    y+=skipy;
  }
  _TIFFfree(buf);

  TIFFClose(tif);
  return(0);
#else
   msSetError(MS_IMGERR, "TIFF support is not available.", "drawTIFF()");
   return(-1);
#endif
}
****** BOTTOM ***


Hana wrote :
------------- Begin Forwarded Message -------------

From: hana.jirsova at oku-pce.cz
Date: Fri, 9 Feb 2001 9:46:12 +0100
To: mapserver-info at lists.gis.umn.edu
Subject: 2 Color(1 bit) tiff files

I tried to display 2 color's files (1 bit) in different
colors, but unsuccessfully. I have rasters for various
themes (one raster for rivers, second for seats, third for
forest,....) and all are drawn only with black and
white(transparent) color. Maybe I'm doing some mistakes in
code. Please, be so kind and look at it :

#**********************
This is the raster of forest
LAYER
  NAME 'cl2421'
  DATA cl2421.tif
  TYPE RASTER
  CLASS
    EXPRESSION "1"
    COLOR 0 255 0
  END  # CLASS
  OFFSITE 0
END  # LAYER
# this upper example works only in black and white



#**********************
# I need to do it with the group of rasters ... rivers,
# it works only in black and white , I don't know how to
# change it
LAYER
  NAME 'cv2421'
  TYPE RASTER
  STATUS off
  TILEINDEX 'kl50'
  TILEITEM RIVERS
  MAXSCALE 200000
  OFFSITE 0
END  # LAYER

Thank you very much. Hana Jirsova


------------- End Forwarded Message -------------


I have tested ms 3.5 on RH7.9 with this options :

1. ./configure --with-tiff --with-gdal ...
this options do not support classes

2. ./configure --without-tiff --with-gdal ...
this options (use gdal tiff) support classes, but same images do not display
correctly

3. I have added "new" code in "static int drawTIFF" of mapraster.c (see
"case PHOTOMETRIC_MINISWHITE:").
Options are ./configure --with-tiff --with-gdal ...
In my tests it's works OK.

LP Alfred Kleva

****** TOP ********
static int drawTIFF(mapObj *map, layerObj *layer, gdImagePtr img, char
*filename)
{
#ifdef USE_TIFF
  int i,j; /* loop counters */

  double x,y;
  TIFF *tif=NULL;
  unsigned char *buf;
  long w, h;
  short type, nbits;
  unsigned short compression;
  unsigned short *red, *green, *blue;
  int cmap[MAXCOLORS];

  int startx, starty; /* this is where we start out reading */
  int st,strip;  /* current strip */
  int xi,yi,startj,endj,boffset,vv;

  double ulx, uly; /* upper left-hand coordinates */
  double skipx,skipy; /* skip factors (x and y) */
  double cx,cy; /* cell sizes (x and y) */
  long rowsPerStrip;

  TIFFSetWarningHandler(NULL); /* can these be directed to the mapserver
error functions... */
  TIFFSetErrorHandler(NULL);

  tif = TIFFOpen(filename, "rb");
  if(!tif) {
    msSetError(MS_IMGERR, "Error loading TIFF image.", "drawTIFF()");
    return(-1);
  }

  if(readGEOTiff(tif, &ulx, &uly, &cx, &cy) != 0) {
    if(readWorldFile(filename, &ulx, &uly, &cx, &cy) != 0) {
      TIFFClose(tif);
      return(-1);
    }
  }

  skipx = map->cellsize/cx;
  skipy = map->cellsize/cy;
  startx = (map->extent.minx - ulx)/cx;
  starty = (uly - map->extent.maxy)/cy;

  TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &w);
  TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h);

  TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &nbits);
  if(nbits != 8 && nbits != 4 && nbits != 1) {
    msSetError(MS_IMGERR, "Only 1, 4, and 8-bit images are supported.",
"drawTIFF()");
    TIFFClose(tif);
    return(-1);
  }

  TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &rowsPerStrip);
  TIFFGetField(tif, TIFFTAG_COMPRESSION, &compression);

  TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &type); /* check image type */
  switch(type) {
  case(PHOTOMETRIC_PALETTE):
    TIFFGetField(tif, TIFFTAG_COLORMAP, &red, &green, &blue);
    if(layer->numclasses > 0) {
      char tmpstr[3];
      int c;

      for(i=0; i<MAXCOLORS; i++) {
 if(i != layer->offsite) {
   sprintf(tmpstr,"%d", i);
   c = getClass(layer, tmpstr);

   if(c == -1) /* doesn't belong to any class, so handle like offsite */
     cmap[i] = -1;
   else {
     if(layer->class[c].color == -1) /* use raster color */
       cmap[i] = add_color(map,img, CVT(red[i]), CVT(green[i]),
CVT(blue[i]));
     else
       if(layer->class[c].color == -255) /* make transparent */
  cmap[i] = -1;
       else
  cmap[i] = layer->class[c].color; /* use class color */
   }
 } else
   cmap[i] = -1;
      }
    } else {
      for(i=0; i<MAXCOLORS; i++) {
 if(i != layer->offsite)
   cmap[i] = add_color(map,img, CVT(red[i]), CVT(green[i]), CVT(blue[i]));
        else
   cmap[i] = -1;
      }
    }
    break;
  case PHOTOMETRIC_MINISBLACK: /* classes are NOT honored for
non-colormapped data */
    if (nbits==1) {
      if(layer->offsite >= 0)
 cmap[layer->offsite] = -1;
      if(layer->offsite != 0)
 cmap[0]=add_color(map,img,0,0,0);
      if(layer->offsite != 1)
 cmap[1]=add_color(map,img,255,255,255);
    } else {
      if (nbits==4) {
 for (i=0; i<16; i++) {
   if(i != layer->offsite)
     cmap[i]=add_color(map,img,i*17,i*17,i*17);
   else
     cmap[i] = -1;
 }
      } else { /* 8-bit */
 for (i=0; i<256; i++) {
   if(i != layer->offsite)
     cmap[i]=add_color(map,img,(i>>4)*17,(i>>4)*17,(i>>4)*17);
   else
     cmap[i] = -1;
 }
      }
    }
    break;
  case PHOTOMETRIC_MINISWHITE: /* classes are NOT honored for
non-colormapped data */
/* ORIGINAL COMENTED
    if (nbits==1) {
      if(layer->offsite >= 0)
 cmap[layer->offsite] = -1;
      if(layer->offsite != 0)
 cmap[0]=add_color(map,img,255,255,255);
      if(layer->offsite != 1)
 cmap[1]=add_color(map,img,0,0,0);
    }
    else {
      msSetError(MS_IMGERR,"Can't do inverted grayscale
images","drawTIFF()");
      TIFFClose(tif);
      return(-1);
    }
*/
    /* COPYED FROM 'case(PHOTOMETRIC_PALETTE)' and 'case
PHOTOMETRIC_MINISWHITE' */
    if (nbits==1) {
      TIFFGetField(tif, TIFFTAG_COLORMAP, &red, &green, &blue);
      if(layer->numclasses > 0) {
        char tmpstr[3];
        int c;

        for(i=0; i<MAXCOLORS; i++) {
   if(i != layer->offsite) {
     sprintf(tmpstr,"%d", i);
     c = getClass(layer, tmpstr);

     if(c == -1) /* doesn't belong to any class, so handle like offsite */
       cmap[i] = -1;
     else {
       if(layer->class[c].color == -1) /* use raster color */
         cmap[i] = add_color(map,img, CVT(red[i]), CVT(green[i]),
CVT(blue[i]));
       else
         if(layer->class[c].color == -255) /* make transparent */
    cmap[i] = -1;
         else
    cmap[i] = layer->class[c].color; /* use class color */
     }
   } else
     cmap[i] = -1;
        }
      } else {
        if(layer->offsite >= 0)
   cmap[layer->offsite] = -1;
        if(layer->offsite != 0)
   cmap[0]=add_color(map,img,255,255,255);
        if(layer->offsite != 1)
   cmap[1]=add_color(map,img,0,0,0);
 /*
        for(i=0; i<MAXCOLORS; i++) {
   if(i != layer->offsite)
     cmap[i] = add_color(map,img, CVT(red[i]), CVT(green[i]), CVT(blue[i]));
          else
     cmap[i] = -1;
        }
 */
      }
    }
    else {
      msSetError(MS_IMGERR,"Can't do inverted grayscale
images","drawTIFF()");
      TIFFClose(tif);
      return(-1);
    }
    break;
  default:
    msSetError(MS_IMGERR, "Only colormapped and grayscale images are
supported.", "drawTIFF()");
    TIFFClose(tif);
    return(-1);
  }

  buf = (unsigned char *)_TIFFmalloc(TIFFStripSize(tif)); /* allocate strip
buffer */

  /*
  ** some set-up;  the startx calculation is problematical analytically so
we
  ** find it iteratively
  */
  x=startx;
  for (j=0; j<img->sx && MS_NINT(x)<0; j++) x+=skipx;
  startx=x; startj=j;
  for (j=startj; j<img->sx && MS_NINT(x)<w; j++) x+=skipx;
  endj=j;
  y=starty;
  strip=-1;
  for(i=0; i<img->sy; i++) { /* for each row */
    yi=MS_NINT(y);
    if((yi >= 0) && (yi < h)) {
      st=TIFFComputeStrip(tif,yi,0);
      if (st!=strip) {
        TIFFReadEncodedStrip(tif, st, buf, TIFFStripSize(tif));
        strip=st;
      }
      x = startx;

      switch (nbits) {
      case 8:
        boffset=(yi % rowsPerStrip) * w;
        for(j=startj; j<endj; j++) {
   xi=MS_NINT(x);
   vv=buf[xi+boffset];

   if (cmap[vv] != -1)
     img->pixels[i][j] = cmap[vv];

   x+=skipx;
        }
        break;
      case 4:
        boffset=(yi % rowsPerStrip) * ((w+1) >> 1);
        for(j=startj; j<endj; j++) {
          xi=MS_NINT(x);
          vv=(buf[(xi >> 1) + boffset] >> (4*((yi+1) & 1))) & 15;

   if (cmap[vv] != -1)
     img->pixels[i][j] = cmap[vv];

   x+=skipx;
 }
        break;
      case 1:
        boffset=(yi % rowsPerStrip) * ((w+7) >> 3);
        for(j=startj; j<endj; j++) {
          xi=MS_NINT(x);
          vv=(buf[(xi >> 3) + boffset] >> (7-(xi & 7))) & 1;

   if (cmap[vv] != -1)
     img->pixels[i][j] = cmap[vv];

   x+=skipx;
 }
        break;
      }
    }
    y+=skipy;
  }
  _TIFFfree(buf);

  TIFFClose(tif);
  return(0);
#else
   msSetError(MS_IMGERR, "TIFF support is not available.", "drawTIFF()");
   return(-1);
#endif
}
****** BOTTOM ***






More information about the MapServer-users mailing list