/// <summary>
/// Gets the value(s) of a tag in an open TIFF file.
/// </summary>
/// <param name="tif">An instance of the <see cref="Tiff"/> class.</param>
/// <param name="tag">The tag.</param>
/// <returns>The value(s) of a tag in an open TIFF file/stream as array of
/// <see cref="FieldValue"/> objects or <c>null</c> if there is no such tag set.</returns>
/// <seealso cref="Tiff.GetField"/>
public virtual FieldValue[] GetField(Tiff tif, TiffTag tag)
{
TiffDirectory td = tif.m_dir;
FieldValue[] result = null;
switch (tag)
{
case TiffTag.SUBFILETYPE:
result = new FieldValue[1];
result[0].Set(td.td_subfiletype);
break;
case TiffTag.IMAGEWIDTH:
result = new FieldValue[1];
result[0].Set(td.td_imagewidth);
break;
case TiffTag.IMAGELENGTH:
result = new FieldValue[1];
result[0].Set(td.td_imagelength);
break;
case TiffTag.BITSPERSAMPLE:
result = new FieldValue[1];
result[0].Set(td.td_bitspersample);
break;
case TiffTag.COMPRESSION:
result = new FieldValue[1];
result[0].Set(td.td_compression);
break;
case TiffTag.PHOTOMETRIC:
result = new FieldValue[1];
result[0].Set(td.td_photometric);
break;
case TiffTag.THRESHHOLDING:
result = new FieldValue[1];
result[0].Set(td.td_threshholding);
break;
case TiffTag.FILLORDER:
result = new FieldValue[1];
result[0].Set(td.td_fillorder);
break;
case TiffTag.ORIENTATION:
result = new FieldValue[1];
result[0].Set(td.td_orientation);
break;
case TiffTag.SAMPLESPERPIXEL:
result = new FieldValue[1];
result[0].Set(td.td_samplesperpixel);
break;
case TiffTag.ROWSPERSTRIP:
result = new FieldValue[1];
result[0].Set(td.td_rowsperstrip);
break;
case TiffTag.MINSAMPLEVALUE:
result = new FieldValue[1];
result[0].Set(td.td_minsamplevalue);
break;
case TiffTag.MAXSAMPLEVALUE:
result = new FieldValue[1];
result[0].Set(td.td_maxsamplevalue);
break;
case TiffTag.SMINSAMPLEVALUE:
result = new FieldValue[1];
result[0].Set(td.td_sminsamplevalue);
break;
case TiffTag.SMAXSAMPLEVALUE:
result = new FieldValue[1];
result[0].Set(td.td_smaxsamplevalue);
break;
case TiffTag.XRESOLUTION:
result = new FieldValue[1];
result[0].Set(td.td_xresolution);
break;
case TiffTag.YRESOLUTION:
result = new FieldValue[1];
result[0].Set(td.td_yresolution);
break;
case TiffTag.PLANARCONFIG:
result = new FieldValue[1];
result[0].Set(td.td_planarconfig);
break;
case TiffTag.XPOSITION:
result = new FieldValue[1];
result[0].Set(td.td_xposition);
break;
case TiffTag.YPOSITION:
result = new FieldValue[1];
result[0].Set(td.td_yposition);
break;
case TiffTag.RESOLUTIONUNIT:
result = new FieldValue[1];
result[0].Set(td.td_resolutionunit);
break;
case TiffTag.PAGENUMBER:
result = new FieldValue[2];
result[0].Set(td.td_pagenumber[0]);
result[1].Set(td.td_pagenumber[1]);
break;
case TiffTag.HALFTONEHINTS:
result = new FieldValue[2];
result[0].Set(td.td_halftonehints[0]);
result[1].Set(td.td_halftonehints[1]);
break;
case TiffTag.COLORMAP:
result = new FieldValue[3];
result[0].Set(td.td_colormap[0]);
result[1].Set(td.td_colormap[1]);
result[2].Set(td.td_colormap[2]);
break;
case TiffTag.STRIPOFFSETS:
case TiffTag.TILEOFFSETS:
result = new FieldValue[1];
result[0].Set(td.td_stripoffset);
break;
case TiffTag.STRIPBYTECOUNTS:
case TiffTag.TILEBYTECOUNTS:
result = new FieldValue[1];
result[0].Set(td.td_stripbytecount);
break;
case TiffTag.MATTEING:
result = new FieldValue[1];
result[0].Set((td.td_extrasamples == 1 && td.td_sampleinfo[0] == ExtraSample.ASSOCALPHA));
break;
case TiffTag.EXTRASAMPLES:
result = new FieldValue[2];
result[0].Set(td.td_extrasamples);
result[1].Set(td.td_sampleinfo);
break;
case TiffTag.TILEWIDTH:
result = new FieldValue[1];
result[0].Set(td.td_tilewidth);
break;
case TiffTag.TILELENGTH:
result = new FieldValue[1];
result[0].Set(td.td_tilelength);
break;
case TiffTag.TILEDEPTH:
result = new FieldValue[1];
result[0].Set(td.td_tiledepth);
break;
case TiffTag.DATATYPE:
switch (td.td_sampleformat)
{
case SampleFormat.UINT:
result = new FieldValue[1];
result[0].Set(DATATYPE_UINT);
break;
case SampleFormat.INT:
result = new FieldValue[1];
result[0].Set(DATATYPE_INT);
break;
case SampleFormat.IEEEFP:
result = new FieldValue[1];
result[0].Set(DATATYPE_IEEEFP);
break;
case SampleFormat.VOID:
result = new FieldValue[1];
result[0].Set(DATATYPE_VOID);
break;
}
break;
case TiffTag.SAMPLEFORMAT:
result = new FieldValue[1];
result[0].Set(td.td_sampleformat);
break;
case TiffTag.IMAGEDEPTH:
result = new FieldValue[1];
result[0].Set(td.td_imagedepth);
break;
case TiffTag.SUBIFD:
result = new FieldValue[2];
result[0].Set(td.td_nsubifd);
result[1].Set(td.td_subifd);
break;
case TiffTag.YCBCRPOSITIONING:
result = new FieldValue[1];
result[0].Set(td.td_ycbcrpositioning);
break;
case TiffTag.YCBCRSUBSAMPLING:
result = new FieldValue[2];
result[0].Set(td.td_ycbcrsubsampling[0]);
result[1].Set(td.td_ycbcrsubsampling[1]);
break;
case TiffTag.TRANSFERFUNCTION:
result = new FieldValue[3];
result[0].Set(td.td_transferfunction[0]);
if (td.td_samplesperpixel - td.td_extrasamples > 1)
{
result[1].Set(td.td_transferfunction[1]);
result[2].Set(td.td_transferfunction[2]);
}
break;
case TiffTag.REFERENCEBLACKWHITE:
if (td.td_refblackwhite != null)
{
result = new FieldValue[1];
result[0].Set(td.td_refblackwhite);
}
break;
case TiffTag.INKNAMES:
result = new FieldValue[1];
result[0].Set(td.td_inknames);
break;
default:
// This can happen if multiple images are open with
// different codecs which have private tags. The global tag
// information table may then have tags that are valid for
// one file but not the other. If the client tries to get a
// tag that is not valid for the image's codec then we'll
// arrive here.
TiffFieldInfo fip = tif.FindFieldInfo(tag, TiffType.ANY);
if (fip == null || fip.Bit != FieldBit.Custom)
{
Tiff.ErrorExt(tif, tif.m_clientdata, "_TIFFVGetField",
"{0}: Invalid {1}tag \"{2}\" (not supported by codec)",
tif.m_name, Tiff.isPseudoTag(tag) ? "pseudo-" : string.Empty,
fip != null ? fip.Name : "Unknown");
result = null;
break;
}
// Do we have a custom value?
result = null;
for (int i = 0; i < td.td_customValueCount; i++)
{
TiffTagValue tv = td.td_customValues[i];
if (tv.info.Tag != tag)
{
continue;
}
if (fip.PassCount)
{
result = new FieldValue[2];
if (fip.ReadCount == TiffFieldInfo.Variable2)
{
result[0].Set(tv.count);
}
else
{
// Assume TiffFieldInfo.Variable
result[0].Set(tv.count);
}
result[1].Set(tv.value);
}
else
{
if ((fip.Type == TiffType.ASCII ||
fip.ReadCount == TiffFieldInfo.Variable ||
fip.ReadCount == TiffFieldInfo.Variable2 ||
fip.ReadCount == TiffFieldInfo.Spp ||
tv.count > 1) && fip.Tag != TiffTag.PAGENUMBER &&
fip.Tag != TiffTag.HALFTONEHINTS &&
fip.Tag != TiffTag.YCBCRSUBSAMPLING &&
fip.Tag != TiffTag.DOTRANGE)
{
result = new FieldValue[1];
byte[] value = tv.value;
if (fip.Type == TiffType.ASCII &&
tv.value.Length > 0 &&
tv.value[tv.value.Length - 1] == 0)
{
// cut unwanted zero at the end
value = new byte[Math.Max(tv.value.Length - 1, 0)];
Buffer.BlockCopy(tv.value, 0, value, 0, value.Length);
}
result[0].Set(value);
}
else
{
result = new FieldValue[tv.count];
byte[] val = tv.value;
int valPos = 0;
for (int j = 0; j < tv.count; j++, valPos += Tiff.dataSize(tv.info.Type))
{
switch (fip.Type)
{
case TiffType.BYTE:
case TiffType.UNDEFINED:
case TiffType.SBYTE:
result[j].Set(val[valPos]);
break;
case TiffType.SHORT:
case TiffType.SSHORT:
result[j].Set(BitConverter.ToInt16(val, valPos));
break;
case TiffType.LONG:
case TiffType.IFD:
case TiffType.SLONG:
result[j].Set(BitConverter.ToInt32(val, valPos));
break;
case TiffType.RATIONAL:
case TiffType.SRATIONAL:
case TiffType.FLOAT:
result[j].Set(BitConverter.ToSingle(val, valPos));
break;
case TiffType.DOUBLE:
result[j].Set(BitConverter.ToDouble(val, valPos));
break;
default:
result = null;
break;
}
}
}
}
break;
}
break;
}
return(result);
}