public bool ReadCustomDirectory(long offset, TiffFieldInfo[] info, int count)
{
const string module = "ReadCustomDirectory";
setupFieldInfo(info, count);
uint dummyNextDirOff;
TiffDirEntry[] dir;
short dircount = fetchDirectory((uint)offset, out dir, out dummyNextDirOff);
if (dircount == 0)
{
ErrorExt(this, m_clientdata, module,
"{0}: Failed to read custom directory at offset {1}", m_name, offset);
return false;
}
FreeDirectory();
m_dir = new TiffDirectory();
int fix = 0;
for (short i = 0; i < dircount; i++)
{
if ((m_flags & TiffFlags.SWAB) == TiffFlags.SWAB)
{
short temp = (short)dir[i].tdir_tag;
SwabShort(ref temp);
dir[i].tdir_tag = (TiffTag)(ushort)temp;
temp = (short)dir[i].tdir_type;
SwabShort(ref temp);
dir[i].tdir_type = (TiffType)temp;
SwabLong(ref dir[i].tdir_count);
SwabUInt(ref dir[i].tdir_offset);
}
if (fix >= m_nfields || dir[i].tdir_tag == TiffTag.IGNORE)
continue;
while (fix < m_nfields && m_fieldinfo[fix].Tag < dir[i].tdir_tag)
fix++;
if (fix >= m_nfields || m_fieldinfo[fix].Tag != dir[i].tdir_tag)
{
WarningExt(this, m_clientdata, module,
"{0}: unknown field with tag {1} (0x{2:x}) encountered",
m_name, (ushort)dir[i].tdir_tag, (ushort)dir[i].tdir_tag);
TiffFieldInfo[] arr = new TiffFieldInfo[1];
arr[0] = createAnonFieldInfo(dir[i].tdir_tag, dir[i].tdir_type);
MergeFieldInfo(arr, 1);
fix = 0;
while (fix < m_nfields && m_fieldinfo[fix].Tag < dir[i].tdir_tag)
fix++;
}
// null out old tags that we ignore.
if (m_fieldinfo[fix].Bit == FieldBit.Ignore)
{
dir[i].tdir_tag = TiffTag.IGNORE;
continue;
}
// Check data type.
TiffFieldInfo fip = m_fieldinfo[fix];
while (dir[i].tdir_type != fip.Type && fix < m_nfields)
{
if (fip.Type == TiffType.ANY)
{
// wildcard
break;
}
fip = m_fieldinfo[++fix];
if (fix >= m_nfields || fip.Tag != dir[i].tdir_tag)
{
WarningExt(this, m_clientdata, module,
"{0}: wrong data type {1} for \"{2}\"; tag ignored",
m_name, dir[i].tdir_type, m_fieldinfo[fix - 1].Name);
dir[i].tdir_tag = TiffTag.IGNORE;
continue;
}
}
// Check count if known in advance.
if (fip.ReadCount != TiffFieldInfo.Variable &&
fip.ReadCount != TiffFieldInfo.Variable2)
{
int expected = fip.ReadCount;
if (fip.ReadCount == TiffFieldInfo.Spp)
expected = m_dir.td_samplesperpixel;
if (!checkDirCount(dir[i], expected))
{
dir[i].tdir_tag = TiffTag.IGNORE;
continue;
}
}
// EXIF tags which need to be specifically processed.
switch (dir[i].tdir_tag)
{
case TiffTag.EXIF_SUBJECTDISTANCE:
fetchSubjectDistance(dir[i]);
break;
default:
fetchNormalTag(dir[i]);
break;
}
}
return true;
}