2008.04.16 13:26 "[Tiff] efficient thumbnailing", by Dr. Michael J. Chudobiak

2008.04.16 16:05 "Re: [Tiff] efficient thumbnailing", by Phillip Crews

I would like to say that I've just been having the exact same problem, except I've been using ImageMagick and GDAL. The images I'm working with are 14400x14400px.

Any solutions out there?

You can skip most scan lines in untiled, non-YCbCr images if they are uncompressed, or compressed with rowsperstrip = 1, and only load enough scan lines to get a good thumbnail. (I use 3 * the thumbnail height, then reduce). This doesn't produce as nice of a thumbnail as a fully resampled image, but it does a good job.

Here's some pseudo-code with no error checking. Variable names should be obvious. All scan lines retain their full width, so your 14400 x 14400 images would load as (for example) 14400 x 300, eliminating 14100 scan line reads and decompressions, requiring 2% of the memory required for a full image load, and much less CPU for resampling to 100x100.

    loadheight = thumbnail_height * 3;
    if (planar_config == PLANARCONFIG_CONTIG) {
        PFNCTGOUT put;
        BYTE *pbuf = malloc(TIFFScanlineSize(tif));
        put = GetContigOutputRoutine();
        for (row=0; row < loadheight; row++) {
            fromrow = (row * height) / loadheight;
            TIFFReadScanline(tif, pbuf, fromrow, 0);
            (*put)(my_image, row, 0, pbuf, width, 1, 1, 0);
    } else {
        PFNSEPOUT put;
        BYTE *r, *g, *b, *a;

        r = pbuf = malloc(4*TIFFScanlineSize(tif));
        g = r + TIFFScanlineSize(tif);
        b = g + TIFFScanlineSize(tif);
        a = b + TIFFScanlineSize(tif);
        put = GetSeparateOutputRoutine();
        for (row=0; row < loadheight; row++) {

            fromrow = (row * height) / loadheight;
            TIFFReadScanline(tif, r, fromrow, 0);
            TIFFReadScanline(tif, g, fromrow, 1);
            TIFFReadScanline(tif, b, fromrow, 2);

            if (sampperpix == 4)
                TIFFReadScanline(tif, a, fromrow, 3);
            (*put)(my_image, row, 0, r, g, b, a, width, 1, 1, 0);

This significantly speeds thumbnailing of very large images as long as they meet the criteria.