gpt4 book ai didi

c++ - 计算内存中的 TIFF 图像大小 [C/C++]

转载 作者:搜寻专家 更新时间:2023-10-31 00:32:49 24 4
gpt4 key购买 nike

如果我有一个指向 TIFF 数据的指针,但没有指示大小,是否有任何方法可以准确计算它?

我经历了几种不同的想法,所有这些想法大部分时间都有效,但并非总是如此,因为格式化 TIFF 的方法太多了,我认为必须有一种更简单的方法来做到这一点.现在,我得到的最接近的是:

ULONG readImageHeader(char* image)
{
TIF_HDR *xTIFHdr;
TIF_IFD *xTIFIFD;
TIF_IFD_ENTRY *pxTIFIFDEntry;
UCHAR *pHdrPtr;
USHORT i;
ULONG length = 0;
ULONG imgLength = 0;
ULONG count = 0;

// check to see if it is a TIFF header
xTIFHdr = (TIF_HDR *)image;

// Little Endian
if (xTIFHdr->usTIFID == TIF_HEAD_LITTLE)
{
pHdrPtr = (UCHAR*)image;
pHdrPtr += xTIFHdr->ulFirstIFDOffset;

// read TIF IFD
xTIFIFD = (TIF_IFD *)pHdrPtr;

// Look at all the IFD entries and set internal image hdr
pHdrPtr += TIF_IFD_LEN;
pxTIFIFDEntry = (TIF_IFD_ENTRY *)pHdrPtr;

// iterate through each IFD entry
for (i=0; i<xTIFIFD->usNumIFDEntries; i++)
{
if(length <= (ULONG)pxTIFIFDEntry->ulTIFValueOffset)
{
length = (ULONG)pxTIFIFDEntry->ulTIFValueOffset;

// the TIF length is in units of the TIF type
switch(pxTIFIFDEntry->usTIFType)
{
case TIF_BYTE:
length += (ULONG)pxTIFIFDEntry->ulTIFLength * TIF_BYTE_SIZE;
break;
case TIF_ASCII:
length += (ULONG)pxTIFIFDEntry->ulTIFLength * TIF_ASCII_SIZE;
break;
case TIF_SHORT:
length += (ULONG)pxTIFIFDEntry->ulTIFLength * TIF_SHORT_SIZE;
break;
case TIF_LONG:
length += (ULONG)pxTIFIFDEntry->ulTIFLength * TIF_LONG_SIZE;
break;
case TIF_RATIONAL:
length += (ULONG)pxTIFIFDEntry->ulTIFLength * TIF_RATIONAL_SIZE;
break;
default:
length += (ULONG)pxTIFIFDEntry->ulTIFLength;
break;
}
}
switch (pxTIFIFDEntry->usTIFTag)
{
case TIF_STRIP_BYTE_COUNTS:
case TIF_STRIP_OFFSETS:
{
ULONG valueOffset = (ULONG)pxTIFIFDEntry->ulTIFValueOffset;
count = (ULONG)pxTIFIFDEntry->ulTIFLength;

// if the count > 1, then the valueOffset actually represents an offset
if(count > 1)
{
ULONG countsize = (count - 1) * sizeof(ULONG);
imgLength += *(ULONG*) ((UCHAR*)image + valueOffset + countsize);
}
else
{
// if count is 1, then the valueOffset is really just the value of that item
imgLength += valueOffset;
}
break;
}
default:
break;
}
pxTIFIFDEntry++;
}

// the length is the largest offset, plus the length of that item
// the imgLength is the offset of the image, plus the size of the image, which is stored as two separate tags
// return the largest of them
return(length > imgLength ? length : imgLength);
}
// Big Endian
else if(xTIFHdr->usTIFID == TIF_HEAD_BIG)
{
// I don't care about this
printf("Big Endian TIFF image\n");
}

printf("Invalid TIFF image\n");
return(0);
}

本质上,我在这里所做的是遍历 TIFF header ,并计算两个运行总和:(最大偏移量 + 数据长度)和( strip 偏移量 + strip 字节数)。然后我只使用两个值中较大的一个。

这主要是有效的,除了有时 ulTIFValueOffset 根本不是偏移量,而是实际值。在(某些)这些情况下,我得到的文件太大了。到目前为止,我所有失败的例子都是在抓取 Width 或 Length 标签时,尽管我不能排除其他标签可能有同样问题的可能性。

有没有

  1. 一种根据 header 计算文件大小的方法?或
  2. 知道 header 是值还是偏移量的方法?

谢谢!

最佳答案

务实为导向的答案是,除非绝对必要,否则不要自己直接处理图像格式。使用图像库。对于 TIFF,有多种免费(自由 和/或免费)图形文件库,包括 libTIFF , ImageMagick/GraphicMagick , DevIL , FreeImage和别的。

TIFF image format非常强大和灵活,但代价是可以说是最复杂的图像格式,如 TIFF 6.0 规范中所述。此外,当前的实现还包含用于 JPEG 支持的 TIFF 技术说明 #2,以及 BigTIFF 草案。

I've gone through several different ideas, all of which work most of the time, but not always, since there's just so many different ways to format a TIFF

这就是我推荐使用图片库的原因。


If I have a pointer to TIFF data, but no indication of the size, is there any way to accurately calculate it?

如果您所说的“TIFF 数据”是指 TIFF 图像本身,不,据我所知不是。如果不解析 TIFF 图像,则无法确定其文件大小(在磁盘上或内存中)。

A way to calculate the file size given the headers?

只使用 8 字节的图像文件头,然后没有。

通过解析图像文件目录 (IFD),您可以计算出该值。

A way to know if the headers are a value or an offset?

您应该能够确定 IFD(图像文件目录,TIFF 规范中的术语)条目的 ValueOffset 是值还是偏移量。它是值当且仅当它适合 4 个字节(ValueOffset 字段的大小)。 (引用:TIFF 6.0 specification: TIFF Structure - 值/偏移量)

关于c++ - 计算内存中的 TIFF 图像大小 [C/C++],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30462141/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com