我认为@KSletmoe指出了一个关键点,即在编写任何子IFD之前,应该在IFD0中添加SubIFD标签(330),但仍存在问题。
SubIFD标签的定义是“指向子IFD的偏移量”。因此,如果您没有正确设置偏移量,则tiff解析器无法正确解析整个tiff。
有两种处理这种情况的方法。
首先,预先计算每个IFD/SubIFD的大小,然后在设置时填入SubIFD标签,而不是设置为0x0。
或者,您可以像下面这样正常编写每个IFD,然后返回到IFD0并使用由libtiff计算的最终偏移量添加SubIFD标签。
//Write down every thing you need in a tiff
// ... IFD0
TIFFWriteDirectory(tif);
// ... IFD1
TIFFWriteDirectory(tif);
// ... IFD2
TIFFWriteDirectory(tif);
//set current Dir as IFD0 in the end
TIFFSetDirectory(tif, 0);
//get next dir offset
sub_offset[1] = TIFFGetNextDirOff(tif, 2);
sub_offset[0] = TIFFGetNextDirOff(tif, 1);
//only for clean next dir offset in IFD0
no_use_offset = TIFFGetNextDirOff(tif, 0);
TIFFSetField(tif, TIFFTAG_SUBIFD, 2, sub_offset);
你可能需要在 tif_dir.c 中添加以下函数
uint64 TIFFGetNextDirOff(TIFF* tif, uint16 dirn)
{
uint64 nextdir;
uint16 n;
if (!(tif->tif_flags&TIFF_BIGTIFF))
nextdir = tif->tif_header.classic.tiff_diroff;
else
nextdir = tif->tif_header.big.tiff_diroff;
for (n = dirn; n > 0 && nextdir != 0; n--)
if (!TIFFAdvanceDirectory(tif, &nextdir, NULL))
return (0);
/*!!Watchout!! Here will reset the next dir offset to 0*/
tif->tif_nextdiroff = 0;
return nextdir;
}
感谢 @KSletmoe。希望这可以帮助到某些人,并期待更加优雅的方式来实现。