コード例 #1
0
ファイル: TiffHelper.cs プロジェクト: billgao87/ImageTest
 private static DoubleByteTiffInfo CreateDoubleByteTiffInfo(byte[] buffer, List <ushort[]> ushortBuffer, int width,
                                                            int height, string filePath,
                                                            int rowsPerStrip,
                                                            int xResolution, int yResolution, ResUnit resUnit = ResUnit.INCH,
                                                            PlanarConfig planarConfig = PlanarConfig.CONTIG,
                                                            int bytePerSample         = 16, Photometric photometric = Photometric.MINISBLACK,
                                                            Compression compression   = Compression.NONE,
                                                            int samplePerPixel        = 1, Orientation orientation = Orientation.TOPLEFT,
                                                            FillOrder fillOrder       = FillOrder.MSB2LSB)
 {
     return(new DoubleByteTiffInfo()
     {
         FilePath = filePath,
         Buffer = buffer,
         UshortBuffer = ushortBuffer,
         Width = width,
         Height = height,
         RowsPerStrip = rowsPerStrip,
         XResolution = xResolution,
         YResolution = yResolution,
         ResolutionUnit = resUnit,
         PlanarConfig = planarConfig,
         BitsPerSample = bytePerSample,
         Photometric = photometric,
         Compression = compression,
         SamplesPerPixel = samplePerPixel,
         Orientation = orientation,
         FillOrder = fillOrder
     });
 }
コード例 #2
0
ファイル: TiffHelper.cs プロジェクト: billgao87/ImageTest
        /// <summary>
        ///
        /// </summary>
        /// <param name="buffer">字节数组</param>
        /// <param name="width">图像的宽</param>
        /// <param name="height">图像的高</param>
        /// <param name="filePath"></param>
        /// <param name="rowsPerStrip">图像的实际高度</param>
        /// <param name="xResolution">x分辨率</param>
        /// <param name="yResolution">y分辨率</param>
        /// <param name="resUnit">分辨率单位,默认选inch</param>
        /// <param name="planarConfig">数据平面存储方式</param>
        /// <param name="bytePerSample">单个像素是多少位</param>
        /// <param name="photometric">图像模式</param>
        /// <param name="compression">压缩方式</param>
        /// <param name="samplePerPixel">一个像素几个采样</param>
        /// <param name="orientation">方向</param>
        /// <param name="fillOrder">大小端</param>
        public static void CreateGrayScaleTiff(byte[] buffer, int width, int height, string filePath, int rowsPerStrip,
                                               int xResolution, int yResolution, ResUnit resUnit = ResUnit.INCH,
                                               PlanarConfig planarConfig = PlanarConfig.CONTIG,
                                               int bytePerSample         = 16, Photometric photometric = Photometric.MINISBLACK,
                                               Compression compression   = Compression.NONE,
                                               int samplePerPixel        = 1, Orientation orientation = Orientation.TOPLEFT,
                                               FillOrder fillOrder       = FillOrder.MSB2LSB)
        {
            var info = CreateDoubleByteTiffInfo(buffer, null, width, height, filePath, height, width, height);

            Create16BitGrayScaleTiff(info);
        }
コード例 #3
0
        public TiffDirectory()
        {
            td_subfiletype  = 0;
            td_compression  = 0;
            td_photometric  = 0;
            td_planarconfig = 0;

            td_fillorder            = FillOrder.MSB2LSB;
            td_bitspersample        = 1;
            td_threshholding        = Threshold.BILEVEL;
            td_orientation          = Orientation.TOPLEFT;
            td_samplesperpixel      = 1;
            td_rowsperstrip         = -1;
            td_tiledepth            = 1;
            td_stripbytecountsorted = true; // Our own arrays always sorted.
            td_resolutionunit       = ResUnit.INCH;
            td_sampleformat         = SampleFormat.UINT;
            td_imagedepth           = 1;
            td_ycbcrsubsampling[0]  = 2;
            td_ycbcrsubsampling[1]  = 2;
            td_ycbcrpositioning     = YCbCrPosition.CENTERED;
        }
コード例 #4
0
ファイル: LibTiff.cs プロジェクト: Orvid/Cosmos
        public TiffDirectory()
        {
            td_subfiletype = 0;
            td_compression = 0;
            td_photometric = 0;
            td_planarconfig = 0;

            td_fillorder = BitOrder.BigEndian;
            td_bitspersample = 1;
            td_threshholding = Threshold.BILevel;
            td_orientation = Orientation.TopLeft;
            td_samplesperpixel = 1;
            td_rowsperstrip = -1;
            td_tiledepth = 1;
            td_stripbytecountsorted = true; // Our own arrays always sorted.
            td_resolutionunit = ResolutionUnit.Inch;
            td_sampleformat = SampleFormat.UInt;
            td_imagedepth = 1;
            td_ycbcrsubsampling[0] = 2;
            td_ycbcrsubsampling[1] = 2;
            td_ycbcrpositioning = YCbCrPosition.Centered;
        }
