| AWARE [SYSTEMS] | Imaging expertise for the Delphi developer | |||||||
![]() |
TIFF and LibTiff Mailing List Archive | |||||||
LibTiff Mailing List
TIFF and LibTiff Mailing List Archive Contact
The TIFF Mailing List Homepage |
Thread2008.04.16 16:05 "Re: efficient thumbnailing", by Phillip CrewsSeth Price wrote:
> 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?
> ~Seth
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.
- For planar-contiguous images, I only use this code if height >
thumbnail_height * 8.
- For planar-separate images, because of the disk seeks between the
planes, I only use this code if height > thumbnail_height * planes * 8.
- There may be some improvement with rowsperstrip > 1, especially with
memory usage.
- For compressed images with rowsperstrip = height, the library will
decompress the whole file into memory anyway
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.
|
|||||||