1998.12.10 22:19 "TIFFReadRGBA{Tile,Strip}()", by Frank Warmerdam

Folks,

As promised, I have written up my work so far for reading, TIFF images into an RGBA buffer by tile, or by strip. The rationale is that these functions allow handling of very large images without taking up an immense amount of memory.

The files can be found at http://gdal.velocet.ca/rgba_tiff

    TIFFRGBAImage.3t       - slightly modified
    TIFFReadRGBAImage.3t   - slightly modified
    TIFFReadRGBAStrip.3t   - new
    TIFFReadRGBATile.3t    - new
    tif_getimage.c         - two new functions, existing gt* functions
                             modified to support an offset
    tif_getimage.c_diff    - diff from old version.
    tiff2rgba.c            - new program for converting anything to 
                             RGBA using new functions.  By default it
                             does the whole image at once, with -b it does
                             it using the new functions (by block).
    tiffio.h               - added two prototypes, and offset fields.
    tiffio.h_diff          - diff from old version

The following (from tiff2rgba.c) shows use of the tile based function. Note that the returned buffers are in bottom to top organization (as are those from the rest of the RGBA api).

    /*
     * Loop over the tiles.
     */
    for( row = 0; ok && row < height; row += tile_height )
    {
        for( col = 0; ok && col < width; col += tile_width )
        {
            int         i_row;

            /* Read the tile into an RGBA array */
            if (!TIFFReadRGBATile(in, col, row, raster)) {
                ok = 0;
                break;
            }

            /*
             * For some reason the TIFFReadRGBATile() function chooses the
             * lower left corner as the origin.  Vertically mirror scanlines.
             */
            for( i_row = 0; i_row < tile_height / 2; i_row++ )
            {
                uint32  *top_line, *bottom_line;

                top_line = raster + tile_width * i_row;
                bottom_line = raster + tile_width * (tile_height-i_row-1);

                _TIFFmemcpy(wrk_line, top_line, 4*tile_width);
                _TIFFmemcpy(top_line, bottom_line, 4*tile_width);
                _TIFFmemcpy(bottom_line, wrk_line, 4*tile_width);
            }

            /*
             * Write out the result in a tile.
             */

            if( TIFFWriteEncodedTile( out,
                                      TIFFComputeTile( out, col, row, 0, 0),
                                      raster,
                                      4 * tile_width * tile_height ) == -1 )
            {
                ok = 0;
                break;
            }
        }
    }

I would also like to thank John Alderidge who responded to my original email, and gave me sample code that lead me to a cleaner set of changes to the underlying functions. At the core the ``get'' functions in tif_getimage.c were modified to support new row_offset, and col_offset values in the TIFFRGBAImage structure.

Sam, if you are interested in distributing the tiff2rgba program as part of the standard distribution, let me know and I will write a man page for it. I wrote it mostly for testing block oriented vs. non block oriented RGBA conversion.

I appologise for the sloppy nature of the diffs. I am not really ``patch'' literate. I also didn't add see alsos from all the other man pages that it might be appropriate for. This is also my first time to modify a man page, so please forgive me if I screwed them up a bit. Additions to the Makefile for the new man pages are also lacking.

Let me know if there is something else I should do.

Now to return to work I can bill for!

Best regards,

-----------------------------------+---------------------------------------
Who can give them back their lives | Frank Warmerdam, Programmer for Hire
and all those wasted years? - Rush | http://members.home.com/warmerda
                                   | warmerda@home.com