Пример #1
0
        /** Reads a page from a TIFF image.
         * @param s the file source
         * @param page the page to get. The first page is 1
         * @param direct for single strip, CCITT images, generate the image
         * by direct byte copying. It's faster but may not work
         * every time
         * @return the <CODE>Image</CODE>
         */
        public static Image GetTiffImage(RandomAccessFileOrArray s, int page, bool direct)
        {
            if (page < 1)
            {
                throw new ArgumentException("The page number must be >= 1.");
            }
            TIFFDirectory dir = new TIFFDirectory(s, page - 1);

            if (dir.IsTagPresent(TIFFConstants.TIFFTAG_TILEWIDTH))
            {
                throw new ArgumentException("Tiles are not supported.");
            }
            int compression = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_COMPRESSION);

            switch (compression)
            {
            case TIFFConstants.COMPRESSION_CCITTRLEW:
            case TIFFConstants.COMPRESSION_CCITTRLE:
            case TIFFConstants.COMPRESSION_CCITTFAX3:
            case TIFFConstants.COMPRESSION_CCITTFAX4:
                break;

            default:
                return(GetTiffImageColor(dir, s));
            }
            float rotation = 0;

            if (dir.IsTagPresent(TIFFConstants.TIFFTAG_ORIENTATION))
            {
                int rot = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_ORIENTATION);
                if (rot == TIFFConstants.ORIENTATION_BOTRIGHT || rot == TIFFConstants.ORIENTATION_BOTLEFT)
                {
                    rotation = (float)Math.PI;
                }
                else if (rot == TIFFConstants.ORIENTATION_LEFTTOP || rot == TIFFConstants.ORIENTATION_LEFTBOT)
                {
                    rotation = (float)(Math.PI / 2.0);
                }
                else if (rot == TIFFConstants.ORIENTATION_RIGHTTOP || rot == TIFFConstants.ORIENTATION_RIGHTBOT)
                {
                    rotation = -(float)(Math.PI / 2.0);
                }
            }

            Image img            = null;
            long  tiffT4Options  = 0;
            long  tiffT6Options  = 0;
            int   fillOrder      = 1;
            int   h              = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_IMAGELENGTH);
            int   w              = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_IMAGEWIDTH);
            int   dpiX           = 0;
            int   dpiY           = 0;
            float XYRatio        = 0;
            int   resolutionUnit = TIFFConstants.RESUNIT_INCH;

            if (dir.IsTagPresent(TIFFConstants.TIFFTAG_RESOLUTIONUNIT))
            {
                resolutionUnit = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_RESOLUTIONUNIT);
            }
            dpiX = GetDpi(dir.GetField(TIFFConstants.TIFFTAG_XRESOLUTION), resolutionUnit);
            dpiY = GetDpi(dir.GetField(TIFFConstants.TIFFTAG_YRESOLUTION), resolutionUnit);
            if (resolutionUnit == TIFFConstants.RESUNIT_NONE)
            {
                if (dpiY != 0)
                {
                    XYRatio = (float)dpiX / (float)dpiY;
                }
                dpiX = 0;
                dpiY = 0;
            }
            int rowsStrip = h;

            if (dir.IsTagPresent(TIFFConstants.TIFFTAG_ROWSPERSTRIP))
            {
                rowsStrip = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_ROWSPERSTRIP);
            }
            if (rowsStrip <= 0 || rowsStrip > h)
            {
                rowsStrip = h;
            }
            long[] offset = GetArrayLongShort(dir, TIFFConstants.TIFFTAG_STRIPOFFSETS);
            long[] size   = GetArrayLongShort(dir, TIFFConstants.TIFFTAG_STRIPBYTECOUNTS);
            if ((size == null || (size.Length == 1 && (size[0] == 0 || size[0] + offset[0] > s.Length))) && h == rowsStrip)   // some TIFF producers are really lousy, so...
            {
                size = new long[] { s.Length - (int)offset[0] };
            }
            bool      reverse        = false;
            TIFFField fillOrderField = dir.GetField(TIFFConstants.TIFFTAG_FILLORDER);

            if (fillOrderField != null)
            {
                fillOrder = fillOrderField.GetAsInt(0);
            }
            reverse = (fillOrder == TIFFConstants.FILLORDER_LSB2MSB);
            int paramsn = 0;

            if (dir.IsTagPresent(TIFFConstants.TIFFTAG_PHOTOMETRIC))
            {
                long photo = dir.GetFieldAsLong(TIFFConstants.TIFFTAG_PHOTOMETRIC);
                if (photo == TIFFConstants.PHOTOMETRIC_MINISBLACK)
                {
                    paramsn |= Image.CCITT_BLACKIS1;
                }
            }
            int imagecomp = 0;

            switch (compression)
            {
            case TIFFConstants.COMPRESSION_CCITTRLEW:
            case TIFFConstants.COMPRESSION_CCITTRLE:
                imagecomp = Image.CCITTG3_1D;
                paramsn  |= Image.CCITT_ENCODEDBYTEALIGN | Image.CCITT_ENDOFBLOCK;
                break;

            case TIFFConstants.COMPRESSION_CCITTFAX3:
                imagecomp = Image.CCITTG3_1D;
                paramsn  |= Image.CCITT_ENDOFLINE | Image.CCITT_ENDOFBLOCK;
                TIFFField t4OptionsField = dir.GetField(TIFFConstants.TIFFTAG_GROUP3OPTIONS);
                if (t4OptionsField != null)
                {
                    tiffT4Options = t4OptionsField.GetAsLong(0);
                    if ((tiffT4Options & TIFFConstants.GROUP3OPT_2DENCODING) != 0)
                    {
                        imagecomp = Image.CCITTG3_2D;
                    }
                    if ((tiffT4Options & TIFFConstants.GROUP3OPT_FILLBITS) != 0)
                    {
                        paramsn |= Image.CCITT_ENCODEDBYTEALIGN;
                    }
                }
                break;

            case TIFFConstants.COMPRESSION_CCITTFAX4:
                imagecomp = Image.CCITTG4;
                TIFFField t6OptionsField = dir.GetField(TIFFConstants.TIFFTAG_GROUP4OPTIONS);
                if (t6OptionsField != null)
                {
                    tiffT6Options = t6OptionsField.GetAsLong(0);
                }
                break;
            }
            if (direct && rowsStrip == h)   //single strip, direct
            {
                byte[] im = new byte[(int)size[0]];
                s.Seek(offset[0]);
                s.ReadFully(im);
                img          = Image.GetInstance(w, h, false, imagecomp, paramsn, im);
                img.Inverted = true;
            }
            else
            {
                int            rowsLeft = h;
                CCITTG4Encoder g4       = new CCITTG4Encoder(w);
                for (int k = 0; k < offset.Length; ++k)
                {
                    byte[] im = new byte[(int)size[k]];
                    s.Seek(offset[k]);
                    s.ReadFully(im);
                    int            height  = Math.Min(rowsStrip, rowsLeft);
                    TIFFFaxDecoder decoder = new TIFFFaxDecoder(fillOrder, w, height);
                    byte[]         outBuf  = new byte[(w + 7) / 8 * height];
                    switch (compression)
                    {
                    case TIFFConstants.COMPRESSION_CCITTRLEW:
                    case TIFFConstants.COMPRESSION_CCITTRLE:
                        decoder.Decode1D(outBuf, im, 0, height);
                        g4.Fax4Encode(outBuf, height);
                        break;

                    case TIFFConstants.COMPRESSION_CCITTFAX3:
                        try {
                            decoder.Decode2D(outBuf, im, 0, height, tiffT4Options);
                        }
                        catch (Exception e) {
                            // let's flip the fill bits and try again...
                            tiffT4Options ^= TIFFConstants.GROUP3OPT_FILLBITS;
                            try {
                                decoder.Decode2D(outBuf, im, 0, height, tiffT4Options);
                            }
                            catch {
                                throw e;
                            }
                        }
                        g4.Fax4Encode(outBuf, height);
                        break;

                    case TIFFConstants.COMPRESSION_CCITTFAX4:
                        decoder.DecodeT6(outBuf, im, 0, height, tiffT6Options);
                        g4.Fax4Encode(outBuf, height);
                        break;
                    }
                    rowsLeft -= rowsStrip;
                }
                byte[] g4pic = g4.Close();
                img = Image.GetInstance(w, h, false, Image.CCITTG4, paramsn & Image.CCITT_BLACKIS1, g4pic);
            }
            img.SetDpi(dpiX, dpiY);
            img.XYRatio = XYRatio;
            if (dir.IsTagPresent(TIFFConstants.TIFFTAG_ICCPROFILE))
            {
                try {
                    TIFFField   fd       = dir.GetField(TIFFConstants.TIFFTAG_ICCPROFILE);
                    ICC_Profile icc_prof = ICC_Profile.GetInstance(fd.GetAsBytes());
                    if (icc_prof.NumComponents == 1)
                    {
                        img.TagICC = icc_prof;
                    }
                }
                catch {
                    //empty
                }
            }
            img.OriginalType = Image.ORIGINAL_TIFF;
            if (rotation != 0)
            {
                img.InitialRotation = rotation;
            }
            return(img);
        }
