Example #1
0
 protected internal virtual void GenerateValue()
 {
     System.Diagnostics.Debug.Assert(content != null, "No byte[] content to generate value");
     value = PdfEncodings.ConvertToString(PdfTokenizer.DecodeStringContent(content, hexWriting), null);
 }
Example #2
0
 public PdfLiteral(String content)
     : this(PdfEncodings.ConvertToBytes(content, null))
 {
 }
        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);
            }
        }
Example #4
0
        /// <summary>Reads next frame image</summary>
        /// <exception cref="System.IO.IOException"/>
        private static void ReadFrame(GifImageHelper.GifParameters gif)
        {
            gif.ix = ReadShort(gif);
            // (sub)image position & size
            gif.iy = ReadShort(gif);
            gif.iw = ReadShort(gif);
            gif.ih = ReadShort(gif);
            int packed = gif.input.Read();

            gif.lctFlag = (packed & 0x80) != 0;
            // 1 - local color table flag
            gif.interlace = (packed & 0x40) != 0;
            // 2 - interlace flag
            // 3 - sort flag
            // 4-5 - reserved
            gif.lctSize = 2 << (packed & 7);
            // 6-8 - local color table size
            gif.m_bpc = NewBpc(gif.m_gbpc);
            if (gif.lctFlag)
            {
                gif.m_curr_table = ReadColorTable((packed & 7) + 1, gif);
                // read table
                gif.m_bpc = NewBpc((packed & 7) + 1);
            }
            else
            {
                gif.m_curr_table = gif.m_global_table;
            }
            if (gif.transparency && gif.transIndex >= gif.m_curr_table.Length / 3)
            {
                gif.transparency = false;
            }
            if (gif.transparency && gif.m_bpc == 1)
            {
                // Acrobat 5.05 doesn't like this combination
                byte[] tp = new byte[12];
                System.Array.Copy(gif.m_curr_table, 0, tp, 0, 6);
                gif.m_curr_table = tp;
                gif.m_bpc        = 2;
            }
            bool skipZero = DecodeImageData(gif);

            // decode pixel data
            if (!skipZero)
            {
                Skip(gif);
            }
            try {
                Object[] colorspace = new Object[4];
                colorspace[0] = "/Indexed";
                colorspace[1] = "/DeviceRGB";
                int len = gif.m_curr_table.Length;
                colorspace[2] = len / 3 - 1;
                colorspace[3] = PdfEncodings.ConvertToString(gif.m_curr_table, null);
                IDictionary <String, Object> ad = new Dictionary <String, Object>();
                ad["ColorSpace"] = colorspace;
                RawImageData img = new RawImageData(gif.m_out, ImageType.NONE);
                RawImageHelper.UpdateRawImageParameters(img, gif.iw, gif.ih, 1, gif.m_bpc, gif.m_out);
                RawImageHelper.UpdateImageAttributes(img, ad);
                gif.image.AddFrame(img);
                if (gif.transparency)
                {
                    img.SetTransparency(new int[] { gif.transIndex, gif.transIndex });
                }
            }
            catch (Exception e) {
                throw new iText.IO.IOException(iText.IO.IOException.GifImageException, e);
            }
        }
        public override int AppendAnyGlyph(String text, int from, IList <Glyph> glyphs)
        {
            int process = 1;

            if (cidFontType == CID_FONT_TYPE_0)
            {
                if (cmapEncoding.IsDirect())
                {
                    Glyph glyph = fontProgram.GetGlyphByCode((int)text[from]);
                    if (glyph != null)
                    {
                        glyphs.Add(glyph);
                    }
                }
                else
                {
                    int ch;
                    if (iText.IO.Util.TextUtil.IsSurrogatePair(text, from))
                    {
                        ch      = iText.IO.Util.TextUtil.ConvertToUtf32(text, from);
                        process = 2;
                    }
                    else
                    {
                        ch = text[from];
                    }
                    glyphs.Add(GetGlyph(ch));
                }
            }
            else
            {
                if (cidFontType == CID_FONT_TYPE_2)
                {
                    TrueTypeFont ttf = (TrueTypeFont)fontProgram;
                    if (ttf.IsFontSpecific())
                    {
                        byte[] b = PdfEncodings.ConvertToBytes(text, "symboltt");
                        if (b.Length > 0)
                        {
                            Glyph glyph = fontProgram.GetGlyph(b[0] & 0xff);
                            if (glyph != null)
                            {
                                glyphs.Add(glyph);
                            }
                        }
                    }
                    else
                    {
                        int ch;
                        if (iText.IO.Util.TextUtil.IsSurrogatePair(text, from))
                        {
                            ch      = iText.IO.Util.TextUtil.ConvertToUtf32(text, from);
                            process = 2;
                        }
                        else
                        {
                            ch = text[from];
                        }
                        glyphs.Add(GetGlyph(ch));
                    }
                }
                else
                {
                    throw new PdfException("Font has no suitable cmap.");
                }
            }
            return(process);
        }
        public override GlyphLine CreateGlyphLine(String content)
        {
            IList <Glyph> glyphs = new List <Glyph>();

            if (cidFontType == CID_FONT_TYPE_0)
            {
                int len = content.Length;
                if (cmapEncoding.IsDirect())
                {
                    for (int k = 0; k < len; ++k)
                    {
                        Glyph glyph = fontProgram.GetGlyphByCode((int)content[k]);
                        if (glyph != null)
                        {
                            glyphs.Add(glyph);
                        }
                    }
                }
                else
                {
                    for (int k = 0; k < len; ++k)
                    {
                        int ch;
                        if (iText.IO.Util.TextUtil.IsSurrogatePair(content, k))
                        {
                            ch = iText.IO.Util.TextUtil.ConvertToUtf32(content, k);
                            k++;
                        }
                        else
                        {
                            ch = content[k];
                        }
                        glyphs.Add(GetGlyph(ch));
                    }
                }
            }
            else
            {
                if (cidFontType == CID_FONT_TYPE_2)
                {
                    int len = content.Length;
                    if (fontProgram.IsFontSpecific())
                    {
                        byte[] b = PdfEncodings.ConvertToBytes(content, "symboltt");
                        len = b.Length;
                        for (int k = 0; k < len; ++k)
                        {
                            Glyph glyph = fontProgram.GetGlyph(b[k] & 0xff);
                            if (glyph != null)
                            {
                                glyphs.Add(glyph);
                            }
                        }
                    }
                    else
                    {
                        for (int k = 0; k < len; ++k)
                        {
                            int val;
                            if (iText.IO.Util.TextUtil.IsSurrogatePair(content, k))
                            {
                                val = iText.IO.Util.TextUtil.ConvertToUtf32(content, k);
                                k++;
                            }
                            else
                            {
                                val = content[k];
                            }
                            glyphs.Add(GetGlyph(val));
                        }
                    }
                }
                else
                {
                    throw new PdfException("Font has no suitable cmap.");
                }
            }
            return(new GlyphLine(glyphs));
        }
