2014.01.18 18:24 "[Tiff] Adding alpha to palette files", by John Hawley

2014.01.18 18:24 "[Tiff] Adding alpha to palette files", by John Hawley

Ok - I'm out of my comfort zone here and looking for a bit of guidance:

I'm in the process of writing a 3D dynamic mapping app which uses geotiff files as a data source. The dynamic nature of the mapping process means I am frequently re-writing numerous Geotiff as more data becomes available - so far so good - I've managed to automatically write these files using an 8-bit palette colour scheme and these are successfully read by gdal. My problem is that I really want the areas which have no data to be transparent i.e. I need to set an alpha channel. Now I've managed to understand from the documentation that I probably need to set EXTRASAMPLES_ASSOCALPHA and set my samples/pixel to 2?. However, I'm not sure how to actually add the alpha data. A snippet of sample code to go about this would be very helpful

My current code ( which writes to 2 output files; 1 a float heightfield and 2 the colour map to overlay the heightfield) is as follows:

   image_width = nx;
   image_height = ny;
   spp = 1; // Samples per pixel
   bppd = 32; // Bits per sample dem
   bppc = 8; // bits per sample colour
   tiepoints[0]=0.0;
   tiepoints[1]=image_height;

   tiepoints[3]=minlong;                     // SW corner
   tiepoints[4]=minlat;

   TIFFSetField(out, TIFFTAG_IMAGEWIDTH, nx / spp);
   TIFFSetField(out2, TIFFTAG_IMAGEWIDTH, nx / spp);

   TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, bppd);
   TIFFSetField(out2, TIFFTAG_BITSPERSAMPLE, bppc);

   TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, spp);
   TIFFSetField(out2, TIFFTAG_SAMPLESPERPIXEL, spp);

   TIFFSetField(out, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
   TIFFSetField(out2, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);

   TIFFSetField(out, TIFFTAG_SAMPLEFORMAT,SAMPLEFORMAT_IEEEFP);

   TIFFSetField(out, TIFFTAG_PHOTOMETRIC,PHOTOMETRIC_MINISBLACK);
   TIFFSetField(out2, TIFFTAG_PHOTOMETRIC,PHOTOMETRIC_PALETTE);

   TIFFSetField(out, TIFFTAG_GEOTIEPOINTS, 6,tiepoints);
   TIFFSetField(out2, TIFFTAG_GEOTIEPOINTS, 6,tiepoints);

   TIFFSetField(out, TIFFTAG_GEOPIXELSCALE, 3,pixscale);
   TIFFSetField(out2, TIFFTAG_GEOPIXELSCALE, 3,pixscale);

   // Allocate and fill colour tables

   red_tbl = (uint16*)    _TIFFmalloc(1<<bppc * sizeof(uint16));
   green_tbl = (uint16*) _TIFFmalloc(1<<bppc * sizeof(uint16));

   blue_tbl = (uint16*) _TIFFmalloc(1<<bppc * sizeof(uint16));
   if (!red_tbl || !green_tbl || !blue_tbl)

    {
         cout << "Can't allocate space for colour component tables." <<
endl;
         return 1;
    }
   // Build Rainbow colour table red through to purple/blue

   for(i = 0; i < 51; i++)
    {

         red_tbl[i] =  255;  green_tbl[i] = 5 * i; blue_tbl[i] = 0;

         red_tbl[i+51] =  255-i*5;  green_tbl[i+51] = 255; 

blue_tbl[i+51] = 0;

         red_tbl[i+102] =  0;  green_tbl[i+102] = 255; blue_tbl[i+102] = 

i*5;

         red_tbl[i+153] =  0;  green_tbl[i+153] = 255-5 * i; 

blue_tbl[i+153] = 255;

         red_tbl[i+204] =  i*5;  green_tbl[i+204] = 0; blue_tbl[i+204] = 

255;
    }

   red_tbl[255] =  255;  green_tbl[255] = 255; blue_tbl[255] = 255;

   TIFFSetField(out2, TIFFTAG_COLORMAP, red_tbl, green_tbl, blue_tbl);

   TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(out, 0));
   TIFFSetField(out2, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(out, 0));

   TIFFSetField(out, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH);
   TIFFSetField(out2, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH);

   TIFFSetField(out, TIFFTAG_XRESOLUTION, 10.0);
   TIFFSetField(out2, TIFFTAG_XRESOLUTION, 10.0);

   TIFFSetField(out, TIFFTAG_YRESOLUTION, 10.0);
   TIFFSetField(out2, TIFFTAG_YRESOLUTION, 10.0);

   uint32 index;
   j=0;
   while (j<image_height)
    {
     index=(image_height-1) -j; // reverse j indices to draw
correct orientation GDAL doesn't honour
     for( i = 0; i < image_width; i++ ) // libtiif orientation tag!
     {
      if (Result.z(i,index)>0.0)
     { // assume < 0
unevaluated
           colour = (int) (Result.z(i,index)*scalefactor)+0.5; // scale
float to 255 (only for this case)
           out2array[i] = min(colour,254); // clamp
colour to maxdepth
       outarray[i] = (Result.z(i,index)*-1); // convert
to depth
          }
      else
      {
            out2array[i] = 255; // white on colour map - need to
be transparent!
        outarray[i] = 0.0; // unevaluated
     }
      }
        TIFFWriteScanline(out, &outarray[0], j, 0);
        TIFFWriteScanline(out2, &out2array[0], j, 0);
        j++;
     }

where unevaluated results need to be transparent rather than white on the colour map.

  Any help gratefully received!!

JonnieH