Пример #2
0
        protected static Image GetTiffImageColor(TIFFDirectory dir, RandomAccessFileOrArray s)
        {
            int            predictor   = 1;
            TIFFLZWDecoder lzwDecoder  = null;
            int            compression = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_COMPRESSION);

            switch (compression)
            {
            case TIFFConstants.COMPRESSION_NONE:
            case TIFFConstants.COMPRESSION_LZW:
            case TIFFConstants.COMPRESSION_PACKBITS:
            case TIFFConstants.COMPRESSION_DEFLATE:
            case TIFFConstants.COMPRESSION_ADOBE_DEFLATE:
            case TIFFConstants.COMPRESSION_OJPEG:
            case TIFFConstants.COMPRESSION_JPEG:
                break;

            default:
                throw new ArgumentException("The compression " + compression + " is not supported.");
            }
            int photometric = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_PHOTOMETRIC);

            switch (photometric)
            {
            case TIFFConstants.PHOTOMETRIC_MINISWHITE:
            case TIFFConstants.PHOTOMETRIC_MINISBLACK:
            case TIFFConstants.PHOTOMETRIC_RGB:
            case TIFFConstants.PHOTOMETRIC_SEPARATED:
            case TIFFConstants.PHOTOMETRIC_PALETTE:
                break;

            default:
                if (compression != TIFFConstants.COMPRESSION_OJPEG && compression != TIFFConstants.COMPRESSION_JPEG)
                {
                    throw new ArgumentException("The photometric " + photometric + " is not supported.");
                }
                break;
            }
            float rotation = 0;

            if (dir.IsTagPresent(TIFFConstants.TIFFTAG_ORIENTATION))
            {
                int rot = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_ORIENTATION);
                if (rot == TIFFConstants.ORIENTATION_BOTRIGHT || rot == TIFFConstants.ORIENTATION_BOTLEFT)
                {
                    rotation = (float)Math.PI;
                }
                else if (rot == TIFFConstants.ORIENTATION_LEFTTOP || rot == TIFFConstants.ORIENTATION_LEFTBOT)
                {
                    rotation = (float)(Math.PI / 2.0);
                }
                else if (rot == TIFFConstants.ORIENTATION_RIGHTTOP || rot == TIFFConstants.ORIENTATION_RIGHTBOT)
                {
                    rotation = -(float)(Math.PI / 2.0);
                }
            }

            if (dir.IsTagPresent(TIFFConstants.TIFFTAG_PLANARCONFIG) &&
                dir.GetFieldAsLong(TIFFConstants.TIFFTAG_PLANARCONFIG) == TIFFConstants.PLANARCONFIG_SEPARATE)
            {
                throw new ArgumentException("Planar images are not supported.");
            }
            if (dir.IsTagPresent(TIFFConstants.TIFFTAG_EXTRASAMPLES))
            {
                throw new ArgumentException("Extra samples are not supported.");
            }
            int samplePerPixel = 1;

            if (dir.IsTagPresent(TIFFConstants.TIFFTAG_SAMPLESPERPIXEL)) // 1,3,4
            {
                samplePerPixel = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_SAMPLESPERPIXEL);
            }
            int bitsPerSample = 1;

            if (dir.IsTagPresent(TIFFConstants.TIFFTAG_BITSPERSAMPLE))
            {
                bitsPerSample = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_BITSPERSAMPLE);
            }
            switch (bitsPerSample)
            {
            case 1:
            case 2:
            case 4:
            case 8:
                break;

            default:
                throw new ArgumentException("Bits per sample " + bitsPerSample + " is not supported.");
            }
            Image img = null;

            int h              = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_IMAGELENGTH);
            int w              = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_IMAGEWIDTH);
            int dpiX           = 0;
            int dpiY           = 0;
            int resolutionUnit = TIFFConstants.RESUNIT_INCH;

            if (dir.IsTagPresent(TIFFConstants.TIFFTAG_RESOLUTIONUNIT))
            {
                resolutionUnit = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_RESOLUTIONUNIT);
            }
            dpiX = GetDpi(dir.GetField(TIFFConstants.TIFFTAG_XRESOLUTION), resolutionUnit);
            dpiY = GetDpi(dir.GetField(TIFFConstants.TIFFTAG_YRESOLUTION), resolutionUnit);
            int       fillOrder      = 1;
            bool      reverse        = false;
            TIFFField fillOrderField = dir.GetField(TIFFConstants.TIFFTAG_FILLORDER);

            if (fillOrderField != null)
            {
                fillOrder = fillOrderField.GetAsInt(0);
            }
            reverse = (fillOrder == TIFFConstants.FILLORDER_LSB2MSB);
            int rowsStrip = h;

            if (dir.IsTagPresent(TIFFConstants.TIFFTAG_ROWSPERSTRIP)) //another hack for broken tiffs
            {
                rowsStrip = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_ROWSPERSTRIP);
            }
            if (rowsStrip <= 0 || rowsStrip > h)
            {
                rowsStrip = h;
            }
            long[] offset = GetArrayLongShort(dir, TIFFConstants.TIFFTAG_STRIPOFFSETS);
            long[] size   = GetArrayLongShort(dir, TIFFConstants.TIFFTAG_STRIPBYTECOUNTS);
            if ((size == null || (size.Length == 1 && (size[0] == 0 || size[0] + offset[0] > s.Length))) && h == rowsStrip)   // some TIFF producers are really lousy, so...
            {
                size = new long[] { s.Length - (int)offset[0] };
            }
            if (compression == TIFFConstants.COMPRESSION_LZW)
            {
                TIFFField predictorField = dir.GetField(TIFFConstants.TIFFTAG_PREDICTOR);
                if (predictorField != null)
                {
                    predictor = predictorField.GetAsInt(0);
                    if (predictor != 1 && predictor != 2)
                    {
                        throw new Exception("Illegal value for Predictor in TIFF file.");
                    }
                    if (predictor == 2 && bitsPerSample != 8)
                    {
                        throw new Exception(bitsPerSample + "-bit samples are not supported for Horizontal differencing Predictor.");
                    }
                }
                lzwDecoder = new TIFFLZWDecoder(w, predictor,
                                                samplePerPixel);
            }
            int                   rowsLeft = h;
            MemoryStream          stream   = null;
            ZDeflaterOutputStream zip      = null;
            CCITTG4Encoder        g4       = null;

            if (bitsPerSample == 1 && samplePerPixel == 1)
            {
                g4 = new CCITTG4Encoder(w);
            }
            else
            {
                stream = new MemoryStream();
                if (compression != TIFFConstants.COMPRESSION_OJPEG && compression != TIFFConstants.COMPRESSION_JPEG)
                {
                    zip = new ZDeflaterOutputStream(stream);
                }
            }
            if (compression == TIFFConstants.COMPRESSION_OJPEG)
            {
                // Assume that the TIFFTAG_JPEGIFBYTECOUNT tag is optional, since it's obsolete and
                // is often missing

                if ((!dir.IsTagPresent(TIFFConstants.TIFFTAG_JPEGIFOFFSET)))
                {
                    throw new IOException("Missing tag(s) for OJPEG compression.");
                }
                int jpegOffset = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_JPEGIFOFFSET);
                int jpegLength = s.Length - jpegOffset;

                if (dir.IsTagPresent(TIFFConstants.TIFFTAG_JPEGIFBYTECOUNT))
                {
                    jpegLength = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_JPEGIFBYTECOUNT) +
                                 (int)size[0];
                }

                byte[] jpeg = new byte[Math.Min(jpegLength, s.Length - jpegOffset)];

                int posFilePointer = s.FilePointer;
                posFilePointer += jpegOffset;
                s.Seek(posFilePointer);
                s.ReadFully(jpeg);
                img = new Jpeg(jpeg);
            }
            else if (compression == TIFFConstants.COMPRESSION_JPEG)
            {
                if (size.Length > 1)
                {
                    throw new IOException("Compression JPEG is only supported with a single strip. This image has " + size.Length + " strips.");
                }
                byte[] jpeg = new byte[(int)size[0]];
                s.Seek(offset[0]);
                s.ReadFully(jpeg);
                img = new Jpeg(jpeg);
            }
            else
            {
                for (int k = 0; k < offset.Length; ++k)
                {
                    byte[] im = new byte[(int)size[k]];
                    s.Seek(offset[k]);
                    s.ReadFully(im);
                    int    height = Math.Min(rowsStrip, rowsLeft);
                    byte[] outBuf = null;
                    if (compression != TIFFConstants.COMPRESSION_NONE)
                    {
                        outBuf = new byte[(w * bitsPerSample * samplePerPixel + 7) / 8 * height];
                    }
                    if (reverse)
                    {
                        TIFFFaxDecoder.ReverseBits(im);
                    }
                    switch (compression)
                    {
                    case TIFFConstants.COMPRESSION_DEFLATE:
                    case TIFFConstants.COMPRESSION_ADOBE_DEFLATE:
                        Inflate(im, outBuf);
                        break;

                    case TIFFConstants.COMPRESSION_NONE:
                        outBuf = im;
                        break;

                    case TIFFConstants.COMPRESSION_PACKBITS:
                        DecodePackbits(im, outBuf);
                        break;

                    case TIFFConstants.COMPRESSION_LZW:
                        lzwDecoder.Decode(im, outBuf, height);
                        break;
                    }
                    if (bitsPerSample == 1 && samplePerPixel == 1)
                    {
                        g4.Fax4Encode(outBuf, height);
                    }
                    else
                    {
                        zip.Write(outBuf, 0, outBuf.Length);
                    }
                    rowsLeft -= rowsStrip;
                }
                if (bitsPerSample == 1 && samplePerPixel == 1)
                {
                    img = Image.GetInstance(w, h, false, Image.CCITTG4,
                                            photometric == TIFFConstants.PHOTOMETRIC_MINISBLACK ? Image.CCITT_BLACKIS1 : 0, g4.Close());
                }
                else
                {
                    zip.Close();
                    img          = Image.GetInstance(w, h, samplePerPixel, bitsPerSample, stream.ToArray());
                    img.Deflated = true;
                }
            }
            img.SetDpi(dpiX, dpiY);
            if (compression != TIFFConstants.COMPRESSION_OJPEG && compression != TIFFConstants.COMPRESSION_JPEG)
            {
                if (dir.IsTagPresent(TIFFConstants.TIFFTAG_ICCPROFILE))
                {
                    try {
                        TIFFField   fd       = dir.GetField(TIFFConstants.TIFFTAG_ICCPROFILE);
                        ICC_Profile icc_prof = ICC_Profile.GetInstance(fd.GetAsBytes());
                        if (samplePerPixel == icc_prof.NumComponents)
                        {
                            img.TagICC = icc_prof;
                        }
                    }
                    catch {
                        //empty
                    }
                }
                if (dir.IsTagPresent(TIFFConstants.TIFFTAG_COLORMAP))
                {
                    TIFFField fd      = dir.GetField(TIFFConstants.TIFFTAG_COLORMAP);
                    char[]    rgb     = fd.GetAsChars();
                    byte[]    palette = new byte[rgb.Length];
                    int       gColor  = rgb.Length / 3;
                    int       bColor  = gColor * 2;
                    for (int k = 0; k < gColor; ++k)
                    {
                        palette[k * 3]     = (byte)(rgb[k] >> 8);
                        palette[k * 3 + 1] = (byte)(rgb[k + gColor] >> 8);
                        palette[k * 3 + 2] = (byte)(rgb[k + bColor] >> 8);
                    }
                    PdfArray indexed = new PdfArray();
                    indexed.Add(PdfName.INDEXED);
                    indexed.Add(PdfName.DEVICERGB);
                    indexed.Add(new PdfNumber(gColor - 1));
                    indexed.Add(new PdfString(palette));
                    PdfDictionary additional = new PdfDictionary();
                    additional.Put(PdfName.COLORSPACE, indexed);
                    img.Additional = additional;
                }
                img.OriginalType = Image.ORIGINAL_TIFF;
            }
            if (photometric == TIFFConstants.PHOTOMETRIC_MINISWHITE)
            {
                img.Inverted = true;
            }
            if (rotation != 0)
            {
                img.InitialRotation = rotation;
            }
            return(img);
        }