コード例 #5
0
ファイル: Copier.cs プロジェクト: XiBeichuan/hydronumerics
        public bool Copy(Tiff inImage, Tiff outImage)
        {
            int width = 0;
            FieldValue[] result = inImage.GetField(TiffTag.IMAGEWIDTH);
            if (result != null)
            {
                width = result[0].ToInt();
                outImage.SetField(TiffTag.IMAGEWIDTH, width);
            }

            int length = 0;
            result = inImage.GetField(TiffTag.IMAGELENGTH);
            if (result != null)
            {
                length = result[0].ToInt();
                outImage.SetField(TiffTag.IMAGELENGTH, length);
            }

            short bitspersample = 1;
            result = inImage.GetField(TiffTag.BITSPERSAMPLE);
            if (result != null)
            {
                bitspersample = result[0].ToShort();
                outImage.SetField(TiffTag.BITSPERSAMPLE, bitspersample);
            }

            short samplesperpixel = 1;
            result = inImage.GetField(TiffTag.SAMPLESPERPIXEL);
            if (result != null)
            {
                samplesperpixel = result[0].ToShort();
                outImage.SetField(TiffTag.SAMPLESPERPIXEL, samplesperpixel);
            }

            if (m_compression != (Compression)(-1))
                outImage.SetField(TiffTag.COMPRESSION, m_compression);
            else
            {
                result = inImage.GetField(TiffTag.COMPRESSION);
                if (result != null)
                {
                    m_compression = (Compression)result[0].ToInt();
                    outImage.SetField(TiffTag.COMPRESSION, m_compression);
                }
            }

            result = inImage.GetFieldDefaulted(TiffTag.COMPRESSION);
            Compression input_compression = (Compression)result[0].ToInt();

            result = inImage.GetFieldDefaulted(TiffTag.PHOTOMETRIC);
            Photometric input_photometric = (Photometric)result[0].ToShort();
    
            if (input_compression == Compression.JPEG)
            {
                /* Force conversion to RGB */
                inImage.SetField(TiffTag.JPEGCOLORMODE, JpegColorMode.RGB);
            }
            else if (input_photometric == Photometric.YCBCR)
            {
                /* Otherwise, can't handle subsampled input */
                result = inImage.GetFieldDefaulted(TiffTag.YCBCRSUBSAMPLING);
                short subsamplinghor = result[0].ToShort();
                short subsamplingver = result[1].ToShort();

                if (subsamplinghor != 1 || subsamplingver != 1)
                {
                    Console.Error.WriteLine("tiffcp: {0}: Can't copy/convert subsampled image.", inImage.FileName());
                    return false;
                }
            }

            if (m_compression == Compression.JPEG)
            {
                if (input_photometric == Photometric.RGB && m_jpegcolormode == JpegColorMode.RGB)
                    outImage.SetField(TiffTag.PHOTOMETRIC, Photometric.YCBCR);
                else
                    outImage.SetField(TiffTag.PHOTOMETRIC, input_photometric);
            }
            else if (m_compression == Compression.SGILOG || m_compression == Compression.SGILOG24)
            {
                outImage.SetField(TiffTag.PHOTOMETRIC, samplesperpixel == 1 ? Photometric.LOGL : Photometric.LOGLUV);
            }
            else
            {
                if (input_compression != Compression.JPEG)
                    copyTag(inImage, outImage, TiffTag.PHOTOMETRIC, 1, TiffType.SHORT);
            }

            if (m_fillorder != 0)
                outImage.SetField(TiffTag.FILLORDER, m_fillorder);
            else
                copyTag(inImage, outImage, TiffTag.FILLORDER, 1, TiffType.SHORT);

            /*
             * Will copy `Orientation' tag from input image
             */
            result = inImage.GetFieldDefaulted(TiffTag.ORIENTATION);
            m_orientation = (Orientation)result[0].ToByte();
            switch (m_orientation)
            {
                case Orientation.BOTRIGHT:
                case Orientation.RIGHTBOT:
                    Tiff.Warning(inImage.FileName(), "using bottom-left orientation");
                    m_orientation = Orientation.BOTLEFT;
                    break;

                case Orientation.LEFTBOT:
                case Orientation.BOTLEFT:
                    break;

                case Orientation.TOPRIGHT:
                case Orientation.RIGHTTOP:
                default:
                    Tiff.Warning(inImage.FileName(), "using top-left orientation");
                    m_orientation = Orientation.TOPLEFT;
                    break;

                case Orientation.LEFTTOP:
                case Orientation.TOPLEFT:
                    break;
            }

            outImage.SetField(TiffTag.ORIENTATION, m_orientation);

            /*
             * Choose tiles/strip for the output image according to
             * the command line arguments (-tiles, -strips) and the
             * structure of the input image.
             */
            if (m_outtiled == -1)
            {
                if (inImage.IsTiled())
                    m_outtiled = 1;
                else
                    m_outtiled = 0;
            }

            if (m_outtiled != 0)
            {
                /*
                 * Setup output file's tile width&height.  If either
                 * is not specified, use either the value from the
                 * input image or, if nothing is defined, use the
                 * library default.
                 */
                if (m_tilewidth == -1)
                {
                    result = inImage.GetFieldDefaulted(TiffTag.TILEWIDTH);
                    if (result != null)
                        m_tilewidth = result[0].ToInt();
                }

                if (m_tilelength == -1)
                {
                    result = inImage.GetFieldDefaulted(TiffTag.TILELENGTH);
                    if (result != null)
                        m_tilelength = result[0].ToInt();
                }

                outImage.DefaultTileSize(ref m_tilewidth, ref m_tilelength);
                outImage.SetField(TiffTag.TILEWIDTH, m_tilewidth);
                outImage.SetField(TiffTag.TILELENGTH, m_tilelength);
            }
            else
            {
                /*
                 * RowsPerStrip is left unspecified: use either the
                 * value from the input image or, if nothing is defined,
                 * use the library default.
                 */
                if (m_rowsperstrip == 0)
                {
                    result = inImage.GetField(TiffTag.ROWSPERSTRIP);
                    if (result == null)
                        m_rowsperstrip = outImage.DefaultStripSize(m_rowsperstrip);
                    else
                        m_rowsperstrip = result[0].ToInt();

                    if (m_rowsperstrip > length && m_rowsperstrip != -1)
                        m_rowsperstrip = length;
                }
                else if (m_rowsperstrip == -1)
                    m_rowsperstrip = length;

                outImage.SetField(TiffTag.ROWSPERSTRIP, m_rowsperstrip);
            }

            if (m_config != PlanarConfig.UNKNOWN)
                outImage.SetField(TiffTag.PLANARCONFIG, m_config);
            else
            {
                result = inImage.GetField(TiffTag.PLANARCONFIG);
                if (result != null)
                {
                    m_config = (PlanarConfig)result[0].ToShort();
                    outImage.SetField(TiffTag.PLANARCONFIG, m_config);
                }
            }

            if (samplesperpixel <= 4)
                copyTag(inImage, outImage, TiffTag.TRANSFERFUNCTION, 4, TiffType.SHORT);

            copyTag(inImage, outImage, TiffTag.COLORMAP, 4, TiffType.SHORT);

            /* SMinSampleValue & SMaxSampleValue */
            switch (m_compression)
            {
                case Compression.JPEG:
                    outImage.SetField(TiffTag.JPEGQUALITY, m_quality);
                    outImage.SetField(TiffTag.JPEGCOLORMODE, m_jpegcolormode);
                    break;
                case Compression.LZW:
                case Compression.ADOBE_DEFLATE:
                case Compression.DEFLATE:
                    if (m_predictor != -1)
                        outImage.SetField(TiffTag.PREDICTOR, m_predictor);
                    else
                    {
                        result = inImage.GetField(TiffTag.PREDICTOR);
                        if (result != null)
                        {
                            m_predictor = result[0].ToShort();
                            outImage.SetField(TiffTag.PREDICTOR, m_predictor);
                        }
                    }
                    break;
                case Compression.CCITTFAX3:
                case Compression.CCITTFAX4:
                    if (m_compression == Compression.CCITTFAX3)
                    {
                        if (m_g3opts != Group3Opt.UNKNOWN)
                            outImage.SetField(TiffTag.GROUP3OPTIONS, m_g3opts);
                        else
                        {
                            result = inImage.GetField(TiffTag.GROUP3OPTIONS);
                            if (result != null)
                            {
                                m_g3opts = (Group3Opt)result[0].ToShort();
                                outImage.SetField(TiffTag.GROUP3OPTIONS, m_g3opts);
                            }
                        }
                    }
                    else
                        copyTag(inImage, outImage, TiffTag.GROUP4OPTIONS, 1, TiffType.LONG);

                    copyTag(inImage, outImage, TiffTag.BADFAXLINES, 1, TiffType.LONG);
                    copyTag(inImage, outImage, TiffTag.CLEANFAXDATA, 1, TiffType.LONG);
                    copyTag(inImage, outImage, TiffTag.CONSECUTIVEBADFAXLINES, 1, TiffType.LONG);
                    copyTag(inImage, outImage, TiffTag.FAXRECVPARAMS, 1, TiffType.LONG);
                    copyTag(inImage, outImage, TiffTag.FAXRECVTIME, 1, TiffType.LONG);
                    copyTag(inImage, outImage, TiffTag.FAXSUBADDRESS, 1, TiffType.ASCII);
                    break;
            }

            result = inImage.GetField(TiffTag.ICCPROFILE);
            if (result != null)
                outImage.SetField(TiffTag.ICCPROFILE, result[0], result[1]);

            result = inImage.GetField(TiffTag.NUMBEROFINKS);
            if (result != null)
            {
                short ninks = result[0].ToShort();
                outImage.SetField(TiffTag.NUMBEROFINKS, ninks);

                result = inImage.GetField(TiffTag.INKNAMES);
                if (result != null)
                {
                    string inknames = result[0].ToString();
                    string[] parts = inknames.Split(new char[] { '\0' });

                    int inknameslen = 0;
                    foreach (string part in parts)
                        inknameslen += part.Length + 1;

                    outImage.SetField(TiffTag.INKNAMES, inknameslen, inknames);
                }
            }

            result = inImage.GetField(TiffTag.PAGENUMBER);
            if (m_pageInSeq == 1)
            {
                if (m_pageNum < 0)
                {
                    /* only one input file */ 
                    if (result != null) 
                        outImage.SetField(TiffTag.PAGENUMBER, result[0], result[1]);
                }
                else
                {
                    outImage.SetField(TiffTag.PAGENUMBER, m_pageNum++, 0);
                }
            }
            else
            {
                if (result != null)
                {
                    if (m_pageNum < 0)
                    {
                        /* only one input file */
                        outImage.SetField(TiffTag.PAGENUMBER, result[0], result[1]);
                    }
                    else
                    {
                        outImage.SetField(TiffTag.PAGENUMBER, m_pageNum++, 0);
                    }
                }
            }

            int NTAGS = g_tags.Length;
            for (int i = 0; i < NTAGS; i++)
            {
                tagToCopy p = g_tags[i];
                copyTag(inImage, outImage, p.tag, p.count, p.type);
            }

            return pickFuncAndCopy(inImage, outImage, bitspersample, samplesperpixel, length, width);
        }