Example #7
0
        /// <exception cref="System.IO.IOException"/>
        private static void ReadPng(Stream pngStream, PngImageHelper.PngParameters png)
        {
            for (int i = 0; i < PNGID.Length; i++)
            {
                if (PNGID[i] != pngStream.Read())
                {
                    throw new System.IO.IOException("file.is.not.a.valid.png");
                }
            }
            byte[] buffer = new byte[TRANSFERSIZE];
            while (true)
            {
                int    len    = GetInt(pngStream);
                String marker = GetString(pngStream);
                if (len < 0 || !CheckMarker(marker))
                {
                    throw new System.IO.IOException("corrupted.png.file");
                }
                if (IDAT.Equals(marker))
                {
                    int size;
                    while (len != 0)
                    {
                        size = pngStream.JRead(buffer, 0, Math.Min(len, TRANSFERSIZE));
                        if (size < 0)
                        {
                            return;
                        }
                        png.idat.Write(buffer, 0, size);
                        len -= size;
                    }
                }
                else
                {
                    if (tRNS.Equals(marker))
                    {
                        switch (png.colorType)
                        {
                        case 0: {
                            if (len >= 2)
                            {
                                len -= 2;
                                int gray = GetWord(pngStream);
                                if (png.bitDepth == 16)
                                {
                                    png.transRedGray = gray;
                                }
                                else
                                {
                                    png.additional.Put("Mask", MessageFormatUtil.Format("[{0} {1}]", gray, gray));
                                }
                            }
                            break;
                        }

                        case 2: {
                            if (len >= 6)
                            {
                                len -= 6;
                                int red   = GetWord(pngStream);
                                int green = GetWord(pngStream);
                                int blue  = GetWord(pngStream);
                                if (png.bitDepth == 16)
                                {
                                    png.transRedGray = red;
                                    png.transGreen   = green;
                                    png.transBlue    = blue;
                                }
                                else
                                {
                                    png.additional.Put("Mask", MessageFormatUtil.Format("[{0} {1} {2} {3} {4} {5}]", red, red, green, green, blue
                                                                                        , blue));
                                }
                            }
                            break;
                        }

                        case 3: {
                            if (len > 0)
                            {
                                png.trans = new byte[len];
                                for (int k = 0; k < len; ++k)
                                {
                                    png.trans[k] = (byte)pngStream.Read();
                                }
                                len = 0;
                            }
                            break;
                        }
                        }
                        StreamUtil.Skip(pngStream, len);
                    }
                    else
                    {
                        if (IHDR.Equals(marker))
                        {
                            png.width             = GetInt(pngStream);
                            png.height            = GetInt(pngStream);
                            png.bitDepth          = pngStream.Read();
                            png.colorType         = pngStream.Read();
                            png.compressionMethod = pngStream.Read();
                            png.filterMethod      = pngStream.Read();
                            png.interlaceMethod   = pngStream.Read();
                        }
                        else
                        {
                            if (PLTE.Equals(marker))
                            {
                                if (png.colorType == 3)
                                {
                                    Object[] colorspace = new Object[4];
                                    colorspace[0] = "/Indexed";
                                    colorspace[1] = GetColorspace(png);
                                    colorspace[2] = len / 3 - 1;
                                    ByteBuffer colorTableBuf = new ByteBuffer();
                                    while ((len--) > 0)
                                    {
                                        colorTableBuf.Append(pngStream.Read());
                                    }
                                    png.colorTable = colorTableBuf.ToByteArray();
                                    colorspace[3]  = PdfEncodings.ConvertToString(png.colorTable, null);
                                    png.additional.Put("ColorSpace", colorspace);
                                }
                                else
                                {
                                    StreamUtil.Skip(pngStream, len);
                                }
                            }
                            else
                            {
                                if (pHYs.Equals(marker))
                                {
                                    int dx   = GetInt(pngStream);
                                    int dy   = GetInt(pngStream);
                                    int unit = pngStream.Read();
                                    if (unit == 1)
                                    {
                                        png.dpiX = (int)(dx * 0.0254f + 0.5f);
                                        png.dpiY = (int)(dy * 0.0254f + 0.5f);
                                    }
                                    else
                                    {
                                        if (dy != 0)
                                        {
                                            png.XYRatio = (float)dx / (float)dy;
                                        }
                                    }
                                }
                                else
                                {
                                    if (cHRM.Equals(marker))
                                    {
                                        png.xW      = GetInt(pngStream) / 100000f;
                                        png.yW      = GetInt(pngStream) / 100000f;
                                        png.xR      = GetInt(pngStream) / 100000f;
                                        png.yR      = GetInt(pngStream) / 100000f;
                                        png.xG      = GetInt(pngStream) / 100000f;
                                        png.yG      = GetInt(pngStream) / 100000f;
                                        png.xB      = GetInt(pngStream) / 100000f;
                                        png.yB      = GetInt(pngStream) / 100000f;
                                        png.hasCHRM = !(Math.Abs(png.xW) < 0.0001f || Math.Abs(png.yW) < 0.0001f || Math.Abs(png.xR) < 0.0001f ||
                                                        Math.Abs(png.yR) < 0.0001f || Math.Abs(png.xG) < 0.0001f || Math.Abs(png.yG) < 0.0001f || Math.Abs(png
                                                                                                                                                           .xB) < 0.0001f || Math.Abs(png.yB) < 0.0001f);
                                    }
                                    else
                                    {
                                        if (sRGB.Equals(marker))
                                        {
                                            int ri = pngStream.Read();
                                            png.intent  = intents[ri];
                                            png.gamma   = 2.2f;
                                            png.xW      = 0.3127f;
                                            png.yW      = 0.329f;
                                            png.xR      = 0.64f;
                                            png.yR      = 0.33f;
                                            png.xG      = 0.3f;
                                            png.yG      = 0.6f;
                                            png.xB      = 0.15f;
                                            png.yB      = 0.06f;
                                            png.hasCHRM = true;
                                        }
                                        else
                                        {
                                            if (gAMA.Equals(marker))
                                            {
                                                int gm = GetInt(pngStream);
                                                if (gm != 0)
                                                {
                                                    png.gamma = 100000f / gm;
                                                    if (!png.hasCHRM)
                                                    {
                                                        png.xW      = 0.3127f;
                                                        png.yW      = 0.329f;
                                                        png.xR      = 0.64f;
                                                        png.yR      = 0.33f;
                                                        png.xG      = 0.3f;
                                                        png.yG      = 0.6f;
                                                        png.xB      = 0.15f;
                                                        png.yB      = 0.06f;
                                                        png.hasCHRM = true;
                                                    }
                                                }
                                            }
                                            else
                                            {
                                                if (iCCP.Equals(marker))
                                                {
                                                    do
                                                    {
                                                        --len;
                                                    }while (pngStream.Read() != 0);
                                                    pngStream.Read();
                                                    --len;
                                                    byte[] icccom = new byte[len];
                                                    int    p      = 0;
                                                    while (len > 0)
                                                    {
                                                        int r = pngStream.JRead(icccom, p, len);
                                                        if (r < 0)
                                                        {
                                                            throw new System.IO.IOException("premature.end.of.file");
                                                        }
                                                        p   += r;
                                                        len -= r;
                                                    }
                                                    byte[] iccp = FilterUtil.FlateDecode(icccom, true);
                                                    icccom = null;
                                                    try {
                                                        png.iccProfile = IccProfile.GetInstance(iccp);
                                                    }
                                                    catch (Exception) {
                                                        png.iccProfile = null;
                                                    }
                                                }
                                                else
                                                {
                                                    if (IEND.Equals(marker))
                                                    {
                                                        break;
                                                    }
                                                    else
                                                    {
                                                        StreamUtil.Skip(pngStream, len);
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                StreamUtil.Skip(pngStream, 4);
            }
        }
        /// <summary>Outputs a <CODE>double</CODE> into a format suitable for the PDF.</summary>
        /// <param name="d">a double</param>
        /// <param name="buf">a ByteBufferOutputStream</param>
        /// <returns>
        /// the <CODE>String</CODE> representation of the <CODE>double</CODE> if
        /// <CODE>buf</CODE> is <CODE>null</CODE>. If <CODE>buf</CODE> is <B>not</B> <CODE>null</CODE>,
        /// then the double is appended directly to the buffer and this methods returns <CODE>null</CODE>.
        /// </returns>
        public static String FormatDouble(double d, iText.Kernel.Pdf.ByteBufferOutputStream
                                          buf)
        {
            if (HIGH_PRECISION)
            {
                String sform = DecimalFormatUtil.FormatNumber(d, "0.######");
                if (buf == null)
                {
                    return(sform);
                }
                else
                {
                    buf.Append(sform);
                    return(null);
                }
            }
            bool negative = false;

            if (Math.Abs(d) < 0.000015)
            {
                if (buf != null)
                {
                    buf.Append(ZERO);
                    return(null);
                }
                else
                {
                    return("0");
                }
            }
            if (d < 0)
            {
                negative = true;
                d        = -d;
            }
            if (d < 1.0)
            {
                d += 0.000005;
                if (d >= 1)
                {
                    if (negative)
                    {
                        if (buf != null)
                        {
                            buf.Append((byte)'-');
                            buf.Append((byte)'1');
                            return(null);
                        }
                        else
                        {
                            return("-1");
                        }
                    }
                    else
                    {
                        if (buf != null)
                        {
                            buf.Append((byte)'1');
                            return(null);
                        }
                        else
                        {
                            return("1");
                        }
                    }
                }
                if (buf != null)
                {
                    int v = (int)(d * 100000);
                    if (negative)
                    {
                        buf.Append((byte)'-');
                    }
                    buf.Append((byte)'0');
                    buf.Append((byte)'.');
                    buf.Append((byte)(v / 10000 + ZERO));
                    if (v % 10000 != 0)
                    {
                        buf.Append((byte)((v / 1000) % 10 + ZERO));
                        if (v % 1000 != 0)
                        {
                            buf.Append((byte)((v / 100) % 10 + ZERO));
                            if (v % 100 != 0)
                            {
                                buf.Append((byte)((v / 10) % 10 + ZERO));
                                if (v % 10 != 0)
                                {
                                    buf.Append((byte)((v) % 10 + ZERO));
                                }
                            }
                        }
                    }
                    return(null);
                }
                else
                {
                    int           x   = 100000;
                    int           v   = (int)(d * x);
                    StringBuilder res = new StringBuilder();
                    if (negative)
                    {
                        res.Append('-');
                    }
                    res.Append("0.");
                    while (v < x / 10)
                    {
                        res.Append('0');
                        x /= 10;
                    }
                    res.Append(v);
                    int cut = res.Length - 1;
                    while (res[cut] == '0')
                    {
                        --cut;
                    }
                    res.Length = cut + 1;
                    return(res.ToString());
                }
            }
            else
            {
                if (d <= 32767)
                {
                    d += 0.005;
                    int v = (int)(d * 100);
                    if (v < byteCacheSize && byteCache[v] != null)
                    {
                        if (buf != null)
                        {
                            if (negative)
                            {
                                buf.Append((byte)'-');
                            }
                            buf.Append(byteCache[v]);
                            return(null);
                        }
                        else
                        {
                            String tmp = PdfEncodings.ConvertToString(byteCache[v], null);
                            if (negative)
                            {
                                tmp = "-" + tmp;
                            }
                            return(tmp);
                        }
                    }
                    if (buf != null)
                    {
                        if (v < byteCacheSize)
                        {
                            //create the cachebyte[]
                            byte[] cache;
                            int    size = 0;
                            if (v >= 1000000)
                            {
                                //the original number is >=10000, we need 5 more bytes
                                size += 5;
                            }
                            else
                            {
                                if (v >= 100000)
                                {
                                    //the original number is >=1000, we need 4 more bytes
                                    size += 4;
                                }
                                else
                                {
                                    if (v >= 10000)
                                    {
                                        //the original number is >=100, we need 3 more bytes
                                        size += 3;
                                    }
                                    else
                                    {
                                        if (v >= 1000)
                                        {
                                            //the original number is >=10, we need 2 more bytes
                                            size += 2;
                                        }
                                        else
                                        {
                                            if (v >= 100)
                                            {
                                                //the original number is >=1, we need 1 more bytes
                                                size += 1;
                                            }
                                        }
                                    }
                                }
                            }
                            //now we must check if we have a decimal number
                            if (v % 100 != 0)
                            {
                                //yes, do not forget the "."
                                size += 2;
                            }
                            if (v % 10 != 0)
                            {
                                size++;
                            }
                            cache = new byte[size];
                            int add = 0;
                            if (v >= 1000000)
                            {
                                cache[add++] = bytes[(v / 1000000)];
                            }
                            if (v >= 100000)
                            {
                                cache[add++] = bytes[(v / 100000) % 10];
                            }
                            if (v >= 10000)
                            {
                                cache[add++] = bytes[(v / 10000) % 10];
                            }
                            if (v >= 1000)
                            {
                                cache[add++] = bytes[(v / 1000) % 10];
                            }
                            if (v >= 100)
                            {
                                cache[add++] = bytes[(v / 100) % 10];
                            }
                            if (v % 100 != 0)
                            {
                                cache[add++] = (byte)'.';
                                cache[add++] = bytes[(v / 10) % 10];
                                if (v % 10 != 0)
                                {
                                    cache[add++] = bytes[v % 10];
                                }
                            }
                            byteCache[v] = cache;
                        }
                        if (negative)
                        {
                            buf.Append((byte)'-');
                        }
                        if (v >= 1000000)
                        {
                            buf.Append(bytes[(v / 1000000)]);
                        }
                        if (v >= 100000)
                        {
                            buf.Append(bytes[(v / 100000) % 10]);
                        }
                        if (v >= 10000)
                        {
                            buf.Append(bytes[(v / 10000) % 10]);
                        }
                        if (v >= 1000)
                        {
                            buf.Append(bytes[(v / 1000) % 10]);
                        }
                        if (v >= 100)
                        {
                            buf.Append(bytes[(v / 100) % 10]);
                        }
                        if (v % 100 != 0)
                        {
                            buf.Append((byte)'.');
                            buf.Append(bytes[(v / 10) % 10]);
                            if (v % 10 != 0)
                            {
                                buf.Append(bytes[v % 10]);
                            }
                        }
                        return(null);
                    }
                    else
                    {
                        StringBuilder res = new StringBuilder();
                        if (negative)
                        {
                            res.Append('-');
                        }
                        if (v >= 1000000)
                        {
                            res.Append(chars[(v / 1000000)]);
                        }
                        if (v >= 100000)
                        {
                            res.Append(chars[(v / 100000) % 10]);
                        }
                        if (v >= 10000)
                        {
                            res.Append(chars[(v / 10000) % 10]);
                        }
                        if (v >= 1000)
                        {
                            res.Append(chars[(v / 1000) % 10]);
                        }
                        if (v >= 100)
                        {
                            res.Append(chars[(v / 100) % 10]);
                        }
                        if (v % 100 != 0)
                        {
                            res.Append('.');
                            res.Append(chars[(v / 10) % 10]);
                            if (v % 10 != 0)
                            {
                                res.Append(chars[v % 10]);
                            }
                        }
                        return(res.ToString());
                    }
                }
                else
                {
                    d += 0.5;
                    long v = (long)d;
                    if (negative)
                    {
                        return("-" + System.Convert.ToString(v));
                    }
                    else
                    {
                        return(System.Convert.ToString(v));
                    }
                }
            }
        }
Example #9
0
        private static PdfStream CreatePdfStream(ImageData image, iText.Kernel.Pdf.Xobject.PdfImageXObject imageMask
                                                 )
        {
            PdfStream stream;

            if (image.GetOriginalType() == ImageType.RAW)
            {
                RawImageHelper.UpdateImageAttributes((RawImageData)image, null);
            }
            stream = new PdfStream(image.GetData());
            String filter = image.GetFilter();

            if (filter != null && "JPXDecode".Equals(filter) && image.GetColorSpace() <= 0)
            {
                stream.SetCompressionLevel(CompressionConstants.NO_COMPRESSION);
                image.SetBpc(0);
            }
            stream.Put(PdfName.Type, PdfName.XObject);
            stream.Put(PdfName.Subtype, PdfName.Image);
            PdfDictionary decodeParms = CreateDictionaryFromMap(stream, image.GetDecodeParms());

            if (decodeParms != null)
            {
                stream.Put(PdfName.DecodeParms, decodeParms);
            }
            if (!(image is PngImageData))
            {
                PdfName colorSpace;
                switch (image.GetColorSpace())
                {
                case 1: {
                    colorSpace = PdfName.DeviceGray;
                    break;
                }

                case 3: {
                    colorSpace = PdfName.DeviceRGB;
                    break;
                }

                default: {
                    colorSpace = PdfName.DeviceCMYK;
                    break;
                }
                }
                stream.Put(PdfName.ColorSpace, colorSpace);
            }
            if (image.GetBpc() != 0)
            {
                stream.Put(PdfName.BitsPerComponent, new PdfNumber(image.GetBpc()));
            }
            if (image.GetFilter() != null)
            {
                stream.Put(PdfName.Filter, new PdfName(image.GetFilter()));
            }
            //TODO: return to this later
            //        if (image.getLayer() != null)
            //            put(PdfName.OC, image.getLayer().getRef());
            if (image.GetColorSpace() == -1)
            {
                stream.Remove(PdfName.ColorSpace);
            }
            PdfDictionary additional = null;

            if (image is PngImageData)
            {
                PngImageData pngImage = (PngImageData)image;
                if (pngImage.IsIndexed())
                {
                    PdfArray colorspace = new PdfArray();
                    colorspace.Add(PdfName.Indexed);
                    colorspace.Add(GetColorSpaceInfo(pngImage));
                    if ((pngImage.GetColorPalette() != null) && (pngImage.GetColorPalette().Length > 0))
                    {
                        //Each palette entry is a three-byte series, so the number of entries is calculated as the length
                        //of the stream divided by 3. The number below specifies the maximum valid index value (starting from 0 up)
                        colorspace.Add(new PdfNumber(pngImage.GetColorPalette().Length / 3 - 1));
                    }
                    if (pngImage.GetColorPalette() != null)
                    {
                        colorspace.Add(new PdfString(PdfEncodings.ConvertToString(pngImage.GetColorPalette(), null)));
                    }
                    stream.Put(PdfName.ColorSpace, colorspace);
                }
                else
                {
                    stream.Put(PdfName.ColorSpace, GetColorSpaceInfo(pngImage));
                }
            }
            additional = CreateDictionaryFromMap(stream, image.GetImageAttributes());
            if (additional != null)
            {
                stream.PutAll(additional);
            }
            IccProfile iccProfile = image.GetProfile();

            if (iccProfile != null)
            {
                PdfStream iccProfileStream   = PdfCieBasedCs.IccBased.GetIccProfileStream(iccProfile);
                PdfArray  iccBasedColorSpace = new PdfArray();
                iccBasedColorSpace.Add(PdfName.ICCBased);
                iccBasedColorSpace.Add(iccProfileStream);
                PdfObject colorSpaceObject          = stream.Get(PdfName.ColorSpace);
                bool      iccProfileShouldBeApplied = true;
                if (colorSpaceObject != null)
                {
                    PdfColorSpace cs = PdfColorSpace.MakeColorSpace(colorSpaceObject);
                    if (cs == null)
                    {
                        LogManager.GetLogger(typeof(iText.Kernel.Pdf.Xobject.PdfImageXObject)).Error(iText.IO.LogMessageConstant.IMAGE_HAS_INCORRECT_OR_UNSUPPORTED_COLOR_SPACE_OVERRIDDEN_BY_ICC_PROFILE
                                                                                                     );
                    }
                    else
                    {
                        if (cs is PdfSpecialCs.Indexed)
                        {
                            PdfColorSpace baseCs = ((PdfSpecialCs.Indexed)cs).GetBaseCs();
                            if (baseCs == null)
                            {
                                LogManager.GetLogger(typeof(iText.Kernel.Pdf.Xobject.PdfImageXObject)).Error(iText.IO.LogMessageConstant.IMAGE_HAS_INCORRECT_OR_UNSUPPORTED_BASE_COLOR_SPACE_IN_INDEXED_COLOR_SPACE_OVERRIDDEN_BY_ICC_PROFILE
                                                                                                             );
                            }
                            else
                            {
                                if (baseCs.GetNumberOfComponents() != iccProfile.GetNumComponents())
                                {
                                    LogManager.GetLogger(typeof(iText.Kernel.Pdf.Xobject.PdfImageXObject)).Error(iText.IO.LogMessageConstant.IMAGE_HAS_ICC_PROFILE_WITH_INCOMPATIBLE_NUMBER_OF_COLOR_COMPONENTS_COMPARED_TO_BASE_COLOR_SPACE_IN_INDEXED_COLOR_SPACE
                                                                                                                 );
                                    iccProfileShouldBeApplied = false;
                                }
                                else
                                {
                                    iccProfileStream.Put(PdfName.Alternate, baseCs.GetPdfObject());
                                }
                            }
                            if (iccProfileShouldBeApplied)
                            {
                                ((PdfArray)colorSpaceObject).Set(1, iccBasedColorSpace);
                                iccProfileShouldBeApplied = false;
                            }
                        }
                        else
                        {
                            if (cs.GetNumberOfComponents() != iccProfile.GetNumComponents())
                            {
                                LogManager.GetLogger(typeof(iText.Kernel.Pdf.Xobject.PdfImageXObject)).Error(iText.IO.LogMessageConstant.IMAGE_HAS_ICC_PROFILE_WITH_INCOMPATIBLE_NUMBER_OF_COLOR_COMPONENTS_COMPARED_TO_COLOR_SPACE
                                                                                                             );
                                iccProfileShouldBeApplied = false;
                            }
                            else
                            {
                                iccProfileStream.Put(PdfName.Alternate, colorSpaceObject);
                            }
                        }
                    }
                }
                if (iccProfileShouldBeApplied)
                {
                    stream.Put(PdfName.ColorSpace, iccBasedColorSpace);
                }
            }
            if (image.IsMask() && (image.GetBpc() == 1 || image.GetBpc() > 0xff))
            {
                stream.Put(PdfName.ImageMask, PdfBoolean.TRUE);
            }
            if (imageMask != null)
            {
                if (imageMask.softMask)
                {
                    stream.Put(PdfName.SMask, imageMask.GetPdfObject());
                }
                else
                {
                    if (imageMask.mask)
                    {
                        stream.Put(PdfName.Mask, imageMask.GetPdfObject());
                    }
                }
            }
            ImageData mask = image.GetImageMask();

            if (mask != null)
            {
                if (mask.IsSoftMask())
                {
                    stream.Put(PdfName.SMask, new iText.Kernel.Pdf.Xobject.PdfImageXObject(image.GetImageMask()).GetPdfObject(
                                   ));
                }
                else
                {
                    if (mask.IsMask())
                    {
                        stream.Put(PdfName.Mask, new iText.Kernel.Pdf.Xobject.PdfImageXObject(image.GetImageMask()).GetPdfObject()
                                   );
                    }
                }
            }
            if (image.GetDecode() != null)
            {
                stream.Put(PdfName.Decode, new PdfArray(image.GetDecode()));
            }
            if (image.IsMask() && image.IsInverted())
            {
                stream.Put(PdfName.Decode, new PdfArray(new float[] { 1, 0 }));
            }
            if (image.IsInterpolation())
            {
                stream.Put(PdfName.Interpolate, PdfBoolean.TRUE);
            }
            // deal with transparency
            int[] transparency = image.GetTransparency();
            if (transparency != null && !image.IsMask() && imageMask == null)
            {
                PdfArray t = new PdfArray();
                foreach (int transparencyItem in transparency)
                {
                    t.Add(new PdfNumber(transparencyItem));
                }
                stream.Put(PdfName.Mask, t);
            }
            stream.Put(PdfName.Width, new PdfNumber(image.GetWidth()));
            stream.Put(PdfName.Height, new PdfNumber(image.GetHeight()));
            return(stream);
        }