Пример #3
0
        protected static Image GetTiffImageColor(TIFFDirectory dir, RandomAccessFileOrArray s)
        {
            int            predictor   = 1;
            TIFFLZWDecoder lzwDecoder  = null;
            int            compression = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_COMPRESSION);

            switch (compression)
            {
            case TIFFConstants.COMPRESSION_NONE:
            case TIFFConstants.COMPRESSION_LZW:
            case TIFFConstants.COMPRESSION_PACKBITS:
            case TIFFConstants.COMPRESSION_DEFLATE:
            case TIFFConstants.COMPRESSION_ADOBE_DEFLATE:
            case TIFFConstants.COMPRESSION_OJPEG:
            case TIFFConstants.COMPRESSION_JPEG:
                break;

            default:
                throw new ArgumentException(MessageLocalization.GetComposedMessage("the.compression.1.is.not.supported", compression));
            }
            int photometric = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_PHOTOMETRIC);

            switch (photometric)
            {
            case TIFFConstants.PHOTOMETRIC_MINISWHITE:
            case TIFFConstants.PHOTOMETRIC_MINISBLACK:
            case TIFFConstants.PHOTOMETRIC_RGB:
            case TIFFConstants.PHOTOMETRIC_SEPARATED:
            case TIFFConstants.PHOTOMETRIC_PALETTE:
                break;

            default:
                if (compression != TIFFConstants.COMPRESSION_OJPEG && compression != TIFFConstants.COMPRESSION_JPEG)
                {
                    throw new ArgumentException(MessageLocalization.GetComposedMessage("the.photometric.1.is.not.supported", photometric));
                }
                break;
            }
            float rotation = 0;

            if (dir.IsTagPresent(TIFFConstants.TIFFTAG_ORIENTATION))
            {
                int rot = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_ORIENTATION);
                if (rot == TIFFConstants.ORIENTATION_BOTRIGHT || rot == TIFFConstants.ORIENTATION_BOTLEFT)
                {
                    rotation = (float)Math.PI;
                }
                else if (rot == TIFFConstants.ORIENTATION_LEFTTOP || rot == TIFFConstants.ORIENTATION_LEFTBOT)
                {
                    rotation = (float)(Math.PI / 2.0);
                }
                else if (rot == TIFFConstants.ORIENTATION_RIGHTTOP || rot == TIFFConstants.ORIENTATION_RIGHTBOT)
                {
                    rotation = -(float)(Math.PI / 2.0);
                }
            }

            if (dir.IsTagPresent(TIFFConstants.TIFFTAG_PLANARCONFIG) &&
                dir.GetFieldAsLong(TIFFConstants.TIFFTAG_PLANARCONFIG) == TIFFConstants.PLANARCONFIG_SEPARATE)
            {
                throw new ArgumentException(MessageLocalization.GetComposedMessage("planar.images.are.not.supported"));
            }
            int extraSamples = 0;

            if (dir.IsTagPresent(TIFFConstants.TIFFTAG_EXTRASAMPLES))
            {
                extraSamples = 1;
            }
            int samplePerPixel = 1;

            if (dir.IsTagPresent(TIFFConstants.TIFFTAG_SAMPLESPERPIXEL)) // 1,3,4
            {
                samplePerPixel = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_SAMPLESPERPIXEL);
            }
            int bitsPerSample = 1;

            if (dir.IsTagPresent(TIFFConstants.TIFFTAG_BITSPERSAMPLE))
            {
                bitsPerSample = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_BITSPERSAMPLE);
            }
            switch (bitsPerSample)
            {
            case 1:
            case 2:
            case 4:
            case 8:
                break;

            default:
                throw new ArgumentException(MessageLocalization.GetComposedMessage("bits.per.sample.1.is.not.supported", bitsPerSample));
            }
            Image img = null;

            int h              = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_IMAGELENGTH);
            int w              = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_IMAGEWIDTH);
            int dpiX           = 0;
            int dpiY           = 0;
            int resolutionUnit = TIFFConstants.RESUNIT_INCH;

            if (dir.IsTagPresent(TIFFConstants.TIFFTAG_RESOLUTIONUNIT))
            {
                resolutionUnit = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_RESOLUTIONUNIT);
            }
            dpiX = GetDpi(dir.GetField(TIFFConstants.TIFFTAG_XRESOLUTION), resolutionUnit);
            dpiY = GetDpi(dir.GetField(TIFFConstants.TIFFTAG_YRESOLUTION), resolutionUnit);
            int       fillOrder      = 1;
            bool      reverse        = false;
            TIFFField fillOrderField = dir.GetField(TIFFConstants.TIFFTAG_FILLORDER);

            if (fillOrderField != null)
            {
                fillOrder = fillOrderField.GetAsInt(0);
            }
            reverse = (fillOrder == TIFFConstants.FILLORDER_LSB2MSB);
            int rowsStrip = h;

            if (dir.IsTagPresent(TIFFConstants.TIFFTAG_ROWSPERSTRIP)) //another hack for broken tiffs
            {
                rowsStrip = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_ROWSPERSTRIP);
            }
            if (rowsStrip <= 0 || rowsStrip > h)
            {
                rowsStrip = h;
            }
            long[] offset = GetArrayLongShort(dir, TIFFConstants.TIFFTAG_STRIPOFFSETS);
            long[] size   = GetArrayLongShort(dir, TIFFConstants.TIFFTAG_STRIPBYTECOUNTS);
            if ((size == null || (size.Length == 1 && (size[0] == 0 || size[0] + offset[0] > s.Length))) && h == rowsStrip)   // some TIFF producers are really lousy, so...
            {
                size = new long[] { s.Length - (int)offset[0] };
            }
            if (compression == TIFFConstants.COMPRESSION_LZW || compression == TIFFConstants.COMPRESSION_DEFLATE || compression == TIFFConstants.COMPRESSION_ADOBE_DEFLATE)
            {
                TIFFField predictorField = dir.GetField(TIFFConstants.TIFFTAG_PREDICTOR);
                if (predictorField != null)
                {
                    predictor = predictorField.GetAsInt(0);
                    if (predictor != 1 && predictor != 2)
                    {
                        throw new Exception(MessageLocalization.GetComposedMessage("illegal.value.for.predictor.in.tiff.file"));
                    }
                    if (predictor == 2 && bitsPerSample != 8)
                    {
                        throw new Exception(MessageLocalization.GetComposedMessage("1.bit.samples.are.not.supported.for.horizontal.differencing.predictor", bitsPerSample));
                    }
                }
            }
            if (compression == TIFFConstants.COMPRESSION_LZW)
            {
                lzwDecoder = new TIFFLZWDecoder(w, predictor, samplePerPixel);
            }
            int                   rowsLeft = h;
            MemoryStream          stream   = null;
            MemoryStream          mstream  = null;
            ZDeflaterOutputStream zip      = null;
            ZDeflaterOutputStream mzip     = null;

            if (extraSamples > 0)
            {
                mstream = new MemoryStream();
                mzip    = new ZDeflaterOutputStream(mstream);
            }

            CCITTG4Encoder g4 = null;

            if (bitsPerSample == 1 && samplePerPixel == 1 && photometric != TIFFConstants.PHOTOMETRIC_PALETTE)
            {
                g4 = new CCITTG4Encoder(w);
            }
            else
            {
                stream = new MemoryStream();
                if (compression != TIFFConstants.COMPRESSION_OJPEG && compression != TIFFConstants.COMPRESSION_JPEG)
                {
                    zip = new ZDeflaterOutputStream(stream);
                }
            }
            if (compression == TIFFConstants.COMPRESSION_OJPEG)
            {
                // Assume that the TIFFTAG_JPEGIFBYTECOUNT tag is optional, since it's obsolete and
                // is often missing

                if ((!dir.IsTagPresent(TIFFConstants.TIFFTAG_JPEGIFOFFSET)))
                {
                    throw new IOException(MessageLocalization.GetComposedMessage("missing.tag.s.for.ojpeg.compression"));
                }
                int jpegOffset = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_JPEGIFOFFSET);
                int jpegLength = (int)s.Length - jpegOffset;

                if (dir.IsTagPresent(TIFFConstants.TIFFTAG_JPEGIFBYTECOUNT))
                {
                    jpegLength = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_JPEGIFBYTECOUNT) +
                                 (int)size[0];
                }

                byte[] jpeg = new byte[Math.Min(jpegLength, s.Length - jpegOffset)];

                int posFilePointer = (int)s.FilePointer;
                posFilePointer += jpegOffset;
                s.Seek(posFilePointer);
                s.ReadFully(jpeg);
                // if quantization and/or Huffman tables are stored separately in the tiff,
                // we need to add them to the jpeg data
                TIFFField jpegtables = dir.GetField(TIFFConstants.TIFFTAG_JPEGTABLES);
                if (jpegtables != null)
                {
                    byte[] temp        = jpegtables.GetAsBytes();
                    int    tableoffset = 0;
                    int    tablelength = temp.Length;
                    // remove FFD8 from start
                    if (temp[0] == (byte)0xFF && temp[1] == (byte)0xD8)
                    {
                        tableoffset  = 2;
                        tablelength -= 2;
                    }
                    // remove FFD9 from end
                    if (temp[temp.Length - 2] == (byte)0xFF && temp[temp.Length - 1] == (byte)0xD9)
                    {
                        tablelength -= 2;
                    }
                    byte[] tables = new byte[tablelength];
                    Array.Copy(temp, tableoffset, tables, 0, tablelength);
                    // TODO insert after JFIF header, instead of at the start
                    byte[] jpegwithtables = new byte[jpeg.Length + tables.Length];
                    Array.Copy(jpeg, 0, jpegwithtables, 0, 2);
                    Array.Copy(tables, 0, jpegwithtables, 2, tables.Length);
                    Array.Copy(jpeg, 2, jpegwithtables, tables.Length + 2, jpeg.Length - 2);
                    jpeg = jpegwithtables;
                }
                img = new Jpeg(jpeg);
            }
            else if (compression == TIFFConstants.COMPRESSION_JPEG)
            {
                if (size.Length > 1)
                {
                    throw new IOException(MessageLocalization.GetComposedMessage("compression.jpeg.is.only.supported.with.a.single.strip.this.image.has.1.strips", size.Length));
                }
                byte[] jpeg = new byte[(int)size[0]];
                s.Seek(offset[0]);
                s.ReadFully(jpeg);
                img = new Jpeg(jpeg);
                if (photometric == TIFFConstants.PHOTOMETRIC_RGB)
                {
                    img.ColorTransform = 0;
                }
            }
            else
            {
                for (int k = 0; k < offset.Length; ++k)
                {
                    byte[] im = new byte[(int)size[k]];
                    s.Seek(offset[k]);
                    s.ReadFully(im);
                    int    height = Math.Min(rowsStrip, rowsLeft);
                    byte[] outBuf = null;
                    if (compression != TIFFConstants.COMPRESSION_NONE)
                    {
                        outBuf = new byte[(w * bitsPerSample * samplePerPixel + 7) / 8 * height];
                    }
                    if (reverse)
                    {
                        TIFFFaxDecoder.ReverseBits(im);
                    }
                    switch (compression)
                    {
                    case TIFFConstants.COMPRESSION_DEFLATE:
                    case TIFFConstants.COMPRESSION_ADOBE_DEFLATE:
                        Inflate(im, outBuf);
                        ApplyPredictor(outBuf, predictor, w, height, samplePerPixel);
                        break;

                    case TIFFConstants.COMPRESSION_NONE:
                        outBuf = im;
                        break;

                    case TIFFConstants.COMPRESSION_PACKBITS:
                        DecodePackbits(im, outBuf);
                        break;

                    case TIFFConstants.COMPRESSION_LZW:
                        lzwDecoder.Decode(im, outBuf, height);
                        break;
                    }
                    if (bitsPerSample == 1 && samplePerPixel == 1 && photometric != TIFFConstants.PHOTOMETRIC_PALETTE)
                    {
                        g4.Fax4Encode(outBuf, height);
                    }
                    else
                    {
                        if (extraSamples > 0)
                        {
                            ProcessExtraSamples(zip, mzip, outBuf, samplePerPixel, bitsPerSample, w, height);
                        }
                        else
                        {
                            zip.Write(outBuf, 0, outBuf.Length);
                        }
                    }
                    rowsLeft -= rowsStrip;
                }
                if (bitsPerSample == 1 && samplePerPixel == 1 && photometric != TIFFConstants.PHOTOMETRIC_PALETTE)
                {
                    img = Image.GetInstance(w, h, false, Image.CCITTG4,
                                            photometric == TIFFConstants.PHOTOMETRIC_MINISBLACK ? Image.CCITT_BLACKIS1 : 0, g4.Close());
                }
                else
                {
                    zip.Close();
                    img          = new ImgRaw(w, h, samplePerPixel - extraSamples, bitsPerSample, stream.ToArray());
                    img.Deflated = true;
                }
            }
            img.SetDpi(dpiX, dpiY);
            if (compression != TIFFConstants.COMPRESSION_OJPEG && compression != TIFFConstants.COMPRESSION_JPEG)
            {
                if (dir.IsTagPresent(TIFFConstants.TIFFTAG_ICCPROFILE))
                {
                    try {
                        TIFFField   fd       = dir.GetField(TIFFConstants.TIFFTAG_ICCPROFILE);
                        ICC_Profile icc_prof = ICC_Profile.GetInstance(fd.GetAsBytes());
                        if (samplePerPixel - extraSamples == icc_prof.NumComponents)
                        {
                            img.TagICC = icc_prof;
                        }
                    }
                    catch {
                        //empty
                    }
                }
                if (dir.IsTagPresent(TIFFConstants.TIFFTAG_COLORMAP))
                {
                    TIFFField fd      = dir.GetField(TIFFConstants.TIFFTAG_COLORMAP);
                    char[]    rgb     = fd.GetAsChars();
                    byte[]    palette = new byte[rgb.Length];
                    int       gColor  = rgb.Length / 3;
                    int       bColor  = gColor * 2;
                    for (int k = 0; k < gColor; ++k)
                    {
                        palette[k * 3]     = (byte)(rgb[k] >> 8);
                        palette[k * 3 + 1] = (byte)(rgb[k + gColor] >> 8);
                        palette[k * 3 + 2] = (byte)(rgb[k + bColor] >> 8);
                    }
                    // Colormap components are supposed to go from 0 to 655535 but,
                    // as usually, some tiff producers just put values from 0 to 255.
                    // Let's check for these broken tiffs.
                    bool colormapBroken = true;
                    for (int k = 0; k < palette.Length; ++k)
                    {
                        if (palette[k] != 0)
                        {
                            colormapBroken = false;
                            break;
                        }
                    }
                    if (colormapBroken)
                    {
                        for (int k = 0; k < gColor; ++k)
                        {
                            palette[k * 3]     = (byte)rgb[k];
                            palette[k * 3 + 1] = (byte)rgb[k + gColor];
                            palette[k * 3 + 2] = (byte)rgb[k + bColor];
                        }
                    }
                    PdfArray indexed = new PdfArray();
                    indexed.Add(PdfName.INDEXED);
                    indexed.Add(PdfName.DEVICERGB);
                    indexed.Add(new PdfNumber(gColor - 1));
                    indexed.Add(new PdfString(palette));
                    PdfDictionary additional = new PdfDictionary();
                    additional.Put(PdfName.COLORSPACE, indexed);
                    img.Additional = additional;
                }
                img.OriginalType = Image.ORIGINAL_TIFF;
            }
            if (photometric == TIFFConstants.PHOTOMETRIC_MINISWHITE)
            {
                img.Inverted = true;
            }
            if (rotation != 0)
            {
                img.InitialRotation = rotation;
            }
            if (extraSamples > 0)
            {
                mzip.Close();
                Image mimg = Image.GetInstance(w, h, 1, bitsPerSample, mstream.ToArray());
                mimg.MakeMask();
                mimg.Deflated = true;
                img.ImageMask = mimg;
            }
            return(img);
        }