コード例 #6
0
        public static void Main(string[] args)
        {
            Copier c = new Copier();

            StringBuilder mode = new StringBuilder();

            mode.Append('w');

            char         imageNumberSeparator   = ','; // (default) comma separator character
            FillOrder    defaultFillOrder       = 0;
            int          defaultTileLength      = -1;
            int          initialDirectoryOffset = 0;
            PlanarConfig defaultPlanarConfig    = PlanarConfig.UNKNOWN;
            int          defaultRowsPerStrip    = 0;
            int          defaultTileWidth       = -1;

            int argn = 0;

            for (; argn < args.Length; argn++)
            {
                string option = args[argn];
                if (option[0] == '-')
                {
                    option = option.Substring(1);
                }
                else
                {
                    break;
                }

                string optionArg = null;
                if (argn < (args.Length - 1))
                {
                    optionArg = args[argn + 1];
                }

                switch (option[0])
                {
                case ',':
                    if (option[1] != '=')
                    {
                        usage();
                        return;
                    }

                    imageNumberSeparator = option[2];
                    break;

                case 'b':
                    // this file is bias image subtracted from others
                    if (c.m_bias != null)
                    {
                        Console.Error.Write("Only 1 bias image may be specified\n");
                        return;
                    }

                    string biasName = args[argn + 1];
                    c.m_bias = Tiff.Open(biasName, "r");
                    if (c.m_bias == null)
                    {
                        Console.Error.WriteLine("Failed to open '{0}' as input.", biasName);
                        return;
                    }

                    if (c.m_bias.IsTiled())
                    {
                        Console.Error.Write("Bias image must be organized in strips\n");
                        return;
                    }

                    FieldValue[] result  = c.m_bias.GetField(TiffTag.SAMPLESPERPIXEL);
                    short        samples = result[0].ToShort();
                    if (samples != 1)
                    {
                        Console.Error.Write("Bias image must be monochrome\n");
                        return;
                    }

                    argn++;
                    break;

                case 'a':
                    // append to output
                    mode[0] = 'a';
                    break;

                case 'c':
                    // compression scheme
                    if (!c.ProcessCompressOptions(optionArg))
                    {
                        usage();
                        return;
                    }

                    argn++;
                    break;

                case 'f':
                    // fill order
                    if (optionArg == "lsb2msb")
                    {
                        defaultFillOrder = FillOrder.LSB2MSB;
                    }
                    else if (optionArg == "msb2lsb")
                    {
                        defaultFillOrder = FillOrder.MSB2LSB;
                    }
                    else
                    {
                        usage();
                        return;
                    }

                    argn++;
                    break;

                case 'i':
                    // ignore errors
                    c.m_ignore = true;
                    break;

                case 'l':
                    // tile length
                    c.m_outtiled      = 1;
                    defaultTileLength = int.Parse(optionArg, CultureInfo.InvariantCulture);
                    argn++;
                    break;

                case 'o':
                    // initial directory offset
                    initialDirectoryOffset = int.Parse(optionArg, CultureInfo.InvariantCulture);
                    break;

                case 'p':
                    // planar configuration
                    if (optionArg == "separate")
                    {
                        defaultPlanarConfig = PlanarConfig.SEPARATE;
                    }
                    else if (optionArg == "contig")
                    {
                        defaultPlanarConfig = PlanarConfig.CONTIG;
                    }
                    else
                    {
                        usage();
                        return;
                    }

                    argn++;
                    break;

                case 'r':
                    // rows/strip
                    defaultRowsPerStrip = int.Parse(optionArg, CultureInfo.InvariantCulture);
                    argn++;
                    break;

                case 's':
                    // generate stripped output
                    c.m_outtiled = 0;
                    break;

                case 't':
                    // generate tiled output
                    c.m_outtiled = 1;
                    break;

                case 'w':
                    // tile width
                    c.m_outtiled     = 1;
                    defaultTileWidth = int.Parse(optionArg, CultureInfo.InvariantCulture);
                    argn++;
                    break;

                case 'B':
                    mode.Append('b');
                    break;

                case 'L':
                    mode.Append('l');
                    break;

                case 'M':
                    mode.Append('m');
                    break;

                case 'C':
                    mode.Append('c');
                    break;

                case 'x':
                    c.m_pageInSeq = 1;
                    break;

                case '?':
                    usage();
                    return;
                }
            }

            if (args.Length - argn < 2)
            {
                // there must be at least one input and one output image names after options
                usage();
                return;
            }

            using (Tiff outImage = Tiff.Open(args[args.Length - 1], mode.ToString()))
            {
                if (outImage == null)
                {
                    Console.Error.WriteLine("Failed to open '{0}' as output.", args[args.Length - 1]);
                    return;
                }

                if ((args.Length - argn) == 2)
                {
                    c.m_pageNum = -1;
                }

                for (; argn < args.Length - 1; argn++)
                {
                    string[] fileAndPageNums = args[argn].Split(new char[] { imageNumberSeparator });

                    using (Tiff inImage = Tiff.Open(fileAndPageNums[0], "r"))
                    {
                        if (inImage == null)
                        {
                            return;
                        }

                        if (initialDirectoryOffset != 0 && !inImage.SetSubDirectory(initialDirectoryOffset))
                        {
                            Tiff.Error(inImage.FileName(), "Error, setting subdirectory at 0x{0:x}", initialDirectoryOffset);
                            break;
                        }

                        int initialPage = 0;
                        int pageNumPos  = 1;

                        if (pageNumPos < fileAndPageNums.Length && !string.IsNullOrEmpty(fileAndPageNums[pageNumPos]))
                        {
                            initialPage = int.Parse(fileAndPageNums[pageNumPos]);
                        }

                        int totalPages = inImage.NumberOfDirectories();
                        for (int i = initialPage; i < totalPages;)
                        {
                            c.m_config       = defaultPlanarConfig;
                            c.m_compression  = c.m_defcompression;
                            c.m_predictor    = c.m_defpredictor;
                            c.m_fillorder    = defaultFillOrder;
                            c.m_rowsperstrip = defaultRowsPerStrip;
                            c.m_tilewidth    = defaultTileWidth;
                            c.m_tilelength   = defaultTileLength;
                            c.m_g3opts       = c.m_defg3opts;

                            if (!inImage.SetDirectory((short)i))
                            {
                                Console.Error.Write("{0}{1}{2} not found!\n",
                                                    inImage.FileName(), imageNumberSeparator, i);
                                return;
                            }

                            if (!c.Copy(inImage, outImage) || !outImage.WriteDirectory())
                            {
                                return;
                            }

                            // if we have at least one page specifier and current specifier is not empty.
                            // specifier is empty when trailing separator used like this: "file,num,"
                            if (pageNumPos < fileAndPageNums.Length && !string.IsNullOrEmpty(fileAndPageNums[pageNumPos]))
                            {
                                // move to next page specifier
                                pageNumPos++;

                                if (pageNumPos < fileAndPageNums.Length)
                                {
                                    // new page specifier position is valid

                                    if (!string.IsNullOrEmpty(fileAndPageNums[pageNumPos]))
                                    {
                                        // new page specifier is not empty. use specified page number
                                        i = int.Parse(fileAndPageNums[pageNumPos]);
                                    }
                                    else
                                    {
                                        // new page specifier is empty. just move to the next page
                                        i++;
                                    }
                                }
                                else
                                {
                                    // new page specifier position is invalid. done all pages.
                                    break;
                                }
                            }
                            else
                            {
                                // we have no page specifiers or current page specifier is empty
                                // just move to the next page
                                i++;
                            }
                        }
                    }
                }
            }
        }
