Ejemplo n.º 1
0
        internal static TiffTagValue[] Realloc(TiffTagValue[] buffer, int elementCount, int newElementCount)
        {
            TiffTagValue[] newBuffer = new TiffTagValue[newElementCount];

            if (buffer != null)
            {
                int copyLength = Math.Min(elementCount, newElementCount);
                Array.Copy(buffer, newBuffer, copyLength);
            }

            return(newBuffer);
        }
        /// <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);
        }