Пример #4
0
        /// <exception cref="System.IO.IOException"/>
        protected internal virtual void AssembleFont()
        {
            int[]          tableLocation;
            int            fullFontSize = 0;
            IList <String> tableNames   = new List <String>();

            tableNames.AddAll(tableNamesSimple);
            if (includeExtras)
            {
                tableNames.AddAll(tableNamesExtra);
            }
            else
            {
                if (includeCmap)
                {
                    tableNames.AddAll(tableNamesCmap);
                }
            }
            int tablesUsed = 2;

            foreach (String name in tableNames)
            {
                if (name.Equals("glyf") || name.Equals("loca"))
                {
                    continue;
                }
                tableLocation = tableDirectory.Get(name);
                if (tableLocation == null)
                {
                    continue;
                }
                tablesUsed++;
                fullFontSize += tableLocation[TABLE_LENGTH] + 3 & ~3;
            }
            fullFontSize += newLocaTableOut.Length;
            fullFontSize += newGlyfTable.Length;
            int reference = 16 * tablesUsed + 12;

            fullFontSize += reference;
            outFont       = new byte[fullFontSize];
            fontPtr       = 0;
            WriteFontInt(0x00010000);
            WriteFontShort(tablesUsed);
            int selector = entrySelectors[tablesUsed];

            WriteFontShort((1 << selector) * 16);
            WriteFontShort(selector);
            WriteFontShort((tablesUsed - (1 << selector)) * 16);
            foreach (String name in tableNames)
            {
                int len;
                tableLocation = tableDirectory.Get(name);
                if (tableLocation == null)
                {
                    continue;
                }
                WriteFontString(name);
                switch (name)
                {
                case "glyf": {
                    WriteFontInt(CalculateChecksum(newGlyfTable));
                    len = glyfTableRealSize;
                    break;
                }

                case "loca": {
                    WriteFontInt(CalculateChecksum(newLocaTableOut));
                    len = locaTableRealSize;
                    break;
                }

                default: {
                    WriteFontInt(tableLocation[TABLE_CHECKSUM]);
                    len = tableLocation[TABLE_LENGTH];
                    break;
                }
                }
                WriteFontInt(reference);
                WriteFontInt(len);
                reference += len + 3 & ~3;
            }
            foreach (String name in tableNames)
            {
                tableLocation = tableDirectory.Get(name);
                if (tableLocation == null)
                {
                    continue;
                }
                switch (name)
                {
                case "glyf": {
                    Array.Copy(newGlyfTable, 0, outFont, fontPtr, newGlyfTable.Length);
                    fontPtr     += newGlyfTable.Length;
                    newGlyfTable = null;
                    break;
                }

                case "loca": {
                    Array.Copy(newLocaTableOut, 0, outFont, fontPtr, newLocaTableOut.Length);
                    fontPtr        += newLocaTableOut.Length;
                    newLocaTableOut = null;
                    break;
                }

                default: {
                    rf.Seek(tableLocation[TABLE_OFFSET]);
                    rf.ReadFully(outFont, fontPtr, tableLocation[TABLE_LENGTH]);
                    fontPtr += tableLocation[TABLE_LENGTH] + 3 & ~3;
                    break;
                }
                }
            }
        }
Пример #5
0
        /** Reads a page from a TIFF image.
        * @param s the file source
        * @param page the page to get. The first page is 1
        * @param direct for single strip, CCITT images, generate the image
        * by direct byte copying. It's faster but may not work
        * every time
        * @return the <CODE>Image</CODE>
        */
        public static Image GetTiffImage(RandomAccessFileOrArray s, int page, bool direct)
        {
            if (page < 1)
                throw new ArgumentException("The page number must be >= 1.");
            TIFFDirectory dir = new TIFFDirectory(s, page - 1);
            if (dir.IsTagPresent(TIFFConstants.TIFFTAG_TILEWIDTH))
                throw new ArgumentException("Tiles are not supported.");
            int compression = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_COMPRESSION);
            switch (compression) {
                case TIFFConstants.COMPRESSION_CCITTRLEW:
                case TIFFConstants.COMPRESSION_CCITTRLE:
                case TIFFConstants.COMPRESSION_CCITTFAX3:
                case TIFFConstants.COMPRESSION_CCITTFAX4:
                    break;
                default:
                    return GetTiffImageColor(dir, s);
            }
            float rotation = 0;
            if (dir.IsTagPresent(TIFFConstants.TIFFTAG_ORIENTATION)) {
                int rot = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_ORIENTATION);
                if (rot == TIFFConstants.ORIENTATION_BOTRIGHT || rot == TIFFConstants.ORIENTATION_BOTLEFT)
                    rotation = (float)Math.PI;
                else if (rot == TIFFConstants.ORIENTATION_LEFTTOP || rot == TIFFConstants.ORIENTATION_LEFTBOT)
                    rotation = (float)(Math.PI / 2.0);
                else if (rot == TIFFConstants.ORIENTATION_RIGHTTOP || rot == TIFFConstants.ORIENTATION_RIGHTBOT)
                    rotation = -(float)(Math.PI / 2.0);
            }

            Image img = null;
            long tiffT4Options = 0;
            long tiffT6Options = 0;
            int fillOrder = 1;
            int h = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_IMAGELENGTH);
            int w = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_IMAGEWIDTH);
            int dpiX = 0;
            int dpiY = 0;
            float XYRatio = 0;
            int resolutionUnit = TIFFConstants.RESUNIT_INCH;
            if (dir.IsTagPresent(TIFFConstants.TIFFTAG_RESOLUTIONUNIT))
                resolutionUnit = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_RESOLUTIONUNIT);
            dpiX = GetDpi(dir.GetField(TIFFConstants.TIFFTAG_XRESOLUTION), resolutionUnit);
            dpiY = GetDpi(dir.GetField(TIFFConstants.TIFFTAG_YRESOLUTION), resolutionUnit);
            if (resolutionUnit == TIFFConstants.RESUNIT_NONE) {
                if (dpiY != 0)
                    XYRatio = (float)dpiX / (float)dpiY;
                dpiX = 0;
                dpiY = 0;
            }
            int rowsStrip = h;
            if (dir.IsTagPresent(TIFFConstants.TIFFTAG_ROWSPERSTRIP))
                rowsStrip = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_ROWSPERSTRIP);
            if (rowsStrip <= 0 || rowsStrip > h)
                rowsStrip = h;
            long[] offset = GetArrayLongShort(dir, TIFFConstants.TIFFTAG_STRIPOFFSETS);
            long[] size = GetArrayLongShort(dir, TIFFConstants.TIFFTAG_STRIPBYTECOUNTS);
            if ((size == null || (size.Length == 1 && (size[0] == 0 || size[0] + offset[0] > s.Length))) && h == rowsStrip) { // some TIFF producers are really lousy, so...
                size = new long[]{s.Length - (int)offset[0]};
            }
            bool reverse = false;
            TIFFField fillOrderField =  dir.GetField(TIFFConstants.TIFFTAG_FILLORDER);
            if (fillOrderField != null)
                fillOrder = fillOrderField.GetAsInt(0);
            reverse = (fillOrder == TIFFConstants.FILLORDER_LSB2MSB);
            int paramsn = 0;
            if (dir.IsTagPresent(TIFFConstants.TIFFTAG_PHOTOMETRIC)) {
                long photo = dir.GetFieldAsLong(TIFFConstants.TIFFTAG_PHOTOMETRIC);
                if (photo == TIFFConstants.PHOTOMETRIC_MINISBLACK)
                    paramsn |= Image.CCITT_BLACKIS1;
            }
            int imagecomp = 0;
            switch (compression) {
                case TIFFConstants.COMPRESSION_CCITTRLEW:
                case TIFFConstants.COMPRESSION_CCITTRLE:
                    imagecomp = Image.CCITTG3_1D;
                    paramsn |= Image.CCITT_ENCODEDBYTEALIGN | Image.CCITT_ENDOFBLOCK;
                    break;
                case TIFFConstants.COMPRESSION_CCITTFAX3:
                    imagecomp = Image.CCITTG3_1D;
                    paramsn |= Image.CCITT_ENDOFLINE | Image.CCITT_ENDOFBLOCK;
                    TIFFField t4OptionsField = dir.GetField(TIFFConstants.TIFFTAG_GROUP3OPTIONS);
                    if (t4OptionsField != null) {
                        tiffT4Options = t4OptionsField.GetAsLong(0);
                    if ((tiffT4Options & TIFFConstants.GROUP3OPT_2DENCODING) != 0)
                        imagecomp = Image.CCITTG3_2D;
                    if ((tiffT4Options & TIFFConstants.GROUP3OPT_FILLBITS) != 0)
                        paramsn |= Image.CCITT_ENCODEDBYTEALIGN;
                    }
                    break;
                case TIFFConstants.COMPRESSION_CCITTFAX4:
                    imagecomp = Image.CCITTG4;
                    TIFFField t6OptionsField = dir.GetField(TIFFConstants.TIFFTAG_GROUP4OPTIONS);
                    if (t6OptionsField != null)
                        tiffT6Options = t6OptionsField.GetAsLong(0);
                    break;
            }
            if (direct && rowsStrip == h) { //single strip, direct
                byte[] im = new byte[(int)size[0]];
                s.Seek(offset[0]);
                s.ReadFully(im);
                img = Image.GetInstance(w, h, false, imagecomp, paramsn, im);
                img.Inverted = true;
            }
            else {
                int rowsLeft = h;
                CCITTG4Encoder g4 = new CCITTG4Encoder(w);
                for (int k = 0; k < offset.Length; ++k) {
                    byte[] im = new byte[(int)size[k]];
                    s.Seek(offset[k]);
                    s.ReadFully(im);
                    int height = Math.Min(rowsStrip, rowsLeft);
                    TIFFFaxDecoder decoder = new TIFFFaxDecoder(fillOrder, w, height);
                    byte[] outBuf = new byte[(w + 7) / 8 * height];
                    switch (compression) {
                        case TIFFConstants.COMPRESSION_CCITTRLEW:
                        case TIFFConstants.COMPRESSION_CCITTRLE:
                            decoder.Decode1D(outBuf, im, 0, height);
                            g4.Fax4Encode(outBuf, height);
                            break;
                        case TIFFConstants.COMPRESSION_CCITTFAX3:
                            try {
                                decoder.Decode2D(outBuf, im, 0, height, tiffT4Options);
                            }
                            catch (Exception e) {
                                // let's flip the fill bits and try again...
                                tiffT4Options ^= TIFFConstants.GROUP3OPT_FILLBITS;
                                try {
                                    decoder.Decode2D(outBuf, im, 0, height, tiffT4Options);
                                }
                                catch {
                                    throw e;
                                }
                            }
                            g4.Fax4Encode(outBuf, height);
                            break;
                        case TIFFConstants.COMPRESSION_CCITTFAX4:
                            decoder.DecodeT6(outBuf, im, 0, height, tiffT6Options);
                            g4.Fax4Encode(outBuf, height);
                            break;
                    }
                    rowsLeft -= rowsStrip;
                }
                byte[] g4pic = g4.Close();
                img = Image.GetInstance(w, h, false, Image.CCITTG4, paramsn & Image.CCITT_BLACKIS1, g4pic);
            }
            img.SetDpi(dpiX, dpiY);
            img.XYRatio = XYRatio;
            if (dir.IsTagPresent(TIFFConstants.TIFFTAG_ICCPROFILE)) {
                try {
                    TIFFField fd = dir.GetField(TIFFConstants.TIFFTAG_ICCPROFILE);
                    ICC_Profile icc_prof = ICC_Profile.GetInstance(fd.GetAsBytes());
                    if (icc_prof.NumComponents == 1)
                        img.TagICC = icc_prof;
                }
                catch {
                    //empty
                }
            }
            img.OriginalType = Image.ORIGINAL_TIFF;
            if (rotation != 0)
                img.InitialRotation = rotation;
            return img;
        }
