fix tiff directory mixup

we were not always selecting the correct read directory
This commit is contained in:
John Cupitt 2020-06-01 00:39:15 +01:00
parent f0d4b36d7d
commit 0bdd2290a0
2 changed files with 163 additions and 30 deletions

View File

@ -271,7 +271,7 @@ typedef struct _RtiffHeader {
int alpha_band;
uint16 compression;
/* Result of TIFFIsTiled().
/* Is this directory tiled.
*/
gboolean tiled;
@ -667,7 +667,7 @@ rtiff_n_pages( Rtiff *rtiff )
for( n = 1; TIFFReadDirectory( rtiff->tiff ); n++ )
;
(void) TIFFSetDirectory( rtiff->tiff, rtiff->current_page );
rtiff->current_page = n - 1;
#ifdef DEBUG
printf( "rtiff_n_pages: found %d pages\n", n );
@ -1554,17 +1554,6 @@ rtiff_set_header( Rtiff *rtiff, VipsImage *out )
*/
vips_image_pipelinev( out, VIPS_DEMAND_STYLE_THINSTRIP, NULL );
#ifdef DEBUG
printf( "rtiff_set_header: header.samples_per_pixel = %d\n",
rtiff->header.samples_per_pixel );
printf( "rtiff_set_header: header.bits_per_sample = %d\n",
rtiff->header.bits_per_sample );
printf( "rtiff_set_header: header.sample_format = %d\n",
rtiff->header.sample_format );
printf( "rtiff_set_header: header.orientation = %d\n",
rtiff->header.orientation );
#endif /*DEBUG*/
/* We have a range of output paths. Look at the tiff header and try to
* route the input image to the best output path.
*/
@ -2231,19 +2220,6 @@ rtiff_read_stripwise( Rtiff *rtiff, VipsImage *out )
vips_image_pipelinev( t[0], VIPS_DEMAND_STYLE_THINSTRIP, NULL );
#ifdef DEBUG
printf( "rtiff_read_stripwise: header.rows_per_strip = %u\n",
rtiff->header.rows_per_strip );
printf( "rtiff_read_stripwise: header.strip_size = %zd\n",
rtiff->header.strip_size );
printf( "rtiff_read_stripwise: header.number_of_strips = %d\n",
rtiff->header.number_of_strips );
printf( "rtiff_read_stripwise: header.read_height = %u\n",
rtiff->header.read_height );
printf( "rtiff_read_stripwise: header.read_size = %zd\n",
rtiff->header.read_size );
#endif /*DEBUG*/
/* Double check: in memcpy mode, the vips linesize should exactly
* match the tiff line size.
*/
@ -2422,11 +2398,25 @@ rtiff_header_read( Rtiff *rtiff, RtiffHeader *header )
}
/* Tiles and strip images have slightly different fields.
*
* We can't use TIFFIsTiled() since some TIFFs have a mix of tiled and
* stip layouts. Test for TILEWIDTH in this directory.
*/
header->tiled = tfexists( rtiff->tiff, TIFFTAG_TILEWIDTH );
header->tiled = TIFFIsTiled( rtiff->tiff );
#ifdef DEBUG
printf( "rtiff_header_read: header.width = %d\n",
header->width );
printf( "rtiff_header_read: header.height = %d\n",
header->height );
printf( "rtiff_header_read: header.samples_per_pixel = %d\n",
header->samples_per_pixel );
printf( "rtiff_header_read: header.bits_per_sample = %d\n",
header->bits_per_sample );
printf( "rtiff_header_read: header.sample_format = %d\n",
header->sample_format );
printf( "rtiff_header_read: header.orientation = %d\n",
header->orientation );
printf( "rtiff_header_read: header.tiled = %d\n",
header->tiled );
#endif /*DEBUG*/
if( header->tiled ) {
if( !tfget32( rtiff->tiff,
@ -2435,6 +2425,13 @@ rtiff_header_read( Rtiff *rtiff, RtiffHeader *header )
TIFFTAG_TILELENGTH, &header->tile_height ) )
return( -1 );
#ifdef DEBUG
printf( "rtiff_header_read: header.tile_width = %d\n",
header->tile_width );
printf( "rtiff_header_read: header.tile_height = %d\n",
header->tile_height );
#endif /*DEBUG*/
/* Arbitrary sanity-checking limits.
*/
if( header->tile_width <= 0 ||
@ -2449,6 +2446,13 @@ rtiff_header_read( Rtiff *rtiff, RtiffHeader *header )
header->tile_size = TIFFTileSize( rtiff->tiff );
header->tile_row_size = TIFFTileRowSize( rtiff->tiff );
#ifdef DEBUG
printf( "rtiff_header_read: header.tile_size = %zd\n",
header->tile_size );
printf( "rtiff_header_read: header.tile_row_size = %zd\n",
header->tile_row_size );
#endif /*DEBUG*/
/* Fuzzed TIFFs can give crazy values for tile_size. Sanity
* check at 100mb per tile.
*/
@ -2477,6 +2481,17 @@ rtiff_header_read( Rtiff *rtiff, RtiffHeader *header )
header->scanline_size = TIFFScanlineSize( rtiff->tiff );
header->number_of_strips = TIFFNumberOfStrips( rtiff->tiff );
#ifdef DEBUG
printf( "rtiff_header_read: header.rows_per_strip = %d\n",
header->rows_per_strip );
printf( "rtiff_header_read: header.strip_size = %zd\n",
header->strip_size );
printf( "rtiff_header_read: header.scanline_size = %zd\n",
header->scanline_size );
printf( "rtiff_header_read: header.number_of_strips = %d\n",
header->number_of_strips );
#endif /*DEBUG*/
/* libtiff has two strip-wise readers. TIFFReadEncodedStrip()
* decompresses an entire strip to memory. It's fast, but it
* will need a lot of ram if the strip is large.
@ -2515,6 +2530,15 @@ rtiff_header_read( Rtiff *rtiff, RtiffHeader *header )
header->read_size = header->strip_size;
}
#ifdef DEBUG
printf( "rtiff_header_read: header.read_scanlinewise = %d\n",
header->read_scanlinewise );
printf( "rtiff_header_read: header.read_height = %d\n",
header->read_height );
printf( "rtiff_header_read: header.read_size = %zd\n",
header->read_size );
#endif /*DEBUG*/
/* Stop some compiler warnings.
*/
header->tile_width = 0;

View File

@ -250,6 +250,115 @@
#include "tiff.h"
/* TODO:
*
* verify image contents:
*
* $ vips copy LuCa-7color_Scan1.ome.tiff[page=0] x.v
* whole slice, 25k x 35k
* $ vips copy LuCa-7color_Scan1.ome.tiff[page=0,subifd=0] x.v
* top-left corner, 12k x 17k
* $ vips copy LuCa-7color_Scan1.ome.tiff[page=0,subifd=1] x.v
* top-left corner, cropped in from subifd=0, 6k x 9k
* $ vips copy LuCa-7color_Scan1.ome.tiff[page=0,subifd=2] x.v
* "cannot read scanlines from tiled image"
*
* $ vips copy LuCa-7color_Scan1.ome.tiff[page=1] x.v
* whole slice, 25k x 35k
* $ vips copy LuCa-7color_Scan1.ome.tiff[page=1,subifd=0] x.v
* top-left corner, 12k x 17k
* $ vips copy LuCa-7color_Scan1.ome.tiff[page=1,subifd=1] x.v
* top-left corner, cropped in from subifd=0, 6k x 9k
* $ vips copy LuCa-7color_Scan1.ome.tiff[page=1,subifd=2] x.v
* "cannot read scanlines from tiled image"
*
* top-level tiffinfo:
*
* $ tiffinfo LuCa-7color_Scan1.ome.tiff
* TIFF Directory at offset 0x10 (16)
* Image Width: 24960 Image Length: 34560
* Tile Width: 512 Tile Length: 512
* Resolution: 20080.5, 20080.5 pixels/cm
* Bits/Sample: 8
* Sample Format: unsigned integer
* Compression Scheme: LZW
* Photometric Interpretation: min-is-black
* Samples/Pixel: 1
* Planar Configuration: single image plane
* SubIFD Offsets: 1533039599 1920856308 2021666749 2052152209 2060362679
* ImageDescription:...
* Software: OME Bio-Formats 6.0.0-rc1
* TIFF Directory at offset 0x14d40236 (349438518)
* Image Width: 24960 Image Length: 34560
* ...
*
* tiffinfo for page=0, subifd=0
*
* $ tiffinfo LuCa-7color_Scan1.ome.tiff -o 1533039599
* TIFF Directory at offset 0x5b6053ef (1533039599)
* Subfile Type: reduced-resolution image (1 = 0x1)
* Image Width: 12480 Image Length: 17280
* Tile Width: 512 Tile Length: 512
* Resolution: 20080.5, 20080.5 pixels/cm
* Bits/Sample: 8
* Sample Format: unsigned integer
* Compression Scheme: LZW
* Photometric Interpretation: min-is-black
* Samples/Pixel: 1
* Planar Configuration: single image plane
* ImageDescription: ...
* Software: OME Bio-Formats 6.0.0-rc1
*
* tiffinfo for page=0, subifd=2
*
* $ tiffinfo LuCa-7color_Scan1.ome.tiff -o 2021666749
* TIFF Directory at offset 0x78802fbd (2021666749)
* Subfile Type: reduced-resolution image (1 = 0x1)
* Image Width: 3120 Image Length: 4320
* Resolution: 20080.5, 20080.5 pixels/cm
* Bits/Sample: 8
* Sample Format: unsigned integer
* Compression Scheme: LZW
* Photometric Interpretation: min-is-black
* Samples/Pixel: 1
* Rows/Strip: 1
* Planar Configuration: single image plane
* ImageDescription: ...
* Software: OME Bio-Formats 6.0.0-rc1
*
* this subifd is untiled! same for 3 & 4.
*
* try:
*
* vips copy LuCa-7color_Scan1.ome.tiff[n=5] x.tif[pyramid,tile-width=512,tile-height=512,compression=lzw]
* vips copy x.tif[page=1] x.v
*
* horizontal stripes in image (page 0 is fine) ... a problem in rewind? it
* looks like the stripes are half a tile high
*
* try:
*
* $ vips copy LuCa-7color_Scan1.ome.tiff[subifd=4] x.png
* (vips:1284665): VIPS-WARNING **: 13:59:15.555: error in tile 0 x 0
* source input: Can not read scanlines from a tiled image
* tiff2vips: read error
* vips2png: unable to write to target
*
* subifd=3 seems to work, curiously ... are some subifds tiled and some
* striped? how come we don't pick up tile/strip from the subifd?
*
* try:
*
* vips copy test.tif x.tif[page-height=2048,pyramid]
* vips copy x.tif[page=1] x.png
*
* test.tif is k2.jpg split into bands and joined top to bottom ... no stripes
* visible
*
*
* - have a layout enum rather than a bool
* - revise docs