コード例 #7
0
        /// <summary>
        /// Sets the value(s) of a tag in a TIFF file/stream open for writing.
        /// </summary>
        /// <param name="tif">An instance of the <see cref="Tiff"/> class.</param>
        /// <param name="tag">The tag.</param>
        /// <param name="value">The tag value(s).</param>
        /// <returns>
        /// <c>true</c> if tag value(s) were set successfully; otherwise, <c>false</c>.
        /// </returns>
        /// <seealso cref="Tiff.SetField"/>
        public virtual bool SetField(Tiff tif, TiffTag tag, FieldValue[] value)
        {
            const string module = "vsetfield";

            TiffDirectory td     = tif.m_dir;
            bool          status = true;
            int           v32    = 0;
            int           v      = 0;

            bool end        = false;
            bool badvalue   = false;
            bool badvalue32 = false;

            switch (tag)
            {
            case TiffTag.SUBFILETYPE:
                td.td_subfiletype = (FileType)value[0].ToByte();
                break;

            case TiffTag.IMAGEWIDTH:
                td.td_imagewidth = value[0].ToInt();
                break;

            case TiffTag.IMAGELENGTH:
                td.td_imagelength = value[0].ToInt();
                break;

            case TiffTag.BITSPERSAMPLE:
                td.td_bitspersample = value[0].ToShort();
                // If the data require post-decoding processing to byte-swap samples, set it
                // up here. Note that since tags are required to be ordered, compression code
                // can override this behavior in the setup method if it wants to roll the post
                // decoding work in with its normal work.
                if ((tif.m_flags & TiffFlags.SWAB) == TiffFlags.SWAB)
                {
                    switch (td.td_bitspersample)
                    {
                    case 16:
                        tif.m_postDecodeMethod = Tiff.PostDecodeMethodType.pdmSwab16Bit;
                        break;

                    case 24:
                        tif.m_postDecodeMethod = Tiff.PostDecodeMethodType.pdmSwab24Bit;
                        break;

                    case 32:
                        tif.m_postDecodeMethod = Tiff.PostDecodeMethodType.pdmSwab32Bit;
                        break;

                    case 64:
                        tif.m_postDecodeMethod = Tiff.PostDecodeMethodType.pdmSwab64Bit;
                        break;

                    case 128:
                        // two 64's
                        tif.m_postDecodeMethod = Tiff.PostDecodeMethodType.pdmSwab64Bit;
                        break;
                    }
                }
                break;

            case TiffTag.COMPRESSION:
                v = value[0].ToInt() & 0xffff;
                Compression comp = (Compression)v;
                // If we're changing the compression scheme, then notify the previous module
                // so that it can cleanup any state it's setup.
                if (tif.fieldSet(FieldBit.Compression))
                {
                    if (td.td_compression == comp)
                    {
                        break;
                    }

                    tif.m_currentCodec.Cleanup();
                    tif.m_flags &= ~TiffFlags.CODERSETUP;
                }
                // Setup new compression scheme.
                status = tif.setCompressionScheme(comp);
                if (status)
                {
                    td.td_compression = comp;
                }
                else
                {
                    status = false;
                }
                break;

            case TiffTag.PHOTOMETRIC:
                td.td_photometric = (Photometric)value[0].ToInt();
                break;

            case TiffTag.THRESHHOLDING:
                td.td_threshholding = (Threshold)value[0].ToByte();
                break;

            case TiffTag.FILLORDER:
                v = value[0].ToInt();
                FillOrder fo = (FillOrder)v;
                if (fo != FillOrder.LSB2MSB && fo != FillOrder.MSB2LSB)
                {
                    badvalue = true;
                    break;
                }

                td.td_fillorder = fo;
                break;

            case TiffTag.ORIENTATION:
                v = value[0].ToInt();
                Orientation or = (Orientation)v;
                if (or < Orientation.TOPLEFT || Orientation.LEFTBOT < or)
                {
                    badvalue = true;
                    break;
                }
                else
                {
                    td.td_orientation = or;
                }
                break;

            case TiffTag.SAMPLESPERPIXEL:
                // XXX should cross check - e.g. if pallette, then 1
                v = value[0].ToInt();
                if (v == 0)
                {
                    badvalue = true;
                    break;
                }

                td.td_samplesperpixel = (short)v;
                break;

            case TiffTag.ROWSPERSTRIP:
                v32 = value[0].ToInt();
                if (v32 == 0)
                {
                    badvalue32 = true;
                    break;
                }

                td.td_rowsperstrip = v32;
                if (!tif.fieldSet(FieldBit.TileDimensions))
                {
                    td.td_tilelength = v32;
                    td.td_tilewidth  = td.td_imagewidth;
                }
                break;

            case TiffTag.MINSAMPLEVALUE:
                td.td_minsamplevalue = value[0].ToUShort();
                break;

            case TiffTag.MAXSAMPLEVALUE:
                td.td_maxsamplevalue = value[0].ToUShort();
                break;

            case TiffTag.SMINSAMPLEVALUE:
                td.td_sminsamplevalue = value[0].ToDouble();
                break;

            case TiffTag.SMAXSAMPLEVALUE:
                td.td_smaxsamplevalue = value[0].ToDouble();
                break;

            case TiffTag.XRESOLUTION:
                td.td_xresolution = value[0].ToFloat();
                break;

            case TiffTag.YRESOLUTION:
                td.td_yresolution = value[0].ToFloat();
                break;

            case TiffTag.PLANARCONFIG:
                v = value[0].ToInt();
                PlanarConfig pc = (PlanarConfig)v;
                if (pc != PlanarConfig.CONTIG && pc != PlanarConfig.SEPARATE)
                {
                    badvalue = true;
                    break;
                }
                td.td_planarconfig = pc;
                break;

            case TiffTag.XPOSITION:
                td.td_xposition = value[0].ToFloat();
                break;

            case TiffTag.YPOSITION:
                td.td_yposition = value[0].ToFloat();
                break;

            case TiffTag.RESOLUTIONUNIT:
                v = value[0].ToInt();
                ResUnit ru = (ResUnit)v;
                if (ru < ResUnit.NONE || ResUnit.CENTIMETER < ru)
                {
                    badvalue = true;
                    break;
                }

                td.td_resolutionunit = ru;
                break;

            case TiffTag.PAGENUMBER:
                td.td_pagenumber[0] = value[0].ToShort();
                td.td_pagenumber[1] = value[1].ToShort();
                break;

            case TiffTag.HALFTONEHINTS:
                td.td_halftonehints[0] = value[0].ToShort();
                td.td_halftonehints[1] = value[1].ToShort();
                break;

            case TiffTag.COLORMAP:
                v32 = 1 << td.td_bitspersample;
                Tiff.setShortArray(out td.td_colormap[0], value[0].ToShortArray(), v32);
                Tiff.setShortArray(out td.td_colormap[1], value[1].ToShortArray(), v32);
                Tiff.setShortArray(out td.td_colormap[2], value[2].ToShortArray(), v32);
                break;

            case TiffTag.EXTRASAMPLES:
                if (!setExtraSamples(td, ref v, value))
                {
                    badvalue = true;
                    break;
                }

                break;

            case TiffTag.MATTEING:
                if (value[0].ToShort() != 0)
                {
                    td.td_extrasamples = 1;
                }
                else
                {
                    td.td_extrasamples = 0;
                }

                if (td.td_extrasamples != 0)
                {
                    td.td_sampleinfo    = new ExtraSample[1];
                    td.td_sampleinfo[0] = ExtraSample.ASSOCALPHA;
                }
                break;

            case TiffTag.TILEWIDTH:
                v32 = value[0].ToInt();
                if ((v32 % 16) != 0)
                {
                    if (tif.m_mode != Tiff.O_RDONLY)
                    {
                        badvalue32 = true;
                        break;
                    }

                    Tiff.WarningExt(tif, tif.m_clientdata, tif.m_name,
                                    "Nonstandard tile width {0}, convert file", v32);
                }
                td.td_tilewidth = v32;
                tif.m_flags    |= TiffFlags.ISTILED;
                break;

            case TiffTag.TILELENGTH:
                v32 = value[0].ToInt();
                if ((v32 % 16) != 0)
                {
                    if (tif.m_mode != Tiff.O_RDONLY)
                    {
                        badvalue32 = true;
                        break;
                    }

                    Tiff.WarningExt(tif, tif.m_clientdata, tif.m_name,
                                    "Nonstandard tile length {0}, convert file", v32);
                }
                td.td_tilelength = v32;
                tif.m_flags     |= TiffFlags.ISTILED;
                break;

            case TiffTag.TILEDEPTH:
                v32 = value[0].ToInt();
                if (v32 == 0)
                {
                    badvalue32 = true;
                    break;
                }

                td.td_tiledepth = v32;
                break;

            case TiffTag.DATATYPE:
                v = value[0].ToInt();
                SampleFormat sf = SampleFormat.VOID;
                switch (v)
                {
                case DATATYPE_VOID:
                    sf = SampleFormat.VOID;
                    break;

                case DATATYPE_INT:
                    sf = SampleFormat.INT;
                    break;

                case DATATYPE_UINT:
                    sf = SampleFormat.UINT;
                    break;

                case DATATYPE_IEEEFP:
                    sf = SampleFormat.IEEEFP;
                    break;

                default:
                    badvalue = true;
                    break;
                }

                if (!badvalue)
                {
                    td.td_sampleformat = sf;
                }

                break;

            case TiffTag.SAMPLEFORMAT:
                v  = value[0].ToInt();
                sf = (SampleFormat)v;
                if (sf < SampleFormat.UINT || SampleFormat.COMPLEXIEEEFP < sf)
                {
                    badvalue = true;
                    break;
                }

                td.td_sampleformat = sf;

                // Try to fix up the SWAB function for complex data.
                if (td.td_sampleformat == SampleFormat.COMPLEXINT &&
                    td.td_bitspersample == 32 && tif.m_postDecodeMethod == Tiff.PostDecodeMethodType.pdmSwab32Bit)
                {
                    tif.m_postDecodeMethod = Tiff.PostDecodeMethodType.pdmSwab16Bit;
                }
                else if ((td.td_sampleformat == SampleFormat.COMPLEXINT ||
                          td.td_sampleformat == SampleFormat.COMPLEXIEEEFP) &&
                         td.td_bitspersample == 64 && tif.m_postDecodeMethod == Tiff.PostDecodeMethodType.pdmSwab64Bit)
                {
                    tif.m_postDecodeMethod = Tiff.PostDecodeMethodType.pdmSwab32Bit;
                }
                break;

            case TiffTag.IMAGEDEPTH:
                td.td_imagedepth = value[0].ToInt();
                break;

            case TiffTag.SUBIFD:
                if ((tif.m_flags & TiffFlags.INSUBIFD) != TiffFlags.INSUBIFD)
                {
                    td.td_nsubifd = value[0].ToInt();
                    Tiff.setLong8Array(out td.td_subifd, value[1].TolongArray(), td.td_nsubifd);
                }
                else
                {
                    Tiff.ErrorExt(tif, tif.m_clientdata, module,
                                  "{0}: Sorry, cannot nest SubIFDs", tif.m_name);
                    status = false;
                }
                break;

            case TiffTag.YCBCRPOSITIONING:
                td.td_ycbcrpositioning = (YCbCrPosition)value[0].ToShort();
                break;

            case TiffTag.YCBCRSUBSAMPLING:
                td.td_ycbcrsubsampling[0] = value[0].ToShort();
                td.td_ycbcrsubsampling[1] = value[1].ToShort();
                break;

            case TiffTag.TRANSFERFUNCTION:
                v = ((td.td_samplesperpixel - td.td_extrasamples) > 1 ? 3 : 1);
                for (int i = 0; i < v; i++)
                {
                    Tiff.setShortArray(out td.td_transferfunction[i], value[0].ToShortArray(), 1 << td.td_bitspersample);
                }
                break;

            case TiffTag.REFERENCEBLACKWHITE:
                // XXX should check for null range
                Tiff.setFloatArray(out td.td_refblackwhite, value[0].ToFloatArray(), 6);
                break;

            case TiffTag.INKNAMES:
                v = value[0].ToInt();
                string s = value[1].ToString();
                v      = checkInkNamesString(tif, v, s);
                status = v > 0;
                if (v > 0)
                {
                    setNString(out td.td_inknames, s, v);
                    td.td_inknameslen = v;
                }
                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 set a
                // tag that is not valid for the image's codec then we'll
                // arrive here. This happens, for example, when tiffcp is
                // used to convert between compression schemes and
                // codec-specific tags are blindly copied.
                TiffFieldInfo fip = tif.FindFieldInfo(tag, TiffType.ANY);
                if (fip == null || fip.Bit != FieldBit.Custom)
                {
                    Tiff.ErrorExt(tif, tif.m_clientdata, module,
                                  "{0}: Invalid {1}tag \"{2}\" (not supported by codec)",
                                  tif.m_name, Tiff.isPseudoTag(tag) ? "pseudo-" : string.Empty,
                                  fip != null ? fip.Name : "Unknown");
                    status = false;
                    break;
                }

                // Find the existing entry for this custom value.
                int tvIndex = -1;
                for (int iCustom = 0; iCustom < td.td_customValueCount; iCustom++)
                {
                    if (td.td_customValues[iCustom].info.Tag == tag)
                    {
                        tvIndex = iCustom;
                        td.td_customValues[iCustom].value = null;
                        break;
                    }
                }

                // Grow the custom list if the entry was not found.
                if (tvIndex == -1)
                {
                    td.td_customValueCount++;
                    TiffTagValue[] new_customValues = Tiff.Realloc(
                        td.td_customValues, td.td_customValueCount - 1, td.td_customValueCount);
                    td.td_customValues = new_customValues;

                    tvIndex = td.td_customValueCount - 1;
                    td.td_customValues[tvIndex].info  = fip;
                    td.td_customValues[tvIndex].value = null;
                    td.td_customValues[tvIndex].count = 0;
                }

                // Set custom value ... save a copy of the custom tag value.
                int tv_size = Tiff.dataSize(fip.Type);
                if (tv_size == 0)
                {
                    status = false;
                    Tiff.ErrorExt(tif, tif.m_clientdata, module,
                                  "{0}: Bad field type {1} for \"{2}\"",
                                  tif.m_name, fip.Type, fip.Name);
                    end = true;
                    break;
                }

                int paramIndex = 0;
                if (fip.PassCount)
                {
                    if (fip.WriteCount == TiffFieldInfo.Variable2)
                    {
                        td.td_customValues[tvIndex].count = value[paramIndex++].ToInt();
                    }
                    else
                    {
                        td.td_customValues[tvIndex].count = value[paramIndex++].ToInt();
                    }
                }
                else if (fip.WriteCount == TiffFieldInfo.Variable ||
                         fip.WriteCount == TiffFieldInfo.Variable2)
                {
                    td.td_customValues[tvIndex].count = 1;
                }
                else if (fip.WriteCount == TiffFieldInfo.Spp)
                {
                    td.td_customValues[tvIndex].count = td.td_samplesperpixel;
                }
                else
                {
                    td.td_customValues[tvIndex].count = fip.WriteCount;
                }

                if (fip.Type == TiffType.ASCII)
                {
                    string ascii;
                    Tiff.setString(out ascii, value[paramIndex++].ToString());
                    td.td_customValues[tvIndex].value = Tiff.Latin1Encoding.GetBytes(ascii);
                }
                else
                {
                    td.td_customValues[tvIndex].value = new byte[tv_size * td.td_customValues[tvIndex].count];
                    if ((fip.PassCount ||
                         fip.WriteCount == TiffFieldInfo.Variable ||
                         fip.WriteCount == TiffFieldInfo.Variable2 ||
                         fip.WriteCount == TiffFieldInfo.Spp ||
                         td.td_customValues[tvIndex].count > 1) &&
                        fip.Tag != TiffTag.PAGENUMBER &&
                        fip.Tag != TiffTag.HALFTONEHINTS &&
                        fip.Tag != TiffTag.YCBCRSUBSAMPLING &&
                        fip.Tag != TiffTag.DOTRANGE)
                    {
                        byte[] apBytes = value[paramIndex++].GetBytes();
                        Buffer.BlockCopy(apBytes, 0, td.td_customValues[tvIndex].value, 0, Math.Min(apBytes.Length, td.td_customValues[tvIndex].value.Length));
                    }
                    else
                    {
                        // XXX: The following loop required to handle
                        // PAGENUMBER, HALFTONEHINTS,
                        // YCBCRSUBSAMPLING and DOTRANGE tags.
                        // These tags are actually arrays and should be
                        // passed as arrays to SetField() function, but
                        // actually passed as a list of separate values.
                        // This behavior must be changed in the future!

                        // Upd: This loop also processes some EXIF tags with
                        // UNDEFINED type (like EXIF_FILESOURCE or EXIF_SCENETYPE)
                        // In this case input value is string-based, so
                        // in TiffType.UNDEFINED case we use FieldValue.GetBytes()[0]
                        // construction instead of direct call of FieldValue.ToByte() method.
                        byte[] val    = td.td_customValues[tvIndex].value;
                        int    valPos = 0;
                        for (int i = 0; i < td.td_customValues[tvIndex].count; i++, valPos += tv_size)
                        {
                            switch (fip.Type)
                            {
                            case TiffType.BYTE:
                            case TiffType.UNDEFINED:
                                val[valPos] = value[paramIndex + i].GetBytes()[0];
                                break;

                            case TiffType.SBYTE:
                                val[valPos] = value[paramIndex + i].ToByte();
                                break;

                            case TiffType.SHORT:
                                Buffer.BlockCopy(BitConverter.GetBytes(value[paramIndex + i].ToShort()), 0, val, valPos, tv_size);
                                break;

                            case TiffType.SSHORT:
                                Buffer.BlockCopy(BitConverter.GetBytes(value[paramIndex + i].ToShort()), 0, val, valPos, tv_size);
                                break;

                            case TiffType.LONG:
                            case TiffType.IFD:
                                Buffer.BlockCopy(BitConverter.GetBytes(value[paramIndex + i].ToInt()), 0, val, valPos, tv_size);
                                break;

                            case TiffType.SLONG:
                                Buffer.BlockCopy(BitConverter.GetBytes(value[paramIndex + i].ToInt()), 0, val, valPos, tv_size);
                                break;

                            case TiffType.RATIONAL:
                            case TiffType.SRATIONAL:
                            case TiffType.FLOAT:
                                Buffer.BlockCopy(BitConverter.GetBytes(value[paramIndex + i].ToFloat()), 0, val, valPos, tv_size);
                                break;

                            case TiffType.DOUBLE:
                                Buffer.BlockCopy(BitConverter.GetBytes(value[paramIndex + i].ToDouble()), 0, val, valPos, tv_size);
                                break;

                            default:
                                Array.Clear(val, valPos, tv_size);
                                status = false;
                                break;
                            }
                        }
                    }
                }
                break;
            }

            if (!end && !badvalue && !badvalue32)
            {
                if (status)
                {
                    tif.setFieldBit(tif.FieldWithTag(tag).Bit);
                    tif.m_flags |= TiffFlags.DIRTYDIRECT;
                }
            }

            if (badvalue)
            {
                Tiff.ErrorExt(tif, tif.m_clientdata, module,
                              "{0}: Bad value {1} for \"{2}\" tag",
                              tif.m_name, v, tif.FieldWithTag(tag).Name);
                return(false);
            }

            if (badvalue32)
            {
                Tiff.ErrorExt(tif, tif.m_clientdata, module,
                              "{0}: Bad value {1} for \"{2}\" tag",
                              tif.m_name, v32, tif.FieldWithTag(tag).Name);
                return(false);
            }

            return(status);
        }
