BitMiracle.LibTiff.Classic.Tiff.ReadDirectory C# (CSharp) Method

ReadDirectory() public method

Reads the contents of the next TIFF directory in an open TIFF file/stream and makes it the current directory.

Directories are read sequentially.

Applications only need to call ReadDirectory to read multiple subfiles in a single TIFF file/stream - the first directory in a file/stream is automatically read when Open(string, string) or ClientOpen(string, string, object, BitMiracle.LibTiff.Classic.TiffStream) is called.

The images that have a single uncompressed strip or tile of data are automatically treated as if they were made up of multiple strips or tiles of approximately 8 kilobytes each. This operation is done only in-memory; it does not alter the contents of the file/stream. However, the construction of the "chopped strips" is visible to the application through the number of strips returned by NumberOfStrips or the number of tiles returned by NumberOfTiles.

public ReadDirectory ( ) : bool
return bool
        public bool ReadDirectory()
        {
            const string module = "ReadDirectory";

            m_diroff = m_nextdiroff;
            if (m_diroff == 0)
            {
                // no more directories
                return false;
            }

            // Check whether we have the last offset or bad offset (IFD looping).
            if (!checkDirOffset(m_nextdiroff))
                return false;

            // Cleanup any previous compression state.
            m_currentCodec.Cleanup();
            m_curdir++;
            TiffDirEntry[] dir;
            short dircount = fetchDirectory(m_nextdiroff, out dir, out m_nextdiroff);
            if (dircount == 0)
            {
                ErrorExt(this, m_clientdata, module, "{0}: Failed to read directory at offset {1}", m_name, m_nextdiroff);
                return false;
            }

            // reset before new dir
            m_flags &= ~TiffFlags.BEENWRITING;

            // Setup default value and then make a pass over the fields to check type and tag
            // information, and to extract info required to size data structures. A second pass is
            // made afterwards to read in everthing not taken in the first pass.

            // free any old stuff and reinit
            FreeDirectory();
            setupDefaultDirectory();

            // Electronic Arts writes gray-scale TIFF files without a PlanarConfiguration
            // directory entry. Thus we setup a default value here, even though the TIFF spec says
            // there is no default value.
            SetField(TiffTag.PLANARCONFIG, PlanarConfig.CONTIG);

            // Sigh, we must make a separate pass through the directory for the following reason:
            //
            // We must process the Compression tag in the first pass in order to merge in
            // codec-private tag definitions (otherwise we may get complaints about unknown tags).
            // However, the Compression tag may be dependent on the SamplesPerPixel tag value
            // because older TIFF specs permited Compression to be written as a
            // SamplesPerPixel-count tag entry. Thus if we don't first figure out the correct
            // SamplesPerPixel tag value then we may end up ignoring the Compression tag value
            // because it has an incorrect count value (if the true value of SamplesPerPixel is not 1).
            //
            // It sure would have been nice if Aldus had really thought this stuff through carefully.

            for (int i = 0; i < dircount; i++)
            {
                TiffDirEntry dp = dir[i];
                if ((m_flags & TiffFlags.SWAB) == TiffFlags.SWAB)
                {
                    short temp = (short)dp.tdir_tag;
                    SwabShort(ref temp);
                    dp.tdir_tag = (TiffTag)(ushort)temp;

                    temp = (short)dp.tdir_type;
                    SwabShort(ref temp);
                    dp.tdir_type = (TiffType)temp;

                    SwabLong(ref dp.tdir_count);
                    SwabUInt(ref dp.tdir_offset);
                }

                if (dp.tdir_tag == TiffTag.SAMPLESPERPIXEL)
                {
                    if (!fetchNormalTag(dir[i]))
                        return false;

                    dp.tdir_tag = TiffTag.IGNORE;
                }
            }

            // First real pass over the directory.
            int fix = 0;
            bool diroutoforderwarning = false;
            bool haveunknowntags = false;
            #if FIX_JPEG_IS_OJPEG
            bool fixJpegIsOJpeg = false;
            #endif
            for (int i = 0; i < dircount; i++)
            {
                if (dir[i].tdir_tag == TiffTag.IGNORE)
                    continue;

                if (fix >= m_nfields)
                    fix = 0;

                // Silicon Beach (at least) writes unordered directory tags (violating the spec).
                // Handle it here, but be obnoxious (maybe they'll fix it?).
                if (dir[i].tdir_tag < m_fieldinfo[fix].Tag)
                {
                    if (!diroutoforderwarning)
                    {
                        WarningExt(this, m_clientdata, module,
                            "{0}: invalid TIFF directory; tags are not sorted in ascending order", m_name);
                        diroutoforderwarning = true;
                    }

                    fix = 0; // O(n^2)
                }

                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)
                {
                    // Unknown tag ... we'll deal with it below
                    haveunknowntags = true;
                    continue;
                }

                // 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];
                bool tagIgnored = false;
                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;
                        tagIgnored = true;
                        break;
                    }
                }

                if (tagIgnored)
                    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;
                    }
                }

                switch (dir[i].tdir_tag)
                {
                    case TiffTag.COMPRESSION:
                        // The 5.0 spec says the Compression tag has one value,
                        // while earlier specs say it has one value per sample.
                        // Because of this, we accept the tag if one value is supplied.
                        if (dir[i].tdir_count == 1)
                        {
                            int v = extractData(dir[i]);
            #if FIX_JPEG_IS_OJPEG
                            fixJpegIsOJpeg = checkJpegIsOJpeg(ref v, dir, dircount);
            #endif
                            if (!SetField(dir[i].tdir_tag, v))
                                return false;

                            break;
                            // XXX: workaround for broken TIFFs
                        }
                        else if (dir[i].tdir_type == TiffType.LONG)
                        {
            #if FIX_JPEG_IS_OJPEG
                            int v;
                            bool isFetched = fetchPerSampleLongs(dir[i], out v);
                            if (!isFetched)
                                return false;
                            fixJpegIsOJpeg = checkJpegIsOJpeg(ref v, dir, dircount);
                            if (!SetField(dir[i].tdir_tag, v))
                                return false;
            #else
                            int v;
                            if (!fetchPerSampleLongs(dir[i], out v) || !SetField(dir[i].tdir_tag, v))
                                return false;
            #endif
                        }
                        else
                        {
            #if FIX_JPEG_IS_OJPEG
                            short iv;
                            bool isFetched = fetchPerSampleShorts(dir[i], out iv);
                            if (!isFetched)
                                return false;
                            int v = iv;
                            fixJpegIsOJpeg = checkJpegIsOJpeg(ref v, dir, dircount);
                            if (!SetField(dir[i].tdir_tag, (short)v))
                                return false;
            #else
                            short iv;
                            if (!fetchPerSampleShorts(dir[i], out iv) || !SetField(dir[i].tdir_tag, iv))
                                return false;
            #endif
                        }
                        dir[i].tdir_tag = TiffTag.IGNORE;
                        break;
                    case TiffTag.STRIPOFFSETS:
                    case TiffTag.STRIPBYTECOUNTS:
                    case TiffTag.TILEOFFSETS:
                    case TiffTag.TILEBYTECOUNTS:
                        setFieldBit(fip.Bit);
                        break;
                    case TiffTag.IMAGEWIDTH:
                    case TiffTag.IMAGELENGTH:
                    case TiffTag.IMAGEDEPTH:
                    case TiffTag.TILELENGTH:
                    case TiffTag.TILEWIDTH:
                    case TiffTag.TILEDEPTH:
                    case TiffTag.PLANARCONFIG:
                    case TiffTag.ROWSPERSTRIP:
                    case TiffTag.EXTRASAMPLES:
                        if (!fetchNormalTag(dir[i]))
                            return false;
                        dir[i].tdir_tag = TiffTag.IGNORE;
                        break;
                }
            }

            // If we saw any unknown tags, make an extra pass over the directory to deal with
            // them. This must be done separately because the tags could have become known when we
            // registered a codec after finding the Compression tag. In a correctly-sorted
            // directory there's no problem because Compression will come before any codec-private
            // tags, but if the sorting is wrong that might not hold.
            if (haveunknowntags)
            {
                fix = 0;
                for (int i = 0; i < dircount; i++)
                {
                    if (dir[i].tdir_tag == TiffTag.IGNORE)
                        continue;

                    if (fix >= m_nfields || dir[i].tdir_tag < m_fieldinfo[fix].Tag)
                    {
                        // O(n^2)
                        fix = 0;
                    }

                    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)
                    {
                        Tiff.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++;
                    }

                    // 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)
                        {
                            Tiff.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;
                            break;
                        }
                    }
                }
            }

            // XXX: OJPEG hack.
            // If a) compression is OJPEG, b) planarconfig tag says it's separate, c) strip
            // offsets/bytecounts tag are both present and d) both contain exactly one value, then
            // we consistently find that the buggy implementation of the buggy compression scheme
            // matches contig planarconfig best. So we 'fix-up' the tag here
            if ((m_dir.td_compression == Compression.OJPEG) && (m_dir.td_planarconfig == PlanarConfig.SEPARATE))
            {
                int dpIndex = readDirectoryFind(dir, dircount, TiffTag.STRIPOFFSETS);
                if (dpIndex != -1 && dir[dpIndex].tdir_count == 1)
                {
                    dpIndex = readDirectoryFind(dir, dircount, TiffTag.STRIPBYTECOUNTS);
                    if (dpIndex != -1 && dir[dpIndex].tdir_count == 1)
                    {
                        m_dir.td_planarconfig = PlanarConfig.CONTIG;
                        WarningExt(this, m_clientdata, "ReadDirectory",
                            "Planarconfig tag value assumed incorrect, assuming data is contig instead of chunky");
                    }
                }
            }

            // Allocate directory structure and setup defaults.
            if (!fieldSet(FieldBit.ImageDimensions))
            {
                missingRequired("ImageLength");
                return false;
            }

            // Setup appropriate structures (by strip or by tile)
            if (!fieldSet(FieldBit.TileDimensions))
            {
                m_dir.td_nstrips = NumberOfStrips();
                m_dir.td_tilewidth = m_dir.td_imagewidth;
                m_dir.td_tilelength = m_dir.td_rowsperstrip;
                m_dir.td_tiledepth = m_dir.td_imagedepth;
                m_flags &= ~TiffFlags.ISTILED;
            }
            else
            {
                m_dir.td_nstrips = NumberOfTiles();
                m_flags |= TiffFlags.ISTILED;
            }

            if (m_dir.td_nstrips == 0)
            {
                ErrorExt(this, m_clientdata, module,
                    "{0}: cannot handle zero number of {1}", m_name, IsTiled() ? "tiles" : "strips");
                return false;
            }

            m_dir.td_stripsperimage = m_dir.td_nstrips;
            if (m_dir.td_planarconfig == PlanarConfig.SEPARATE)
                m_dir.td_stripsperimage /= m_dir.td_samplesperpixel;

            if (!fieldSet(FieldBit.StripOffsets))
            {
                if ((m_dir.td_compression == Compression.OJPEG) && !IsTiled() && (m_dir.td_nstrips == 1))
                {
                    // XXX: OJPEG hack.
                    // If a) compression is OJPEG, b) it's not a tiled TIFF, and c) the number of
                    // strips is 1, then we tolerate the absence of stripoffsets tag, because,
                    // presumably, all required data is in the JpegInterchangeFormat stream.
                    setFieldBit(FieldBit.StripOffsets);
                }
                else
                {
                    missingRequired(IsTiled() ? "TileOffsets" : "StripOffsets");
                    return false;
                }
            }

            // Second pass: extract other information.
            for (int i = 0; i < dircount; i++)
            {
                if (dir[i].tdir_tag == TiffTag.IGNORE)
                    continue;

                switch (dir[i].tdir_tag)
                {
                    case TiffTag.MINSAMPLEVALUE:
                    case TiffTag.MAXSAMPLEVALUE:
                    case TiffTag.BITSPERSAMPLE:
                    case TiffTag.DATATYPE:
                    case TiffTag.SAMPLEFORMAT:
                        // The 5.0 spec says the Compression tag has one value, while earlier
                        // specs say it has one value per sample. Because of this, we accept the
                        // tag if one value is supplied.
                        //
                        // The MinSampleValue, MaxSampleValue, BitsPerSample DataType and
                        // SampleFormat tags are supposed to be written as one value/sample, but
                        // some vendors incorrectly write one value only - so we accept that as
                        // well (yech). Other vendors write correct value for NumberOfSamples, but
                        // incorrect one for BitsPerSample and friends, and we will read this too.
                        if (dir[i].tdir_count == 1)
                        {
                            int v = extractData(dir[i]);
                            if (!SetField(dir[i].tdir_tag, v))
                                return false;
                            // XXX: workaround for broken TIFFs
                        }
                        else if (dir[i].tdir_tag == TiffTag.BITSPERSAMPLE && dir[i].tdir_type == TiffType.LONG)
                        {
                            int v;
                            if (!fetchPerSampleLongs(dir[i], out v) || !SetField(dir[i].tdir_tag, v))
                                return false;
                        }
                        else
                        {
                            short iv;
                            if (!fetchPerSampleShorts(dir[i], out iv) || !SetField(dir[i].tdir_tag, iv))
                                return false;
                        }
                        break;
                    case TiffTag.SMINSAMPLEVALUE:
                    case TiffTag.SMAXSAMPLEVALUE:
                        double dv;
                        if (!fetchPerSampleAnys(dir[i], out dv) || !SetField(dir[i].tdir_tag, dv))
                            return false;
                        break;
                    case TiffTag.STRIPOFFSETS:
                    case TiffTag.TILEOFFSETS:
                        if (!fetchStripThing(dir[i], m_dir.td_nstrips, ref m_dir.td_stripoffset))
                            return false;
                        break;
                    case TiffTag.STRIPBYTECOUNTS:
                    case TiffTag.TILEBYTECOUNTS:
                        if (!fetchStripThing(dir[i], m_dir.td_nstrips, ref m_dir.td_stripbytecount))
                            return false;
                        break;
                    case TiffTag.COLORMAP:
                    case TiffTag.TRANSFERFUNCTION:
                        {
                            // TransferFunction can have either 1x or 3x data values;
                            // Colormap can have only 3x items.
                            int v = 1 << m_dir.td_bitspersample;
                            if (dir[i].tdir_tag == TiffTag.COLORMAP || dir[i].tdir_count != v)
                            {
                                if (!checkDirCount(dir[i], 3 * v))
                                    break;
                            }

                            byte[] cp = new byte[dir[i].tdir_count * sizeof(short)];
                            if (fetchData(dir[i], cp) != 0)
                            {
                                int c = 1 << m_dir.td_bitspersample;
                                if (dir[i].tdir_count == c)
                                {
                                    // This deals with there being only one array to apply to all samples.
                                    short[] u = ByteArrayToShorts(cp, 0, dir[i].tdir_count * sizeof(short));
                                    SetField(dir[i].tdir_tag, u, u, u);
                                }
                                else
                                {
                                    v *= sizeof(short);
                                    short[] u0 = ByteArrayToShorts(cp, 0, v);
                                    short[] u1 = ByteArrayToShorts(cp, v, v);
                                    short[] u2 = ByteArrayToShorts(cp, 2 * v, v);
                                    SetField(dir[i].tdir_tag, u0, u1, u2);
                                }
                            }
                            break;
                        }
                    case TiffTag.PAGENUMBER:
                    case TiffTag.HALFTONEHINTS:
                    case TiffTag.YCBCRSUBSAMPLING:
                    case TiffTag.DOTRANGE:
                        fetchShortPair(dir[i]);
                        break;
                    case TiffTag.REFERENCEBLACKWHITE:
                        fetchRefBlackWhite(dir[i]);
                        break;
                    // BEGIN REV 4.0 COMPATIBILITY
                    case TiffTag.OSUBFILETYPE:
                        FileType ft = 0;
                        switch ((OFileType)extractData(dir[i]))
                        {
                            case OFileType.REDUCEDIMAGE:
                                ft = FileType.REDUCEDIMAGE;
                                break;
                            case OFileType.PAGE:
                                ft = FileType.PAGE;
                                break;
                        }

                        if (ft != 0)
                            SetField(TiffTag.SUBFILETYPE, ft);

                        break;
                    // END REV 4.0 COMPATIBILITY
            #if FIX_JPEG_IS_OJPEG
                    case TiffTag.COMPRESSION:
                        // do not set compression field again (see first pass) to avoid undoing the fix
                        if (!fixJpegIsOJpeg)
                        {
                            fetchNormalTag(dir[i]);
                        }
                        break;
            #endif
                    default:
                        fetchNormalTag(dir[i]);
                        break;
                }
            }

            // OJPEG hack:
            // - If a) compression is OJPEG, and b) photometric tag is missing, then we
            // consistently find that photometric should be YCbCr
            // - If a) compression is OJPEG, and b) photometric tag says it's RGB, then we
            // consistently find that the buggy implementation of the buggy compression scheme
            // matches photometric YCbCr instead.
            // - If a) compression is OJPEG, and b) bitspersample tag is missing, then we
            // consistently find bitspersample should be 8.
            // - If a) compression is OJPEG, b) samplesperpixel tag is missing, and c) photometric
            // is RGB or YCbCr, then we consistently find samplesperpixel should be 3
            // - If a) compression is OJPEG, b) samplesperpixel tag is missing, and c) photometric
            // is MINISWHITE or MINISBLACK, then we consistently find samplesperpixel should be 3
            if (m_dir.td_compression == Compression.OJPEG)
            {
                if (!fieldSet(FieldBit.Photometric))
                {
                    WarningExt(this, m_clientdata,
                        "ReadDirectory", "Photometric tag is missing, assuming data is YCbCr");

                    if (!SetField(TiffTag.PHOTOMETRIC, Photometric.YCBCR))
                        return false;
                }
                else if (m_dir.td_photometric == Photometric.RGB)
                {
                    m_dir.td_photometric = Photometric.YCBCR;
                    WarningExt(this, m_clientdata, "ReadDirectory",
                        "Photometric tag value assumed incorrect, assuming data is YCbCr instead of RGB");
                }

                if (!fieldSet(FieldBit.BitsPerSample))
                {
                    WarningExt(this, m_clientdata, "ReadDirectory",
                        "BitsPerSample tag is missing, assuming 8 bits per sample");

                    if (!SetField(TiffTag.BITSPERSAMPLE, 8))
                        return false;
                }

                if (!fieldSet(FieldBit.SamplesPerPixel))
                {
                    if ((m_dir.td_photometric == Photometric.RGB) ||
                        (m_dir.td_photometric == Photometric.YCBCR))
                    {
                        WarningExt(this, m_clientdata, "ReadDirectory",
                            "SamplesPerPixel tag is missing, assuming correct SamplesPerPixel value is 3");

                        if (!SetField(TiffTag.SAMPLESPERPIXEL, 3))
                            return false;
                    }
                    else if ((m_dir.td_photometric == Photometric.MINISWHITE) ||
                        (m_dir.td_photometric == Photometric.MINISBLACK))
                    {
                        WarningExt(this, m_clientdata, "ReadDirectory",
                            "SamplesPerPixel tag is missing, assuming correct SamplesPerPixel value is 1");
                        if (!SetField(TiffTag.SAMPLESPERPIXEL, 1))
                            return false;
                    }
                }
            }

            // Verify Palette image has a Colormap.
            if (m_dir.td_photometric == Photometric.PALETTE && !fieldSet(FieldBit.ColorMap))
            {
                missingRequired("Colormap");
                return false;
            }

            // OJPEG hack:
            // We do no further messing with strip/tile offsets/bytecounts in OJPEG TIFFs
            if (m_dir.td_compression != Compression.OJPEG)
            {
                // Attempt to deal with a missing StripByteCounts tag.
                if (!fieldSet(FieldBit.StripByteCounts))
                {
                    // Some manufacturers violate the spec by not giving the size of the strips.
                    // In this case, assume there is one uncompressed strip of data.
                    if ((m_dir.td_planarconfig == PlanarConfig.CONTIG && m_dir.td_nstrips > 1) ||
                        (m_dir.td_planarconfig == PlanarConfig.SEPARATE && m_dir.td_nstrips != m_dir.td_samplesperpixel))
                    {
                        missingRequired("StripByteCounts");
                        return false;
                    }

                    WarningExt(this, m_clientdata, module,
                        "{0}: TIFF directory is missing required \"{1}\" field, calculating from imagelength",
                        m_name, FieldWithTag(TiffTag.STRIPBYTECOUNTS).Name);

                    if (!estimateStripByteCounts(dir, dircount))
                        return false;
                }
                else if (m_dir.td_nstrips == 1 && m_dir.td_stripoffset[0] != 0 && byteCountLooksBad(m_dir))
                {
                    // XXX: Plexus (and others) sometimes give a value of zero for a tag when
                    // they don't know what the correct value is! Try and handle the simple case
                    // of estimating the size of a one strip image.
                    WarningExt(this, m_clientdata, module,
                        "{0}: Bogus \"{1}\" field, ignoring and calculating from imagelength",
                        m_name, FieldWithTag(TiffTag.STRIPBYTECOUNTS).Name);

                    if (!estimateStripByteCounts(dir, dircount))
                        return false;
                }
                else if (m_dir.td_planarconfig == PlanarConfig.CONTIG && m_dir.td_nstrips > 2 &&
                    m_dir.td_compression == Compression.NONE &&
                    m_dir.td_stripbytecount[0] != m_dir.td_stripbytecount[1])
                {
                    // XXX: Some vendors fill StripByteCount array with absolutely wrong values
                    // (it can be equal to StripOffset array, for example). Catch this case here.
                    WarningExt(this, m_clientdata, module,
                        "{0}: Wrong \"{1}\" field, ignoring and calculating from imagelength",
                        m_name, FieldWithTag(TiffTag.STRIPBYTECOUNTS).Name);

                    if (!estimateStripByteCounts(dir, dircount))
                        return false;
                }
            }

            dir = null;

            if (!fieldSet(FieldBit.MaxSampleValue))
                m_dir.td_maxsamplevalue = (ushort)((1 << m_dir.td_bitspersample) - 1);

            // Setup default compression scheme.

            // XXX: We can optimize checking for the strip bounds using the sorted bytecounts
            // array. See also comments for appendToStrip() function.
            if (m_dir.td_nstrips > 1)
            {
                m_dir.td_stripbytecountsorted = true;
                for (int strip = 1; strip < m_dir.td_nstrips; strip++)
                {
                    if (m_dir.td_stripoffset[strip - 1] > m_dir.td_stripoffset[strip])
                    {
                        m_dir.td_stripbytecountsorted = false;
                        break;
                    }
                }
            }

            if (!fieldSet(FieldBit.Compression))
                SetField(TiffTag.COMPRESSION, Compression.NONE);

            // Some manufacturers make life difficult by writing large amounts of uncompressed
            // data as a single strip. This is contrary to the recommendations of the spec. The
            // following makes an attempt at breaking such images into strips closer to the
            // recommended 8k bytes. A side effect, however, is that the RowsPerStrip tag value
            // may be changed.
            if (m_dir.td_nstrips == 1 && m_dir.td_compression == Compression.NONE &&
                (m_flags & TiffFlags.STRIPCHOP) == TiffFlags.STRIPCHOP &&
                (m_flags & TiffFlags.ISTILED) != TiffFlags.ISTILED)
            {
                chopUpSingleUncompressedStrip();
            }

            // Reinitialize i/o since we are starting on a new directory.
            m_row = -1;
            m_curstrip = -1;
            m_col = -1;
            m_curtile = -1;
            m_tilesize = -1;

            m_scanlinesize = ScanlineSize();
            if (m_scanlinesize == 0)
            {
                ErrorExt(this, m_clientdata, module, "{0}: cannot handle zero scanline size", m_name);
                return false;
            }

            if (IsTiled())
            {
                m_tilesize = TileSize();
                if (m_tilesize == 0)
                {
                    ErrorExt(this, m_clientdata, module, "{0}: cannot handle zero tile size", m_name);
                    return false;
                }
            }
            else
            {
                if (StripSize() == 0)
                {
                    ErrorExt(this, m_clientdata, module, "{0}: cannot handle zero strip size", m_name);
                    return false;
                }
            }

            return true;
        }

Usage Example

コード例 #1
0
ファイル: Form1.cs プロジェクト: Atheros364/OLLCreator
        public int getNumberofTiffPages(Tiff image)
        {
            int pageCount = 0;
            do
            {
                ++pageCount;
            } while (image.ReadDirectory());

            return pageCount;
        }
All Usage Examples Of BitMiracle.LibTiff.Classic.Tiff::ReadDirectory
Tiff