Пример #6
0
        protected static Image GetTiffImageColor(TIFFDirectory dir, RandomAccessFileOrArray s)
        {
            int predictor = 1;
            TIFFLZWDecoder lzwDecoder = null;
            int compression = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_COMPRESSION);
            switch (compression) {
                case TIFFConstants.COMPRESSION_NONE:
                case TIFFConstants.COMPRESSION_LZW:
                case TIFFConstants.COMPRESSION_PACKBITS:
                case TIFFConstants.COMPRESSION_DEFLATE:
                case TIFFConstants.COMPRESSION_ADOBE_DEFLATE:
                case TIFFConstants.COMPRESSION_OJPEG:
                case TIFFConstants.COMPRESSION_JPEG:
                    break;
                default:
                    throw new ArgumentException("The compression " + compression + " is not supported.");
            }
            int photometric = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_PHOTOMETRIC);
            switch (photometric) {
                case TIFFConstants.PHOTOMETRIC_MINISWHITE:
                case TIFFConstants.PHOTOMETRIC_MINISBLACK:
                case TIFFConstants.PHOTOMETRIC_RGB:
                case TIFFConstants.PHOTOMETRIC_SEPARATED:
                case TIFFConstants.PHOTOMETRIC_PALETTE:
                    break;
                default:
                    if (compression != TIFFConstants.COMPRESSION_OJPEG && compression != TIFFConstants.COMPRESSION_JPEG)
                        throw new ArgumentException("The photometric " + photometric + " is not supported.");
                    break;
            }
            float rotation = 0;
            if (dir.IsTagPresent(TIFFConstants.TIFFTAG_ORIENTATION)) {
                int rot = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_ORIENTATION);
                if (rot == TIFFConstants.ORIENTATION_BOTRIGHT || rot == TIFFConstants.ORIENTATION_BOTLEFT)
                    rotation = (float)Math.PI;
                else if (rot == TIFFConstants.ORIENTATION_LEFTTOP || rot == TIFFConstants.ORIENTATION_LEFTBOT)
                    rotation = (float)(Math.PI / 2.0);
                else if (rot == TIFFConstants.ORIENTATION_RIGHTTOP || rot == TIFFConstants.ORIENTATION_RIGHTBOT)
                    rotation = -(float)(Math.PI / 2.0);
            }

            if (dir.IsTagPresent(TIFFConstants.TIFFTAG_PLANARCONFIG)
                && dir.GetFieldAsLong(TIFFConstants.TIFFTAG_PLANARCONFIG) == TIFFConstants.PLANARCONFIG_SEPARATE)
                throw new ArgumentException("Planar images are not supported.");
            if (dir.IsTagPresent(TIFFConstants.TIFFTAG_EXTRASAMPLES))
                throw new ArgumentException("Extra samples are not supported.");
            int samplePerPixel = 1;
            if (dir.IsTagPresent(TIFFConstants.TIFFTAG_SAMPLESPERPIXEL)) // 1,3,4
                samplePerPixel = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_SAMPLESPERPIXEL);
            int bitsPerSample = 1;
            if (dir.IsTagPresent(TIFFConstants.TIFFTAG_BITSPERSAMPLE))
                bitsPerSample = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_BITSPERSAMPLE);
            switch (bitsPerSample) {
                case 1:
                case 2:
                case 4:
                case 8:
                    break;
                default:
                    throw new ArgumentException("Bits per sample " + bitsPerSample + " is not supported.");
            }
            Image img = null;

            int h = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_IMAGELENGTH);
            int w = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_IMAGEWIDTH);
            int dpiX = 0;
            int dpiY = 0;
            int resolutionUnit = TIFFConstants.RESUNIT_INCH;
            if (dir.IsTagPresent(TIFFConstants.TIFFTAG_RESOLUTIONUNIT))
                resolutionUnit = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_RESOLUTIONUNIT);
            dpiX = GetDpi(dir.GetField(TIFFConstants.TIFFTAG_XRESOLUTION), resolutionUnit);
            dpiY = GetDpi(dir.GetField(TIFFConstants.TIFFTAG_YRESOLUTION), resolutionUnit);
            int fillOrder = 1;
            bool reverse = false;
            TIFFField fillOrderField =  dir.GetField(TIFFConstants.TIFFTAG_FILLORDER);
            if (fillOrderField != null)
                fillOrder = fillOrderField.GetAsInt(0);
            reverse = (fillOrder == TIFFConstants.FILLORDER_LSB2MSB);
            int rowsStrip = h;
            if (dir.IsTagPresent(TIFFConstants.TIFFTAG_ROWSPERSTRIP)) //another hack for broken tiffs
                rowsStrip = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_ROWSPERSTRIP);
            if (rowsStrip <= 0 || rowsStrip > h)
                rowsStrip = h;
            long[] offset = GetArrayLongShort(dir, TIFFConstants.TIFFTAG_STRIPOFFSETS);
            long[] size = GetArrayLongShort(dir, TIFFConstants.TIFFTAG_STRIPBYTECOUNTS);
            if ((size == null || (size.Length == 1 && (size[0] == 0 || size[0] + offset[0] > s.Length))) && h == rowsStrip) { // some TIFF producers are really lousy, so...
                size = new long[]{s.Length - (int)offset[0]};
            }
            if (compression == TIFFConstants.COMPRESSION_LZW) {
                TIFFField predictorField = dir.GetField(TIFFConstants.TIFFTAG_PREDICTOR);
                if (predictorField != null) {
                    predictor = predictorField.GetAsInt(0);
                    if (predictor != 1 && predictor != 2) {
                        throw new Exception("Illegal value for Predictor in TIFF file.");
                    }
                    if (predictor == 2 && bitsPerSample != 8) {
                        throw new Exception(bitsPerSample + "-bit samples are not supported for Horizontal differencing Predictor.");
                    }
                }
                lzwDecoder = new TIFFLZWDecoder(w, predictor,
                                                samplePerPixel);
            }
            int rowsLeft = h;
            MemoryStream stream = null;
            ZOutputStream zip = null;
            CCITTG4Encoder g4 = null;
            if (bitsPerSample == 1 && samplePerPixel == 1) {
                g4 = new CCITTG4Encoder(w);
            }
            else {
                stream = new MemoryStream();
                if (compression != TIFFConstants.COMPRESSION_OJPEG && compression != TIFFConstants.COMPRESSION_JPEG)
                    zip = new ZOutputStream(stream);
            }
            if (compression == TIFFConstants.COMPRESSION_OJPEG) {

                // Assume that the TIFFTAG_JPEGIFBYTECOUNT tag is optional, since it's obsolete and
                // is often missing

                if ((!dir.IsTagPresent(TIFFConstants.TIFFTAG_JPEGIFOFFSET))) {
                    throw new IOException("Missing tag(s) for OJPEG compression.");
                }
                int jpegOffset = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_JPEGIFOFFSET);
                int jpegLength = s.Length - jpegOffset;

                if (dir.IsTagPresent(TIFFConstants.TIFFTAG_JPEGIFBYTECOUNT)) {
                    jpegLength = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_JPEGIFBYTECOUNT) +
                        (int)size[0];
                }

                byte[] jpeg = new byte[Math.Min(jpegLength, s.Length - jpegOffset)];

                int posFilePointer = s.FilePointer;
                posFilePointer += jpegOffset;
                s.Seek(posFilePointer);
                s.ReadFully(jpeg);
                img = new Jpeg(jpeg);
            }
            else if (compression == TIFFConstants.COMPRESSION_JPEG) {
                if (size.Length > 1)
                    throw new IOException("Compression JPEG is only supported with a single strip. This image has " + size.Length + " strips.");
                byte[] jpeg = new byte[(int)size[0]];
                s.Seek(offset[0]);
                s.ReadFully(jpeg);
                img = new Jpeg(jpeg);
            }
            else {
                for (int k = 0; k < offset.Length; ++k) {
                    byte[] im = new byte[(int)size[k]];
                    s.Seek(offset[k]);
                    s.ReadFully(im);
                    int height = Math.Min(rowsStrip, rowsLeft);
                    byte[] outBuf = null;
                    if (compression != TIFFConstants.COMPRESSION_NONE)
                        outBuf = new byte[(w * bitsPerSample * samplePerPixel + 7) / 8 * height];
                    if (reverse)
                        TIFFFaxDecoder.ReverseBits(im);
                    switch (compression) {
                        case TIFFConstants.COMPRESSION_DEFLATE:
                        case TIFFConstants.COMPRESSION_ADOBE_DEFLATE:
                            Inflate(im, outBuf);
                            break;
                        case TIFFConstants.COMPRESSION_NONE:
                            outBuf = im;
                            break;
                        case TIFFConstants.COMPRESSION_PACKBITS:
                            DecodePackbits(im,  outBuf);
                            break;
                        case TIFFConstants.COMPRESSION_LZW:
                            lzwDecoder.Decode(im, outBuf, height);
                            break;
                    }
                    if (bitsPerSample == 1 && samplePerPixel == 1) {
                        g4.Fax4Encode(outBuf, height);
                    }
                    else {
                        zip.Write(outBuf, 0, outBuf.Length);
                    }
                    rowsLeft -= rowsStrip;
                }
                if (bitsPerSample == 1 && samplePerPixel == 1) {
                    img = Image.GetInstance(w, h, false, Image.CCITTG4,
                        photometric == TIFFConstants.PHOTOMETRIC_MINISBLACK ? Image.CCITT_BLACKIS1 : 0, g4.Close());
                }
                else {
                    zip.Close();
                    img = Image.GetInstance(w, h, samplePerPixel, bitsPerSample, stream.ToArray());
                    img.Deflated = true;
                }
            }
            img.SetDpi(dpiX, dpiY);
            if (compression != TIFFConstants.COMPRESSION_OJPEG && compression != TIFFConstants.COMPRESSION_JPEG) {
                if (dir.IsTagPresent(TIFFConstants.TIFFTAG_ICCPROFILE)) {
                    try {
                        TIFFField fd = dir.GetField(TIFFConstants.TIFFTAG_ICCPROFILE);
                        ICC_Profile icc_prof = ICC_Profile.GetInstance(fd.GetAsBytes());
                        if (samplePerPixel == icc_prof.NumComponents)
                            img.TagICC = icc_prof;
                    }
                    catch {
                        //empty
                    }
                }
                if (dir.IsTagPresent(TIFFConstants.TIFFTAG_COLORMAP)) {
                    TIFFField fd = dir.GetField(TIFFConstants.TIFFTAG_COLORMAP);
                    char[] rgb = fd.GetAsChars();
                    byte[] palette = new byte[rgb.Length];
                    int gColor = rgb.Length / 3;
                    int bColor = gColor * 2;
                    for (int k = 0; k < gColor; ++k) {
                        palette[k * 3] = (byte)(rgb[k] >> 8);
                        palette[k * 3 + 1] = (byte)(rgb[k + gColor] >> 8);
                        palette[k * 3 + 2] = (byte)(rgb[k + bColor] >> 8);
                    }
                    PdfArray indexed = new PdfArray();
                    indexed.Add(PdfName.INDEXED);
                    indexed.Add(PdfName.DEVICERGB);
                    indexed.Add(new PdfNumber(gColor - 1));
                    indexed.Add(new PdfString(palette));
                    PdfDictionary additional = new PdfDictionary();
                    additional.Put(PdfName.COLORSPACE, indexed);
                    img.Additional = additional;
                }
                img.OriginalType = Image.ORIGINAL_TIFF;
            }
            if (photometric == TIFFConstants.PHOTOMETRIC_MINISWHITE)
                img.Inverted = true;
            if (rotation != 0)
                img.InitialRotation = rotation;
            return img;
        }
Пример #7
0
        private void Initialize(RandomAccessFileOrArray stream)
        {
            long nextTagOffset = 0L;
            long maxOffset = (long)stream.Length;
            int  i, j;

            IFDOffset = stream.FilePointer;

            numEntries = ReadUnsignedShort(stream);
            fields     = new TIFFField[numEntries];

            for (i = 0; (i < numEntries) && (nextTagOffset < maxOffset); i++)
            {
                int  tag        = ReadUnsignedShort(stream);
                int  type       = ReadUnsignedShort(stream);
                int  count      = (int)(ReadUnsignedInt(stream));
                bool processTag = true;

                // The place to return to to read the next tag
                nextTagOffset = stream.FilePointer + 4;

                try {
                    // If the tag data can't fit in 4 bytes, the next 4 bytes
                    // contain the starting offset of the data
                    if (count * sizeOfType[type] > 4)
                    {
                        long valueOffset = ReadUnsignedInt(stream);

                        // bounds check offset for EOF
                        if (valueOffset < maxOffset)
                        {
                            stream.Seek(valueOffset);
                        }
                        else
                        {
                            // bad offset pointer .. skip tag
                            processTag = false;
                        }
                    }
                } catch (ArgumentOutOfRangeException) {
                    // if the data type is unknown we should skip this TIFF Field
                    processTag = false;
                }

                if (processTag)
                {
                    fieldIndex[tag] = i;
                    Object obj = null;

                    switch (type)
                    {
                    case TIFFField.TIFF_BYTE:
                    case TIFFField.TIFF_SBYTE:
                    case TIFFField.TIFF_UNDEFINED:
                    case TIFFField.TIFF_ASCII:
                        byte[] bvalues = new byte[count];
                        stream.ReadFully(bvalues, 0, count);

                        if (type == TIFFField.TIFF_ASCII)
                        {
                            // Can be multiple strings
                            int           index = 0, prevIndex = 0;
                            List <string> v = new List <string>();

                            while (index < count)
                            {
                                while ((index < count) && (bvalues[index++] != 0))
                                {
                                    ;
                                }

                                // When we encountered zero, means one string has ended
                                char[] cht = new char[index - prevIndex];
                                Array.Copy(bvalues, prevIndex, cht, 0, index - prevIndex);
                                v.Add(new String(cht));
                                prevIndex = index;
                            }

                            count = v.Count;
                            String[] strings = new String[count];
                            for (int c = 0; c < count; c++)
                            {
                                strings[c] = v[c];
                            }

                            obj = strings;
                        }
                        else
                        {
                            obj = bvalues;
                        }

                        break;

                    case TIFFField.TIFF_SHORT:
                        char[] cvalues = new char[count];
                        for (j = 0; j < count; j++)
                        {
                            cvalues[j] = (char)(ReadUnsignedShort(stream));
                        }
                        obj = cvalues;
                        break;

                    case TIFFField.TIFF_LONG:
                        long[] lvalues = new long[count];
                        for (j = 0; j < count; j++)
                        {
                            lvalues[j] = ReadUnsignedInt(stream);
                        }
                        obj = lvalues;
                        break;

                    case TIFFField.TIFF_RATIONAL:
                        long[][] llvalues = new long[count][];
                        for (j = 0; j < count; j++)
                        {
                            long v0 = ReadUnsignedInt(stream);
                            long v1 = ReadUnsignedInt(stream);
                            llvalues[j] = new long[] { v0, v1 };
                        }
                        obj = llvalues;
                        break;

                    case TIFFField.TIFF_SSHORT:
                        short[] svalues = new short[count];
                        for (j = 0; j < count; j++)
                        {
                            svalues[j] = ReadShort(stream);
                        }
                        obj = svalues;
                        break;

                    case TIFFField.TIFF_SLONG:
                        int[] ivalues = new int[count];
                        for (j = 0; j < count; j++)
                        {
                            ivalues[j] = ReadInt(stream);
                        }
                        obj = ivalues;
                        break;

                    case TIFFField.TIFF_SRATIONAL:
                        int[,] iivalues = new int[count, 2];
                        for (j = 0; j < count; j++)
                        {
                            iivalues[j, 0] = ReadInt(stream);
                            iivalues[j, 1] = ReadInt(stream);
                        }
                        obj = iivalues;
                        break;

                    case TIFFField.TIFF_FLOAT:
                        float[] fvalues = new float[count];
                        for (j = 0; j < count; j++)
                        {
                            fvalues[j] = ReadFloat(stream);
                        }
                        obj = fvalues;
                        break;

                    case TIFFField.TIFF_DOUBLE:
                        double[] dvalues = new double[count];
                        for (j = 0; j < count; j++)
                        {
                            dvalues[j] = ReadDouble(stream);
                        }
                        obj = dvalues;
                        break;

                    default:
                        break;
                    }

                    fields[i] = new TIFFField(tag, type, count, obj);
                }

                stream.Seek(nextTagOffset);
            }

            // Read the offset of the next IFD.
            try {
                nextIFDOffset = ReadUnsignedInt(stream);
            }
            catch {
                // broken tiffs may not have this pointer
                nextIFDOffset = 0;
            }
        }