コード例 #8
0
        public TiffDirectory()
        {
            td_subfiletype = 0;
            td_compression = 0;
            td_photometric = 0;
            td_planarconfig = 0;

            td_fillorder = FillOrder.MSB2LSB;
            td_bitspersample = 1;
            td_threshholding = Threshold.BILEVEL;
            td_orientation = Orientation.TOPLEFT;
            td_samplesperpixel = 1;
            td_rowsperstrip = -1;
            td_tiledepth = 1;
            td_stripbytecountsorted = true; // Our own arrays always sorted.
            td_resolutionunit = ResUnit.INCH;
            td_sampleformat = SampleFormat.UINT;
            td_imagedepth = 1;
            td_ycbcrsubsampling[0] = 2;
            td_ycbcrsubsampling[1] = 2;
            td_ycbcrpositioning = YCbCrPosition.CENTERED;
        }
コード例 #9
0
ファイル: T2P.cs プロジェクト: dronab/libtiff.net
        /*
        This function sets the input directory to the directory of a given
        page and determines information about the image.  It checks
        the image characteristics to determine if it is possible to convert
        the image data into a page of PDF output, setting values of the T2P
        struct for this page.  It determines what color space is used in
        the output PDF to represent the image.

        It determines if the image can be converted as raw data without
        requiring transcoding of the image data.
        */
        private void read_tiff_data(Tiff input)
        {
            m_pdf_transcode = t2p_transcode_t.T2P_TRANSCODE_ENCODE;
            m_pdf_sample = t2p_sample_t.T2P_SAMPLE_NOTHING;
            m_pdf_switchdecode = m_pdf_colorspace_invert;

            input.SetDirectory(m_tiff_pages[m_pdf_page].page_directory);

            FieldValue[] result = input.GetField(TiffTag.IMAGEWIDTH);
            m_tiff_width = result[0].ToInt();
            if (m_tiff_width == 0)
            {
                Tiff.Error(Tiff2PdfConstants.TIFF2PDF_MODULE, "No support for {0} with zero width", input.FileName());
                m_error = true;
                return;
            }

            result = input.GetField(TiffTag.IMAGELENGTH);
            m_tiff_length = result[0].ToInt();
            if (m_tiff_length == 0)
            {
                Tiff.Error(Tiff2PdfConstants.TIFF2PDF_MODULE, 
                    "No support for {0} with zero length", input.FileName());
                m_error = true;
                return;
            }

            result = input.GetField(TiffTag.COMPRESSION);
            if (result == null)
            {
                Tiff.Error(Tiff2PdfConstants.TIFF2PDF_MODULE, 
                    "No support for {0} with no compression tag", input.FileName());
                m_error = true;
                return;
            }
            else
                m_tiff_compression = (Compression)result[0].ToInt();

            if (!input.IsCodecConfigured(m_tiff_compression))
            {
                Tiff.Error(Tiff2PdfConstants.TIFF2PDF_MODULE, 
                    "No support for {0} with compression type {1}:  not configured", 
                    input.FileName(), m_tiff_compression);
                m_error = true;
                return;

            }

            result = input.GetFieldDefaulted(TiffTag.BITSPERSAMPLE);
            m_tiff_bitspersample = result[0].ToShort();

            switch (m_tiff_bitspersample)
            {
                case 1:
                case 2:
                case 4:
                case 8:
                    break;
                case 0:
                    Tiff.Warning(Tiff2PdfConstants.TIFF2PDF_MODULE, 
                        "Image {0} has 0 bits per sample, assuming 1", input.FileName());
                    m_tiff_bitspersample = 1;
                    break;
                default:
                    Tiff.Error(Tiff2PdfConstants.TIFF2PDF_MODULE, 
                        "No support for {0} with {1} bits per sample",
                        input.FileName(), m_tiff_bitspersample);
                    m_error = true;
                    return;
            }

            result = input.GetFieldDefaulted(TiffTag.SAMPLESPERPIXEL);
            m_tiff_samplesperpixel = result[0].ToShort();
            if (m_tiff_samplesperpixel > 4)
            {
                Tiff.Error(Tiff2PdfConstants.TIFF2PDF_MODULE, 
                    "No support for {0} with {1} samples per pixel", input.FileName(), m_tiff_samplesperpixel);
                m_error = true;
                return;
            }

            if (m_tiff_samplesperpixel == 0)
            {
                Tiff.Warning(Tiff2PdfConstants.TIFF2PDF_MODULE, 
                    "Image {0} has 0 samples per pixel, assuming 1", input.FileName());
                m_tiff_samplesperpixel = 1;
            }

            result = input.GetField(TiffTag.SAMPLEFORMAT);
            if (result != null)
            {
                SampleFormat f = (SampleFormat)result[0].ToByte();
                switch (f)
                {
                    case 0:
                    case SampleFormat.UINT:
                    case SampleFormat.VOID:
                        break;

                    default:
                        Tiff.Error(Tiff2PdfConstants.TIFF2PDF_MODULE, 
                            "No support for {0} with sample format {1}", input.FileName(), f);
                        m_error = true;
                        return;
                }
            }

            result = input.GetFieldDefaulted(TiffTag.FILLORDER);
            m_tiff_fillorder = (FillOrder)result[0].ToByte();

            result = input.GetField(TiffTag.PHOTOMETRIC);
            if (result == null)
            {
                Tiff.Error(Tiff2PdfConstants.TIFF2PDF_MODULE, 
                    "No support for {0} with no photometric interpretation tag", input.FileName());
                m_error = true;
                return;
            }
            else
                m_tiff_photometric = (Photometric)result[0].ToInt();

            short[] r;
            short[] g;
            short[] b;
            short[] a;
            bool photometric_palette;
            bool photometric_palette_cmyk;

            switch (m_tiff_photometric)
            {
                case Photometric.MINISWHITE:
                case Photometric.MINISBLACK:
                    if (m_tiff_bitspersample == 1)
                    {
                        m_pdf_colorspace = t2p_cs_t.T2P_CS_BILEVEL;
                        if (m_tiff_photometric == Photometric.MINISWHITE)
                            m_pdf_switchdecode ^= true;
                    }
                    else
                    {
                        m_pdf_colorspace = t2p_cs_t.T2P_CS_GRAY;
                        if (m_tiff_photometric == Photometric.MINISWHITE)
                            m_pdf_switchdecode ^= true;
                    }
                    break;
               
                case Photometric.RGB:
                case Photometric.PALETTE:
                    photometric_palette = (m_tiff_photometric == Photometric.PALETTE);
                    if (!photometric_palette)
                    {
                        m_pdf_colorspace = t2p_cs_t.T2P_CS_RGB;
                        if (m_tiff_samplesperpixel == 3)
                            break;

                        result = input.GetField(TiffTag.INDEXED);
                        if (result != null)
                        {
                            if (result[0].ToInt() == 1)
                                photometric_palette = true;
                        }
                    }

                    if (!photometric_palette)
                    {
                        if (m_tiff_samplesperpixel > 3)
                        {
                            if (m_tiff_samplesperpixel == 4)
                            {
                                m_pdf_colorspace = t2p_cs_t.T2P_CS_RGB;

                                result = input.GetField(TiffTag.EXTRASAMPLES);
                                if (result != null && result[0].ToInt() == 1)
                                {
                                    byte[] xuint16p = result[1].ToByteArray();
                                    if ((ExtraSample)xuint16p[0] == ExtraSample.ASSOCALPHA)
                                    {
                                        m_pdf_sample = t2p_sample_t.T2P_SAMPLE_RGBAA_TO_RGB;
                                        break;
                                    }

                                    if ((ExtraSample)xuint16p[0] == ExtraSample.UNASSALPHA)
                                    {
                                        m_pdf_sample = t2p_sample_t.T2P_SAMPLE_RGBA_TO_RGB;
                                        break;
                                    }
                                    
                                    Tiff.Warning(Tiff2PdfConstants.TIFF2PDF_MODULE,
                                        "RGB image {0} has 4 samples per pixel, assuming RGBA", input.FileName());
                                    break;
                                }

                                m_pdf_colorspace = t2p_cs_t.T2P_CS_CMYK;
                                m_pdf_switchdecode ^= true;
                                Tiff.Warning(Tiff2PdfConstants.TIFF2PDF_MODULE, 
                                    "RGB image {0} has 4 samples per pixel, assuming inverse CMYK", input.FileName());
                                break;
                            }
                            else
                            {
                                Tiff.Error(Tiff2PdfConstants.TIFF2PDF_MODULE,
                                    "No support for RGB image {0} with {1} samples per pixel", 
                                    input.FileName(), m_tiff_samplesperpixel);
                                m_error = true;
                                break;
                            }
                        }
                        else
                        {
                            Tiff.Error(Tiff2PdfConstants.TIFF2PDF_MODULE,
                                "No support for RGB image {0} with {1} samples per pixel",
                                input.FileName(), m_tiff_samplesperpixel);
                            m_error = true;
                            break;
                        }
                    }

                    if (photometric_palette)
                    {
                        if (m_tiff_samplesperpixel != 1)
                        {
                            Tiff.Error(Tiff2PdfConstants.TIFF2PDF_MODULE,
                                "No support for palletized image {0} with not one sample per pixel",
                                input.FileName());
                            m_error = true;
                            return;
                        }

                        m_pdf_colorspace = (t2p_cs_t)(t2p_cs_t.T2P_CS_RGB | t2p_cs_t.T2P_CS_PALETTE);
                        m_pdf_palettesize = 0x0001 << m_tiff_bitspersample;

                        result = input.GetField(TiffTag.COLORMAP);
                        if (result == null)
                        {
                            Tiff.Error(Tiff2PdfConstants.TIFF2PDF_MODULE, 
                                "Palletized image {0} has no color map", input.FileName());
                            m_error = true;
                            return;
                        }
                        else
                        {
                            r = result[0].ToShortArray();
                            g = result[1].ToShortArray();
                            b = result[2].ToShortArray();
                        }

                        m_pdf_palette = new byte [m_pdf_palettesize * 3];
                        for (int i = 0; i < m_pdf_palettesize; i++)
                        {
                            m_pdf_palette[i * 3] = (byte)(r[i] >> 8);
                            m_pdf_palette[i * 3 + 1] = (byte)(g[i] >> 8);
                            m_pdf_palette[i * 3 + 2] = (byte)(b[i] >> 8);
                        }

                        m_pdf_palettesize *= 3;
                    }
                    break;

                case Photometric.SEPARATED:
                    photometric_palette_cmyk = false;
                    result = input.GetField(TiffTag.INDEXED);
                    if (result != null)
                    {
                        if (result[0].ToInt() == 1)
                            photometric_palette_cmyk = true;
                    }

                    if (!photometric_palette_cmyk)
                    {
                        result = input.GetField(TiffTag.INKSET);
                        if (result != null)
                        {
                            if ((InkSet)result[0].ToByte() != InkSet.CMYK)
                            {
                                Tiff.Error(Tiff2PdfConstants.TIFF2PDF_MODULE,
                                    "No support for {0} because its inkset is not CMYK", input.FileName());
                                m_error = true;
                                return;
                            }
                        }
                        
                        if (m_tiff_samplesperpixel == 4)
                        {
                            m_pdf_colorspace = t2p_cs_t.T2P_CS_CMYK;
                        }
                        else
                        {
                            Tiff.Error(Tiff2PdfConstants.TIFF2PDF_MODULE,
                                "No support for {0} because it has {1} samples per pixel",
                                input.FileName(), m_tiff_samplesperpixel);
                            m_error = true;
                            return;
                        }
                    }
                    else
                    {
                        if (m_tiff_samplesperpixel != 1)
                        {
                            Tiff.Error(Tiff2PdfConstants.TIFF2PDF_MODULE,
                                "No support for palletized CMYK image {0} with not one sample per pixel",
                                input.FileName());
                            m_error = true;
                            return;
                        }
                        
                        m_pdf_colorspace = (t2p_cs_t)(t2p_cs_t.T2P_CS_CMYK | t2p_cs_t.T2P_CS_PALETTE);
                        m_pdf_palettesize = 0x0001 << m_tiff_bitspersample;
                        
                        result = input.GetField(TiffTag.COLORMAP);
                        if (result == null)
                        {
                            Tiff.Error(Tiff2PdfConstants.TIFF2PDF_MODULE,
                                "Palletized image {0} has no color map", input.FileName());
                            m_error = true;
                            return;
                        }
                        else
                        {
                            r = result[0].ToShortArray();
                            g = result[1].ToShortArray();
                            b = result[2].ToShortArray();
                            a = result[3].ToShortArray();
                        }
                        
                        m_pdf_palette = new byte [m_pdf_palettesize * 4];
                        for (int i = 0; i < m_pdf_palettesize; i++)
                        {
                            m_pdf_palette[i * 4] = (byte)(r[i] >> 8);
                            m_pdf_palette[i * 4 + 1] = (byte)(g[i] >> 8);
                            m_pdf_palette[i * 4 + 2] = (byte)(b[i] >> 8);
                            m_pdf_palette[i * 4 + 3] = (byte)(a[i] >> 8);
                        }

                        m_pdf_palettesize *= 4;
                    }
                    break;
                
                case Photometric.YCBCR:
                    m_pdf_colorspace = t2p_cs_t.T2P_CS_RGB;
                    if (m_tiff_samplesperpixel == 1)
                    {
                        m_pdf_colorspace = t2p_cs_t.T2P_CS_GRAY;
                        m_tiff_photometric = Photometric.MINISBLACK;
                        break;
                    }

                    m_pdf_sample = t2p_sample_t.T2P_SAMPLE_YCBCR_TO_RGB;
                    if (m_pdf_defaultcompression == t2p_compress_t.T2P_COMPRESS_JPEG)
                        m_pdf_sample = t2p_sample_t.T2P_SAMPLE_NOTHING;

                    break;

                case Photometric.CIELAB:
                    m_pdf_labrange[0] = -127;
                    m_pdf_labrange[1] = 127;
                    m_pdf_labrange[2] = -127;
                    m_pdf_labrange[3] = 127;
                    m_pdf_sample = t2p_sample_t.T2P_SAMPLE_LAB_SIGNED_TO_UNSIGNED;
                    m_pdf_colorspace = t2p_cs_t.T2P_CS_LAB;
                    break;

                case Photometric.ICCLAB:
                    m_pdf_labrange[0] = 0;
                    m_pdf_labrange[1] = 255;
                    m_pdf_labrange[2] = 0;
                    m_pdf_labrange[3] = 255;
                    m_pdf_colorspace = t2p_cs_t.T2P_CS_LAB;
                    break;

                case Photometric.ITULAB:
                    m_pdf_labrange[0] = -85;
                    m_pdf_labrange[1] = 85;
                    m_pdf_labrange[2] = -75;
                    m_pdf_labrange[3] = 124;
                    m_pdf_sample = t2p_sample_t.T2P_SAMPLE_LAB_SIGNED_TO_UNSIGNED;
                    m_pdf_colorspace = t2p_cs_t.T2P_CS_LAB;
                    break;

                case Photometric.LOGL:
                case Photometric.LOGLUV:
                    Tiff.Error(Tiff2PdfConstants.TIFF2PDF_MODULE,
                        "No support for {0} with photometric interpretation LogL/LogLuv", input.FileName());
                    m_error = true;
                    return;
                default:
                    Tiff.Error(Tiff2PdfConstants.TIFF2PDF_MODULE,
                        "No support for {0} with photometric interpretation {1}",
                        input.FileName(), m_tiff_photometric);
                    m_error = true;
                    return;
            }

            result = input.GetField(TiffTag.PLANARCONFIG);
            if (result != null)
            {
                m_tiff_planar = (PlanarConfig)result[0].ToShort();
                switch (m_tiff_planar)
                {
                    case 0:
                        Tiff.Warning(Tiff2PdfConstants.TIFF2PDF_MODULE,
                            "Image {0} has planar configuration 0, assuming 1", input.FileName());
                        m_tiff_planar = PlanarConfig.CONTIG;
                        break;

                    case PlanarConfig.CONTIG:
                        break;
                    
                    case PlanarConfig.SEPARATE:
                        m_pdf_sample = t2p_sample_t.T2P_SAMPLE_PLANAR_SEPARATE_TO_CONTIG;
                        if (m_tiff_bitspersample != 8)
                        {
                            Tiff.Error(Tiff2PdfConstants.TIFF2PDF_MODULE,
                                "No support for {0} with separated planar configuration and {1} bits per sample",
                                input.FileName(), m_tiff_bitspersample);
                            m_error = true;
                            return;
                        }
                        break;
                    
                    default:
                        Tiff.Error(Tiff2PdfConstants.TIFF2PDF_MODULE,
                            "No support for {0} with planar configuration {1}",
                            input.FileName(), m_tiff_planar);
                        m_error = true;
                        return;
                }
            }

            result = input.GetFieldDefaulted(TiffTag.ORIENTATION);
            m_tiff_orientation = (Orientation)result[0].ToByte();

            if (m_tiff_orientation > Orientation.LEFTBOT)
            {
                Tiff.Warning(Tiff2PdfConstants.TIFF2PDF_MODULE,
                    "Image {0} has orientation {1}, assuming 0", 
                    input.FileName(), m_tiff_orientation);
                m_tiff_orientation = 0;
            }

            result = input.GetField(TiffTag.XRESOLUTION);
            if (result == null)
                m_tiff_xres = 0.0f;
            else
                m_tiff_xres = result[0].ToFloat();

            result = input.GetField(TiffTag.YRESOLUTION);
            if (result == null)
                m_tiff_yres = 0.0f;
            else
                m_tiff_yres = result[0].ToFloat();

            result = input.GetFieldDefaulted(TiffTag.RESOLUTIONUNIT);
            m_tiff_resunit = (ResUnit)result[0].ToByte();
            if (m_tiff_resunit == ResUnit.CENTIMETER)
            {
                m_tiff_xres *= 2.54F;
                m_tiff_yres *= 2.54F;
            }
            else if (m_tiff_resunit != ResUnit.INCH && m_pdf_centimeters)
            {
                m_tiff_xres *= 2.54F;
                m_tiff_yres *= 2.54F;
            }

            compose_pdf_page();

            m_pdf_transcode = t2p_transcode_t.T2P_TRANSCODE_ENCODE;
            if (!m_pdf_nopassthrough)
            {
                if (m_tiff_compression == Compression.CCITTFAX4)
                {
                    if (input.IsTiled() || (input.NumberOfStrips() == 1))
                    {
                        m_pdf_transcode = t2p_transcode_t.T2P_TRANSCODE_RAW;
                        m_pdf_compression = t2p_compress_t.T2P_COMPRESS_G4;
                    }
                }

                if (m_tiff_compression == Compression.ADOBE_DEFLATE || m_tiff_compression == Compression.DEFLATE)
                {
                    if (input.IsTiled() || (input.NumberOfStrips() == 1))
                    {
                        m_pdf_transcode = t2p_transcode_t.T2P_TRANSCODE_RAW;
                        m_pdf_compression = t2p_compress_t.T2P_COMPRESS_ZIP;
                    }
                }

                if (m_tiff_compression == Compression.JPEG)
                {
                    m_pdf_transcode = t2p_transcode_t.T2P_TRANSCODE_RAW;
                    m_pdf_compression = t2p_compress_t.T2P_COMPRESS_JPEG;
                }
            }

            if (m_pdf_transcode != t2p_transcode_t.T2P_TRANSCODE_RAW)
                m_pdf_compression = m_pdf_defaultcompression;

            if (m_pdf_defaultcompression == t2p_compress_t.T2P_COMPRESS_JPEG)
            {
                if ((m_pdf_colorspace & t2p_cs_t.T2P_CS_PALETTE) != 0)
                {
                    m_pdf_sample = (t2p_sample_t)(m_pdf_sample | t2p_sample_t.T2P_SAMPLE_REALIZE_PALETTE);
                    m_pdf_colorspace = (t2p_cs_t)(m_pdf_colorspace ^ t2p_cs_t.T2P_CS_PALETTE);
                    m_tiff_pages[m_pdf_page].page_extra--;
                }
            }

            if (m_tiff_compression == Compression.JPEG)
            {
                if (m_tiff_planar == PlanarConfig.SEPARATE)
                {
                    Tiff.Error(Tiff2PdfConstants.TIFF2PDF_MODULE,
                        "No support for {0} with JPEG compression and separated planar configuration",
                        input.FileName());
                    m_error = true;
                    return;
                }
            }

            if ((m_pdf_sample & t2p_sample_t.T2P_SAMPLE_REALIZE_PALETTE) != 0)
            {
                if ((m_pdf_colorspace & t2p_cs_t.T2P_CS_CMYK) != 0)
                {
                    m_tiff_samplesperpixel = 4;
                    m_tiff_photometric = Photometric.SEPARATED;
                }
                else
                {
                    m_tiff_samplesperpixel = 3;
                    m_tiff_photometric = Photometric.RGB;
                }
            }

            result = input.GetField(TiffTag.TRANSFERFUNCTION);
            if (result != null)
            {
                m_tiff_transferfunction[0] = result[0].GetBytes();
                m_tiff_transferfunction[1] = result[1].GetBytes();
                m_tiff_transferfunction[2] = result[2].GetBytes();

                if (m_tiff_transferfunction[1] != m_tiff_transferfunction[0])
                    m_tiff_transferfunctioncount = 3;
                else
                    m_tiff_transferfunctioncount = 1;
            }
            else
            {
                m_tiff_transferfunctioncount = 0;
            }

            result = input.GetField(TiffTag.WHITEPOINT);
            if (result != null)
            {
                float[] xfloatp = result[0].ToFloatArray();
                m_tiff_whitechromaticities[0] = xfloatp[0];
                m_tiff_whitechromaticities[1] = xfloatp[1];
                
                if ((m_pdf_colorspace & t2p_cs_t.T2P_CS_GRAY) != 0)
                    m_pdf_colorspace = (t2p_cs_t)(m_pdf_colorspace | t2p_cs_t.T2P_CS_CALGRAY);

                if ((m_pdf_colorspace & t2p_cs_t.T2P_CS_RGB) != 0)
                    m_pdf_colorspace = (t2p_cs_t)(m_pdf_colorspace | t2p_cs_t.T2P_CS_CALRGB);
            }
            
            result = input.GetField(TiffTag.PRIMARYCHROMATICITIES);
            if (result != null)
            {
                float[] xfloatp = result[0].ToFloatArray();
                m_tiff_primarychromaticities[0] = xfloatp[0];
                m_tiff_primarychromaticities[1] = xfloatp[1];
                m_tiff_primarychromaticities[2] = xfloatp[2];
                m_tiff_primarychromaticities[3] = xfloatp[3];
                m_tiff_primarychromaticities[4] = xfloatp[4];
                m_tiff_primarychromaticities[5] = xfloatp[5];

                if ((m_pdf_colorspace & t2p_cs_t.T2P_CS_RGB) != 0)
                    m_pdf_colorspace = (t2p_cs_t)(m_pdf_colorspace | t2p_cs_t.T2P_CS_CALRGB);
            }

            if ((m_pdf_colorspace & t2p_cs_t.T2P_CS_LAB) != 0)
            {
                result = input.GetField(TiffTag.WHITEPOINT);
                if (result != null)
                {
                    float[] xfloatp = result[0].ToFloatArray();
                    m_tiff_whitechromaticities[0] = xfloatp[0];
                    m_tiff_whitechromaticities[1] = xfloatp[1];
                }
                else
                {
                    m_tiff_whitechromaticities[0] = 0.3457F; /* 0.3127F; */
                    m_tiff_whitechromaticities[1] = 0.3585F; /* 0.3290F; */
                }
            }

            result = input.GetField(TiffTag.ICCPROFILE);
            if (result != null)
            {
                m_tiff_iccprofilelength = result[0].ToInt();
                m_tiff_iccprofile = result[1].ToByteArray();
                m_pdf_colorspace = (t2p_cs_t)(m_pdf_colorspace | t2p_cs_t.T2P_CS_ICCBASED);
            }
            else
            {
                m_tiff_iccprofilelength = 0;
                m_tiff_iccprofile = null;
            }

            if (m_tiff_bitspersample == 1 && m_tiff_samplesperpixel == 1)
                m_pdf_compression = t2p_compress_t.T2P_COMPRESS_G4;
        }