Пример #8
0
        private static void ProcessTiffImage(RandomAccessFileOrArray s, TiffImageHelper.TiffParameters tiff)
        {
            bool recoverFromImageError = tiff.image.IsRecoverFromImageError();
            int  page   = tiff.image.GetPage();
            bool direct = tiff.image.IsDirect();

            if (page < 1)
            {
                throw new iText.IO.IOException(iText.IO.IOException.PageNumberMustBeGtEq1);
            }
            try {
                TIFFDirectory dir = new TIFFDirectory(s, page - 1);
                if (dir.IsTagPresent(TIFFConstants.TIFFTAG_TILEWIDTH))
                {
                    throw new iText.IO.IOException(iText.IO.IOException.TilesAreNotSupported);
                }
                int compression = TIFFConstants.COMPRESSION_NONE;
                if (dir.IsTagPresent(TIFFConstants.TIFFTAG_COMPRESSION))
                {
                    compression = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_COMPRESSION);
                }
                switch (compression)
                {
                case TIFFConstants.COMPRESSION_CCITTRLEW:
                case TIFFConstants.COMPRESSION_CCITTRLE:
                case TIFFConstants.COMPRESSION_CCITTFAX3:
                case TIFFConstants.COMPRESSION_CCITTFAX4: {
                    break;
                }

                default: {
                    ProcessTiffImageColor(dir, s, tiff);
                    return;
                }
                }
                float rotation = 0;
                if (dir.IsTagPresent(TIFFConstants.TIFFTAG_ORIENTATION))
                {
                    int rot = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_ORIENTATION);
                    if (rot == TIFFConstants.ORIENTATION_BOTRIGHT || rot == TIFFConstants.ORIENTATION_BOTLEFT)
                    {
                        rotation = (float)Math.PI;
                    }
                    else
                    {
                        if (rot == TIFFConstants.ORIENTATION_LEFTTOP || rot == TIFFConstants.ORIENTATION_LEFTBOT)
                        {
                            rotation = (float)(Math.PI / 2.0);
                        }
                        else
                        {
                            if (rot == TIFFConstants.ORIENTATION_RIGHTTOP || rot == TIFFConstants.ORIENTATION_RIGHTBOT)
                            {
                                rotation = -(float)(Math.PI / 2.0);
                            }
                        }
                    }
                }
                long  tiffT4Options  = 0;
                long  tiffT6Options  = 0;
                int   fillOrder      = 1;
                int   h              = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_IMAGELENGTH);
                int   w              = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_IMAGEWIDTH);
                float XYRatio        = 0;
                int   resolutionUnit = TIFFConstants.RESUNIT_INCH;
                if (dir.IsTagPresent(TIFFConstants.TIFFTAG_RESOLUTIONUNIT))
                {
                    resolutionUnit = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_RESOLUTIONUNIT);
                }
                int dpiX = GetDpi(dir.GetField(TIFFConstants.TIFFTAG_XRESOLUTION), resolutionUnit);
                int dpiY = GetDpi(dir.GetField(TIFFConstants.TIFFTAG_YRESOLUTION), resolutionUnit);
                if (resolutionUnit == TIFFConstants.RESUNIT_NONE)
                {
                    if (dpiY != 0)
                    {
                        XYRatio = (float)dpiX / (float)dpiY;
                    }
                    dpiX = 0;
                    dpiY = 0;
                }
                int rowsStrip = h;
                if (dir.IsTagPresent(TIFFConstants.TIFFTAG_ROWSPERSTRIP))
                {
                    rowsStrip = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_ROWSPERSTRIP);
                }
                if (rowsStrip <= 0 || rowsStrip > h)
                {
                    rowsStrip = h;
                }
                long[] offset = GetArrayLongShort(dir, TIFFConstants.TIFFTAG_STRIPOFFSETS);
                long[] size   = GetArrayLongShort(dir, TIFFConstants.TIFFTAG_STRIPBYTECOUNTS);
                // some TIFF producers are really lousy, so...
                if ((size == null || (size.Length == 1 && (size[0] == 0 || size[0] + offset[0] > s.Length()))) && h == rowsStrip
                    )
                {
                    size = new long[] { s.Length() - (int)offset[0] };
                }
                bool      reverse        = false;
                TIFFField fillOrderField = dir.GetField(TIFFConstants.TIFFTAG_FILLORDER);
                if (fillOrderField != null)
                {
                    fillOrder = fillOrderField.GetAsInt(0);
                }
                reverse = (fillOrder == TIFFConstants.FILLORDER_LSB2MSB);
                int parameters = 0;
                if (dir.IsTagPresent(TIFFConstants.TIFFTAG_PHOTOMETRIC))
                {
                    long photo = dir.GetFieldAsLong(TIFFConstants.TIFFTAG_PHOTOMETRIC);
                    if (photo == TIFFConstants.PHOTOMETRIC_MINISBLACK)
                    {
                        parameters |= RawImageData.CCITT_BLACKIS1;
                    }
                }
                int imagecomp = 0;
                switch (compression)
                {
                case TIFFConstants.COMPRESSION_CCITTRLEW:
                case TIFFConstants.COMPRESSION_CCITTRLE: {
                    imagecomp   = RawImageData.CCITTG3_1D;
                    parameters |= RawImageData.CCITT_ENCODEDBYTEALIGN | RawImageData.CCITT_ENDOFBLOCK;
                    break;
                }

                case TIFFConstants.COMPRESSION_CCITTFAX3: {
                    imagecomp   = RawImageData.CCITTG3_1D;
                    parameters |= RawImageData.CCITT_ENDOFLINE | RawImageData.CCITT_ENDOFBLOCK;
                    TIFFField t4OptionsField = dir.GetField(TIFFConstants.TIFFTAG_GROUP3OPTIONS);
                    if (t4OptionsField != null)
                    {
                        tiffT4Options = t4OptionsField.GetAsLong(0);
                        if ((tiffT4Options & TIFFConstants.GROUP3OPT_2DENCODING) != 0)
                        {
                            imagecomp = RawImageData.CCITTG3_2D;
                        }
                        if ((tiffT4Options & TIFFConstants.GROUP3OPT_FILLBITS) != 0)
                        {
                            parameters |= RawImageData.CCITT_ENCODEDBYTEALIGN;
                        }
                    }
                    break;
                }

                case TIFFConstants.COMPRESSION_CCITTFAX4: {
                    imagecomp = RawImageData.CCITTG4;
                    TIFFField t6OptionsField = dir.GetField(TIFFConstants.TIFFTAG_GROUP4OPTIONS);
                    if (t6OptionsField != null)
                    {
                        tiffT6Options = t6OptionsField.GetAsLong(0);
                    }
                    break;
                }
                }
                //single strip, direct
                if (direct && rowsStrip == h)
                {
                    byte[] im = new byte[(int)size[0]];
                    s.Seek(offset[0]);
                    s.ReadFully(im);
                    RawImageHelper.UpdateRawImageParameters(tiff.image, w, h, false, imagecomp, parameters, im, null);
                    tiff.image.SetInverted(true);
                }
                else
                {
                    int            rowsLeft = h;
                    CCITTG4Encoder g4       = new CCITTG4Encoder(w);
                    for (int k = 0; k < offset.Length; ++k)
                    {
                        byte[] im = new byte[(int)size[k]];
                        s.Seek(offset[k]);
                        s.ReadFully(im);
                        int            height  = Math.Min(rowsStrip, rowsLeft);
                        TIFFFaxDecoder decoder = new TIFFFaxDecoder(fillOrder, w, height);
                        decoder.SetRecoverFromImageError(recoverFromImageError);
                        byte[] outBuf = new byte[(w + 7) / 8 * height];
                        switch (compression)
                        {
                        case TIFFConstants.COMPRESSION_CCITTRLEW:
                        case TIFFConstants.COMPRESSION_CCITTRLE: {
                            decoder.Decode1D(outBuf, im, 0, height);
                            g4.Fax4Encode(outBuf, height);
                            break;
                        }

                        case TIFFConstants.COMPRESSION_CCITTFAX3: {
                            try {
                                decoder.Decode2D(outBuf, im, 0, height, tiffT4Options);
                            }
                            catch (Exception e) {
                                // let's flip the fill bits and try again...
                                tiffT4Options ^= TIFFConstants.GROUP3OPT_FILLBITS;
                                try {
                                    decoder.Decode2D(outBuf, im, 0, height, tiffT4Options);
                                }
                                catch (Exception) {
                                    if (!recoverFromImageError)
                                    {
                                        throw e;
                                    }
                                    if (rowsStrip == 1)
                                    {
                                        throw e;
                                    }
                                    // repeat of reading the tiff directly (the if section of this if else structure)
                                    // copy pasted to avoid making a method with 10 tiff
                                    im = new byte[(int)size[0]];
                                    s.Seek(offset[0]);
                                    s.ReadFully(im);
                                    RawImageHelper.UpdateRawImageParameters(tiff.image, w, h, false, imagecomp, parameters, im, null);
                                    tiff.image.SetInverted(true);
                                    tiff.image.SetDpi(dpiX, dpiY);
                                    tiff.image.SetXYRatio(XYRatio);
                                    if (rotation != 0)
                                    {
                                        tiff.image.SetRotation(rotation);
                                    }
                                    return;
                                }
                            }
                            g4.Fax4Encode(outBuf, height);
                            break;
                        }

                        case TIFFConstants.COMPRESSION_CCITTFAX4: {
                            try {
                                decoder.DecodeT6(outBuf, im, 0, height, tiffT6Options);
                            }
                            catch (iText.IO.IOException e) {
                                if (!recoverFromImageError)
                                {
                                    throw;
                                }
                            }
                            g4.Fax4Encode(outBuf, height);
                            break;
                        }
                        }
                        rowsLeft -= rowsStrip;
                    }
                    byte[] g4pic = g4.Close();
                    RawImageHelper.UpdateRawImageParameters(tiff.image, w, h, false, RawImageData.CCITTG4, parameters & RawImageData
                                                            .CCITT_BLACKIS1, g4pic, null);
                }
                tiff.image.SetDpi(dpiX, dpiY);
                if (dir.IsTagPresent(TIFFConstants.TIFFTAG_ICCPROFILE))
                {
                    try {
                        TIFFField  fd       = dir.GetField(TIFFConstants.TIFFTAG_ICCPROFILE);
                        IccProfile icc_prof = IccProfile.GetInstance(fd.GetAsBytes());
                        if (icc_prof.GetNumComponents() == 1)
                        {
                            tiff.image.SetProfile(icc_prof);
                        }
                    }
                    catch (Exception) {
                    }
                }
                //empty
                if (rotation != 0)
                {
                    tiff.image.SetRotation(rotation);
                }
            }
            catch (Exception) {
                throw new iText.IO.IOException(iText.IO.IOException.CannotReadTiffImage);
            }
        }
Пример #9
0
        private static void ProcessTiffImageColor(TIFFDirectory dir, RandomAccessFileOrArray s, TiffImageHelper.TiffParameters
                                                  tiff)
        {
            try {
                int compression = TIFFConstants.COMPRESSION_NONE;
                if (dir.IsTagPresent(TIFFConstants.TIFFTAG_COMPRESSION))
                {
                    compression = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_COMPRESSION);
                }
                int            predictor  = 1;
                TIFFLZWDecoder lzwDecoder = null;
                switch (compression)
                {
                case TIFFConstants.COMPRESSION_NONE:
                case TIFFConstants.COMPRESSION_LZW:
                case TIFFConstants.COMPRESSION_PACKBITS:
                case TIFFConstants.COMPRESSION_DEFLATE:
                case TIFFConstants.COMPRESSION_ADOBE_DEFLATE:
                case TIFFConstants.COMPRESSION_OJPEG:
                case TIFFConstants.COMPRESSION_JPEG: {
                    break;
                }

                default: {
                    throw new iText.IO.IOException(iText.IO.IOException.Compression1IsNotSupported).SetMessageParams(compression
                                                                                                                     );
                }
                }
                int photometric = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_PHOTOMETRIC);
                switch (photometric)
                {
                case TIFFConstants.PHOTOMETRIC_MINISWHITE:
                case TIFFConstants.PHOTOMETRIC_MINISBLACK:
                case TIFFConstants.PHOTOMETRIC_RGB:
                case TIFFConstants.PHOTOMETRIC_SEPARATED:
                case TIFFConstants.PHOTOMETRIC_PALETTE: {
                    break;
                }

                default: {
                    if (compression != TIFFConstants.COMPRESSION_OJPEG && compression != TIFFConstants.COMPRESSION_JPEG)
                    {
                        throw new iText.IO.IOException(iText.IO.IOException.Photometric1IsNotSupported).SetMessageParams(photometric
                                                                                                                         );
                    }
                    break;
                }
                }
                float rotation = 0;
                if (dir.IsTagPresent(TIFFConstants.TIFFTAG_ORIENTATION))
                {
                    int rot = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_ORIENTATION);
                    if (rot == TIFFConstants.ORIENTATION_BOTRIGHT || rot == TIFFConstants.ORIENTATION_BOTLEFT)
                    {
                        rotation = (float)Math.PI;
                    }
                    else
                    {
                        if (rot == TIFFConstants.ORIENTATION_LEFTTOP || rot == TIFFConstants.ORIENTATION_LEFTBOT)
                        {
                            rotation = (float)(Math.PI / 2.0);
                        }
                        else
                        {
                            if (rot == TIFFConstants.ORIENTATION_RIGHTTOP || rot == TIFFConstants.ORIENTATION_RIGHTBOT)
                            {
                                rotation = -(float)(Math.PI / 2.0);
                            }
                        }
                    }
                }
                if (dir.IsTagPresent(TIFFConstants.TIFFTAG_PLANARCONFIG) && dir.GetFieldAsLong(TIFFConstants.TIFFTAG_PLANARCONFIG
                                                                                               ) == TIFFConstants.PLANARCONFIG_SEPARATE)
                {
                    throw new iText.IO.IOException(iText.IO.IOException.PlanarImagesAreNotSupported);
                }
                int extraSamples = 0;
                if (dir.IsTagPresent(TIFFConstants.TIFFTAG_EXTRASAMPLES))
                {
                    extraSamples = 1;
                }
                int samplePerPixel = 1;
                // 1,3,4
                if (dir.IsTagPresent(TIFFConstants.TIFFTAG_SAMPLESPERPIXEL))
                {
                    samplePerPixel = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_SAMPLESPERPIXEL);
                }
                int bitsPerSample = 1;
                if (dir.IsTagPresent(TIFFConstants.TIFFTAG_BITSPERSAMPLE))
                {
                    bitsPerSample = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_BITSPERSAMPLE);
                }
                switch (bitsPerSample)
                {
                case 1:
                case 2:
                case 4:
                case 8: {
                    break;
                }

                default: {
                    throw new iText.IO.IOException(iText.IO.IOException.BitsPerSample1IsNotSupported).SetMessageParams(bitsPerSample
                                                                                                                       );
                }
                }
                int h = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_IMAGELENGTH);
                int w = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_IMAGEWIDTH);
                int dpiX;
                int dpiY;
                int resolutionUnit = TIFFConstants.RESUNIT_INCH;
                if (dir.IsTagPresent(TIFFConstants.TIFFTAG_RESOLUTIONUNIT))
                {
                    resolutionUnit = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_RESOLUTIONUNIT);
                }
                dpiX = GetDpi(dir.GetField(TIFFConstants.TIFFTAG_XRESOLUTION), resolutionUnit);
                dpiY = GetDpi(dir.GetField(TIFFConstants.TIFFTAG_YRESOLUTION), resolutionUnit);
                int       fillOrder      = 1;
                TIFFField fillOrderField = dir.GetField(TIFFConstants.TIFFTAG_FILLORDER);
                if (fillOrderField != null)
                {
                    fillOrder = fillOrderField.GetAsInt(0);
                }
                bool reverse   = (fillOrder == TIFFConstants.FILLORDER_LSB2MSB);
                int  rowsStrip = h;
                // another hack for broken tiffs
                if (dir.IsTagPresent(TIFFConstants.TIFFTAG_ROWSPERSTRIP))
                {
                    rowsStrip = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_ROWSPERSTRIP);
                }
                if (rowsStrip <= 0 || rowsStrip > h)
                {
                    rowsStrip = h;
                }
                long[] offset = GetArrayLongShort(dir, TIFFConstants.TIFFTAG_STRIPOFFSETS);
                long[] size   = GetArrayLongShort(dir, TIFFConstants.TIFFTAG_STRIPBYTECOUNTS);
                // some TIFF producers are really lousy, so...
                if ((size == null || (size.Length == 1 && (size[0] == 0 || size[0] + offset[0] > s.Length()))) && h == rowsStrip
                    )
                {
                    size = new long[] { s.Length() - (int)offset[0] };
                }
                if (compression == TIFFConstants.COMPRESSION_LZW || compression == TIFFConstants.COMPRESSION_DEFLATE || compression
                    == TIFFConstants.COMPRESSION_ADOBE_DEFLATE)
                {
                    TIFFField predictorField = dir.GetField(TIFFConstants.TIFFTAG_PREDICTOR);
                    if (predictorField != null)
                    {
                        predictor = predictorField.GetAsInt(0);
                        if (predictor != 1 && predictor != 2)
                        {
                            throw new iText.IO.IOException(iText.IO.IOException.IllegalValueForPredictorInTiffFile);
                        }
                        if (predictor == 2 && bitsPerSample != 8)
                        {
                            throw new iText.IO.IOException(iText.IO.IOException._1BitSamplesAreNotSupportedForHorizontalDifferencingPredictor
                                                           ).SetMessageParams(bitsPerSample);
                        }
                    }
                }
                if (compression == TIFFConstants.COMPRESSION_LZW)
                {
                    lzwDecoder = new TIFFLZWDecoder(w, predictor, samplePerPixel);
                }
                int rowsLeft = h;
                ByteArrayOutputStream stream  = null;
                ByteArrayOutputStream mstream = null;
                DeflaterOutputStream  zip     = null;
                DeflaterOutputStream  mzip    = null;
                if (extraSamples > 0)
                {
                    mstream = new ByteArrayOutputStream();
                    mzip    = new DeflaterOutputStream(mstream);
                }
                CCITTG4Encoder g4 = null;
                if (bitsPerSample == 1 && samplePerPixel == 1 && photometric != TIFFConstants.PHOTOMETRIC_PALETTE)
                {
                    g4 = new CCITTG4Encoder(w);
                }
                else
                {
                    stream = new ByteArrayOutputStream();
                    if (compression != TIFFConstants.COMPRESSION_OJPEG && compression != TIFFConstants.COMPRESSION_JPEG)
                    {
                        zip = new DeflaterOutputStream(stream);
                    }
                }
                if (compression == TIFFConstants.COMPRESSION_OJPEG)
                {
                    // Assume that the TIFFTAG_JPEGIFBYTECOUNT tag is optional, since it's obsolete and
                    // is often missing
                    if ((!dir.IsTagPresent(TIFFConstants.TIFFTAG_JPEGIFOFFSET)))
                    {
                        throw new iText.IO.IOException(iText.IO.IOException.MissingTagsForOjpegCompression);
                    }
                    int jpegOffset = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_JPEGIFOFFSET);
                    int jpegLength = (int)s.Length() - jpegOffset;
                    if (dir.IsTagPresent(TIFFConstants.TIFFTAG_JPEGIFBYTECOUNT))
                    {
                        jpegLength = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_JPEGIFBYTECOUNT) + (int)size[0];
                    }
                    byte[] jpeg           = new byte[Math.Min(jpegLength, (int)s.Length() - jpegOffset)];
                    int    posFilePointer = (int)s.GetPosition();
                    posFilePointer += jpegOffset;
                    s.Seek(posFilePointer);
                    s.ReadFully(jpeg);
                    tiff.image.data = jpeg;
                    tiff.image.SetOriginalType(ImageType.JPEG);
                    JpegImageHelper.ProcessImage(tiff.image);
                    tiff.jpegProcessing = true;
                }
                else
                {
                    if (compression == TIFFConstants.COMPRESSION_JPEG)
                    {
                        if (size.Length > 1)
                        {
                            throw new iText.IO.IOException(iText.IO.IOException.CompressionJpegIsOnlySupportedWithASingleStripThisImageHas1Strips
                                                           ).SetMessageParams(size.Length);
                        }
                        byte[] jpeg = new byte[(int)size[0]];
                        s.Seek(offset[0]);
                        s.ReadFully(jpeg);
                        // if quantization and/or Huffman tables are stored separately in the tiff,
                        // we need to add them to the jpeg data
                        TIFFField jpegtables = dir.GetField(TIFFConstants.TIFFTAG_JPEGTABLES);
                        if (jpegtables != null)
                        {
                            byte[] temp        = jpegtables.GetAsBytes();
                            int    tableoffset = 0;
                            int    tablelength = temp.Length;
                            // remove FFD8 from start
                            if (temp[0] == (byte)0xFF && temp[1] == (byte)0xD8)
                            {
                                tableoffset  = 2;
                                tablelength -= 2;
                            }
                            // remove FFD9 from end
                            if (temp[temp.Length - 2] == (byte)0xFF && temp[temp.Length - 1] == (byte)0xD9)
                            {
                                tablelength -= 2;
                            }
                            byte[] tables = new byte[tablelength];
                            Array.Copy(temp, tableoffset, tables, 0, tablelength);
                            // TODO insert after JFIF header, instead of at the start
                            byte[] jpegwithtables = new byte[jpeg.Length + tables.Length];
                            Array.Copy(jpeg, 0, jpegwithtables, 0, 2);
                            Array.Copy(tables, 0, jpegwithtables, 2, tables.Length);
                            Array.Copy(jpeg, 2, jpegwithtables, tables.Length + 2, jpeg.Length - 2);
                            jpeg = jpegwithtables;
                        }
                        tiff.image.data = jpeg;
                        tiff.image.SetOriginalType(ImageType.JPEG);
                        JpegImageHelper.ProcessImage(tiff.image);
                        tiff.jpegProcessing = true;
                        if (photometric == TIFFConstants.PHOTOMETRIC_RGB)
                        {
                            tiff.image.SetColorTransform(0);
                        }
                    }
                    else
                    {
                        for (int k = 0; k < offset.Length; ++k)
                        {
                            byte[] im = new byte[(int)size[k]];
                            s.Seek(offset[k]);
                            s.ReadFully(im);
                            int    height = Math.Min(rowsStrip, rowsLeft);
                            byte[] outBuf = null;
                            if (compression != TIFFConstants.COMPRESSION_NONE)
                            {
                                outBuf = new byte[(w * bitsPerSample * samplePerPixel + 7) / 8 * height];
                            }
                            if (reverse)
                            {
                                TIFFFaxDecoder.ReverseBits(im);
                            }
                            switch (compression)
                            {
                            case TIFFConstants.COMPRESSION_DEFLATE:
                            case TIFFConstants.COMPRESSION_ADOBE_DEFLATE: {
                                FilterUtil.InflateData(im, outBuf);
                                ApplyPredictor(outBuf, predictor, w, height, samplePerPixel);
                                break;
                            }

                            case TIFFConstants.COMPRESSION_NONE: {
                                outBuf = im;
                                break;
                            }

                            case TIFFConstants.COMPRESSION_PACKBITS: {
                                DecodePackbits(im, outBuf);
                                break;
                            }

                            case TIFFConstants.COMPRESSION_LZW: {
                                lzwDecoder.Decode(im, outBuf, height);
                                break;
                            }
                            }
                            if (bitsPerSample == 1 && samplePerPixel == 1 && photometric != TIFFConstants.PHOTOMETRIC_PALETTE)
                            {
                                g4.Fax4Encode(outBuf, height);
                            }
                            else
                            {
                                if (extraSamples > 0)
                                {
                                    ProcessExtraSamples(zip, mzip, outBuf, samplePerPixel, bitsPerSample, w, height);
                                }
                                else
                                {
                                    zip.Write(outBuf);
                                }
                            }
                            rowsLeft -= rowsStrip;
                        }
                        if (bitsPerSample == 1 && samplePerPixel == 1 && photometric != TIFFConstants.PHOTOMETRIC_PALETTE)
                        {
                            RawImageHelper.UpdateRawImageParameters(tiff.image, w, h, false, RawImageData.CCITTG4, photometric == TIFFConstants
                                                                    .PHOTOMETRIC_MINISBLACK ? RawImageData.CCITT_BLACKIS1 : 0, g4.Close(), null);
                        }
                        else
                        {
                            zip.Dispose();
                            RawImageHelper.UpdateRawImageParameters(tiff.image, w, h, samplePerPixel - extraSamples, bitsPerSample, stream
                                                                    .ToArray());
                            tiff.image.SetDeflated(true);
                        }
                    }
                }
                tiff.image.SetDpi(dpiX, dpiY);
                if (compression != TIFFConstants.COMPRESSION_OJPEG && compression != TIFFConstants.COMPRESSION_JPEG)
                {
                    if (dir.IsTagPresent(TIFFConstants.TIFFTAG_ICCPROFILE))
                    {
                        try {
                            TIFFField  fd       = dir.GetField(TIFFConstants.TIFFTAG_ICCPROFILE);
                            IccProfile icc_prof = IccProfile.GetInstance(fd.GetAsBytes());
                            if (samplePerPixel - extraSamples == icc_prof.GetNumComponents())
                            {
                                tiff.image.SetProfile(icc_prof);
                            }
                        }
                        catch (Exception) {
                        }
                    }
                    //empty
                    if (dir.IsTagPresent(TIFFConstants.TIFFTAG_COLORMAP))
                    {
                        TIFFField fd      = dir.GetField(TIFFConstants.TIFFTAG_COLORMAP);
                        char[]    rgb     = fd.GetAsChars();
                        byte[]    palette = new byte[rgb.Length];
                        int       gColor  = rgb.Length / 3;
                        int       bColor  = gColor * 2;
                        for (int k = 0; k < gColor; ++k)
                        {
                            //there is no sense in >>> for unsigned char
                            palette[k * 3]     = (byte)(rgb[k] >> 8);
                            palette[k * 3 + 1] = (byte)(rgb[k + gColor] >> 8);
                            palette[k * 3 + 2] = (byte)(rgb[k + bColor] >> 8);
                        }
                        // Colormap components are supposed to go from 0 to 655535 but,
                        // as usually, some tiff producers just put values from 0 to 255.
                        // Let's check for these broken tiffs.
                        bool colormapBroken = true;
                        for (int k = 0; k < palette.Length; ++k)
                        {
                            if (palette[k] != 0)
                            {
                                colormapBroken = false;
                                break;
                            }
                        }
                        if (colormapBroken)
                        {
                            for (int k = 0; k < gColor; ++k)
                            {
                                palette[k * 3]     = (byte)rgb[k];
                                palette[k * 3 + 1] = (byte)rgb[k + gColor];
                                palette[k * 3 + 2] = (byte)rgb[k + bColor];
                            }
                        }
                        Object[] indexed = new Object[4];
                        indexed[0]      = "/Indexed";
                        indexed[1]      = "/DeviceRGB";
                        indexed[2]      = gColor - 1;
                        indexed[3]      = PdfEncodings.ConvertToString(palette, null);
                        tiff.additional = new Dictionary <String, Object>();
                        tiff.additional.Put("ColorSpace", indexed);
                    }
                }
                if (photometric == TIFFConstants.PHOTOMETRIC_MINISWHITE)
                {
                    tiff.image.SetInverted(true);
                }
                if (rotation != 0)
                {
                    tiff.image.SetRotation(rotation);
                }
                if (extraSamples > 0)
                {
                    mzip.Dispose();
                    RawImageData mimg = (RawImageData)ImageDataFactory.CreateRawImage(null);
                    RawImageHelper.UpdateRawImageParameters(mimg, w, h, 1, bitsPerSample, mstream.ToArray());
                    mimg.MakeMask();
                    mimg.SetDeflated(true);
                    tiff.image.SetImageMask(mimg);
                }
            }
            catch (Exception) {
                throw new iText.IO.IOException(iText.IO.IOException.CannotGetTiffImageColor);
            }
        }
Пример #10
0
        //  0 = n/a
        //  1 = byte
        //  2 = ascii
        //  3 = short
        //  4 = long
        //  5 = rational
        //  6 = sbyte
        //  7 = undefined
        //  8 = sshort
        //  9 = slong
        // 10 = srational
        // 11 = float
        // 12 = double
        /// <exception cref="System.IO.IOException"/>
        private void Initialize(RandomAccessFileOrArray stream)
        {
            long nextTagOffset = 0L;
            long maxOffset     = stream.Length();
            int  i;
            int  j;

            IFDOffset  = stream.GetPosition();
            numEntries = ReadUnsignedShort(stream);
            fields     = new TIFFField[numEntries];
            for (i = 0; i < numEntries && nextTagOffset < maxOffset; i++)
            {
                int  tag        = ReadUnsignedShort(stream);
                int  type       = ReadUnsignedShort(stream);
                int  count      = (int)ReadUnsignedInt(stream);
                bool processTag = true;
                // The place to return to to read the next tag
                nextTagOffset = stream.GetPosition() + 4;
                try {
                    // If the tag data can't fit in 4 bytes, the next 4 bytes
                    // contain the starting offset of the data
                    if (count * sizeOfType[type] > 4)
                    {
                        long valueOffset = ReadUnsignedInt(stream);
                        // bounds check offset for EOF
                        if (valueOffset < maxOffset)
                        {
                            stream.Seek(valueOffset);
                        }
                        else
                        {
                            // bad offset pointer .. skip tag
                            processTag = false;
                        }
                    }
                }
                catch (IndexOutOfRangeException) {
                    // if the data type is unknown we should skip this TIFF Field
                    processTag = false;
                }
                if (processTag)
                {
                    fieldIndex.Put(tag, i);
                    Object obj = null;
                    switch (type)
                    {
                    case TIFFField.TIFF_BYTE:
                    case TIFFField.TIFF_SBYTE:
                    case TIFFField.TIFF_UNDEFINED:
                    case TIFFField.TIFF_ASCII: {
                        byte[] bvalues = new byte[count];
                        stream.ReadFully(bvalues, 0, count);
                        if (type == TIFFField.TIFF_ASCII)
                        {
                            // Can be multiple strings
                            int            index     = 0;
                            int            prevIndex = 0;
                            IList <String> v         = new List <String>();
                            while (index < count)
                            {
                                while (index < count && bvalues[index++] != 0)
                                {
                                }
                                // When we encountered zero, means one string has ended
                                v.Add(iText.IO.Util.JavaUtil.GetStringForBytes(bvalues, prevIndex, (index - prevIndex)));
                                prevIndex = index;
                            }
                            count = v.Count;
                            String[] strings = new String[count];
                            for (int c = 0; c < count; c++)
                            {
                                strings[c] = v[c];
                            }
                            obj = strings;
                        }
                        else
                        {
                            obj = bvalues;
                        }
                        break;
                    }

                    case TIFFField.TIFF_SHORT: {
                        char[] cvalues = new char[count];
                        for (j = 0; j < count; j++)
                        {
                            cvalues[j] = (char)ReadUnsignedShort(stream);
                        }
                        obj = cvalues;
                        break;
                    }

                    case TIFFField.TIFF_LONG: {
                        long[] lvalues = new long[count];
                        for (j = 0; j < count; j++)
                        {
                            lvalues[j] = ReadUnsignedInt(stream);
                        }
                        obj = lvalues;
                        break;
                    }

                    case TIFFField.TIFF_RATIONAL: {
                        long[][] llvalues = new long[count][];
                        for (j = 0; j < count; j++)
                        {
                            llvalues[j]    = new long[2];
                            llvalues[j][0] = ReadUnsignedInt(stream);
                            llvalues[j][1] = ReadUnsignedInt(stream);
                        }
                        obj = llvalues;
                        break;
                    }

                    case TIFFField.TIFF_SSHORT: {
                        short[] svalues = new short[count];
                        for (j = 0; j < count; j++)
                        {
                            svalues[j] = ReadShort(stream);
                        }
                        obj = svalues;
                        break;
                    }

                    case TIFFField.TIFF_SLONG: {
                        int[] ivalues = new int[count];
                        for (j = 0; j < count; j++)
                        {
                            ivalues[j] = ReadInt(stream);
                        }
                        obj = ivalues;
                        break;
                    }

                    case TIFFField.TIFF_SRATIONAL: {
                        int[][] iivalues = new int[count][];
                        for (j = 0; j < count; j++)
                        {
                            iivalues[j]    = new int[2];
                            iivalues[j][0] = ReadInt(stream);
                            iivalues[j][1] = ReadInt(stream);
                        }
                        obj = iivalues;
                        break;
                    }

                    case TIFFField.TIFF_FLOAT: {
                        float[] fvalues = new float[count];
                        for (j = 0; j < count; j++)
                        {
                            fvalues[j] = ReadFloat(stream);
                        }
                        obj = fvalues;
                        break;
                    }

                    case TIFFField.TIFF_DOUBLE: {
                        double[] dvalues = new double[count];
                        for (j = 0; j < count; j++)
                        {
                            dvalues[j] = ReadDouble(stream);
                        }
                        obj = dvalues;
                        break;
                    }

                    default: {
                        break;
                    }
                    }
                    fields[i] = new TIFFField(tag, type, count, obj);
                }
                stream.Seek(nextTagOffset);
            }
            // Read the offset of the next IFD.
            try {
                nextIFDOffset = ReadUnsignedInt(stream);
            }
            catch (Exception) {
                // broken tiffs may not have this pointer
                nextIFDOffset = 0;
            }
        }
Пример #11
0
        /// <summary>Reads the font data.</summary>
        /// <exception cref="System.IO.IOException"/>
        protected internal virtual void Process()
        {
            tables = new LinkedDictionary <String, int[]>();
            if (ttcIndex >= 0)
            {
                int dirIdx = ttcIndex;
                if (dirIdx < 0)
                {
                    if (fileName != null)
                    {
                        throw new iText.IO.IOException("the.font.index.for.1.must.be.positive").SetMessageParams(fileName);
                    }
                    else
                    {
                        throw new iText.IO.IOException("the.font.index.must.be.positive");
                    }
                }
                String mainTag = ReadStandardString(4);
                if (!mainTag.Equals("ttcf"))
                {
                    if (fileName != null)
                    {
                        throw new iText.IO.IOException("1.is.not.a.valid.ttc.file").SetMessageParams(fileName);
                    }
                    else
                    {
                        throw new iText.IO.IOException("not.a.valid.ttc.file");
                    }
                }
                raf.SkipBytes(4);
                int dirCount = raf.ReadInt();
                if (dirIdx >= dirCount)
                {
                    if (fileName != null)
                    {
                        throw new iText.IO.IOException("the.font.index.for.1.must.be.between.0.and.2.it.was.3").SetMessageParams(fileName
                                                                                                                                 , dirCount - 1, dirIdx);
                    }
                    else
                    {
                        throw new iText.IO.IOException("the.font.index.must.be.between.0.and.1.it.was.2").SetMessageParams(dirCount
                                                                                                                           - 1, dirIdx);
                    }
                }
                raf.SkipBytes(dirIdx * 4);
                directoryOffset = raf.ReadInt();
            }
            raf.Seek(directoryOffset);
            int ttId = raf.ReadInt();

            if (ttId != 0x00010000 && ttId != 0x4F54544F)
            {
                if (fileName != null)
                {
                    throw new iText.IO.IOException("1.is.not.a.valid.ttf.or.otf.file").SetMessageParams(fileName);
                }
                else
                {
                    throw new iText.IO.IOException("not.a.valid.ttf.or.otf.file");
                }
            }
            int num_tables = raf.ReadUnsignedShort();

            raf.SkipBytes(6);
            for (int k = 0; k < num_tables; ++k)
            {
                String tag = ReadStandardString(4);
                raf.SkipBytes(4);
                int[] table_location = new int[2];
                table_location[0] = raf.ReadInt();
                table_location[1] = raf.ReadInt();
                tables[tag]       = table_location;
            }
            CheckCff();
            ReadHheaTable();
            ReadNameTable();
            ReadHeadTable();
            ReadOs_2Table();
            ReadPostTable();
            ReadGlyphWidths();
            ReadCmapTable();
        }