예제 #1
0
        private static void ProcessTiffImageColor(TIFFDirectory dir, RandomAccessFileOrArray s, TiffImageHelper.TiffParameters
                                                  tiff)
        {
            try {
                int            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;
                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 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;
                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 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];
                            System.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];
                            System.Array.Copy(jpeg, 0, jpegwithtables, 0, 2);
                            System.Array.Copy(tables, 0, jpegwithtables, 2, tables.Length);
                            System.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.Close();
                            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_1 = 0; k_1 < palette.Length; ++k_1)
                        {
                            if (palette[k_1] != 0)
                            {
                                colormapBroken = false;
                                break;
                            }
                        }
                        if (colormapBroken)
                        {
                            for (int k_2 = 0; k_2 < gColor; ++k_2)
                            {
                                palette[k_2 * 3]     = (byte)rgb[k_2];
                                palette[k_2 * 3 + 1] = (byte)rgb[k_2 + gColor];
                                palette[k_2 * 3 + 2] = (byte)rgb[k_2 + 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["ColorSpace"] = indexed;
                    }
                }
                if (photometric == TIFFConstants.PHOTOMETRIC_MINISWHITE)
                {
                    tiff.image.SetInverted(true);
                }
                if (rotation != 0)
                {
                    tiff.image.SetRotation(rotation);
                }
                if (extraSamples > 0)
                {
                    mzip.Close();
                    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);
            }
        }
예제 #2
0
        /// <exception cref="System.IO.IOException"/>
        private static void ProcessPng(Stream pngStream, PngImageHelper.PngParameters png)
        {
            ReadPng(pngStream, png);
            if (png.iccProfile != null && png.iccProfile.GetNumComponents() != GetExpectedNumberOfColorComponents(png)
                )
            {
                LogManager.GetLogger(typeof(PngImageHelper)).Warn(iText.IO.LogMessageConstant.PNG_IMAGE_HAS_ICC_PROFILE_WITH_INCOMPATIBLE_NUMBER_OF_COLOR_COMPONENTS
                                                                  );
            }
            try {
                int pal0   = 0;
                int palIdx = 0;
                png.palShades = false;
                if (png.trans != null)
                {
                    for (int k = 0; k < png.trans.Length; ++k)
                    {
                        int n = png.trans[k] & 0xff;
                        if (n == 0)
                        {
                            ++pal0;
                            palIdx = k;
                        }
                        if (n != 0 && n != 255)
                        {
                            png.palShades = true;
                            break;
                        }
                    }
                }
                if ((png.colorType & 4) != 0)
                {
                    png.palShades = true;
                }
                png.genBWMask = (!png.palShades && (pal0 > 1 || png.transRedGray >= 0));
                if (!png.palShades && !png.genBWMask && pal0 == 1)
                {
                    png.additional.Put("Mask", new int[] { palIdx, palIdx });
                }
                bool needDecode = (png.interlaceMethod == 1) || (png.bitDepth == 16) || ((png.colorType & 4) != 0) || png.
                                  palShades || png.genBWMask;
                switch (png.colorType)
                {
                case 0: {
                    png.inputBands = 1;
                    break;
                }

                case 2: {
                    png.inputBands = 3;
                    break;
                }

                case 3: {
                    png.inputBands = 1;
                    break;
                }

                case 4: {
                    png.inputBands = 2;
                    break;
                }

                case 6: {
                    png.inputBands = 4;
                    break;
                }
                }
                if (needDecode)
                {
                    DecodeIdat(png);
                }
                int components = png.inputBands;
                if ((png.colorType & 4) != 0)
                {
                    --components;
                }
                int bpc = png.bitDepth;
                if (bpc == 16)
                {
                    bpc = 8;
                }
                if (png.imageData != null)
                {
                    if (png.colorType == 3)
                    {
                        RawImageHelper.UpdateRawImageParameters(png.image, png.width, png.height, components, bpc, png.imageData);
                    }
                    else
                    {
                        RawImageHelper.UpdateRawImageParameters(png.image, png.width, png.height, components, bpc, png.imageData,
                                                                null);
                    }
                }
                else
                {
                    RawImageHelper.UpdateRawImageParameters(png.image, png.width, png.height, components, bpc, png.idat.ToArray
                                                                ());
                    png.image.SetDeflated(true);
                    IDictionary <String, Object> decodeparms = new Dictionary <String, Object>();
                    decodeparms.Put("BitsPerComponent", png.bitDepth);
                    decodeparms.Put("Predictor", 15);
                    decodeparms.Put("Columns", png.width);
                    decodeparms.Put("Colors", (png.colorType == 3 || (png.colorType & 2) == 0) ? 1 : 3);
                    png.image.decodeParms = decodeparms;
                }
                if (png.additional.Get("ColorSpace") == null)
                {
                    png.additional.Put("ColorSpace", GetColorspace(png));
                }
                if (png.intent != null)
                {
                    png.additional.Put("Intent", png.intent);
                }
                if (png.iccProfile != null)
                {
                    png.image.SetProfile(png.iccProfile);
                }
                if (png.palShades)
                {
                    RawImageData im2 = (RawImageData)ImageDataFactory.CreateRawImage(null);
                    RawImageHelper.UpdateRawImageParameters(im2, png.width, png.height, 1, 8, png.smask);
                    im2.MakeMask();
                    png.image.SetImageMask(im2);
                }
                if (png.genBWMask)
                {
                    RawImageData im2 = (RawImageData)ImageDataFactory.CreateRawImage(null);
                    RawImageHelper.UpdateRawImageParameters(im2, png.width, png.height, 1, 1, png.smask);
                    im2.MakeMask();
                    png.image.SetImageMask(im2);
                }
                png.image.SetDpi(png.dpiX, png.dpiY);
                png.image.SetXYRatio(png.XYRatio);
            }
            catch (Exception e) {
                throw new iText.IO.IOException(iText.IO.IOException.PngImageException, e);
            }
        }
예제 #3
0
        /// <exception cref="System.IO.IOException"/>
        private static void ProcessPng(Stream pngStream, PngImageHelper.PngParameters png)
        {
            ReadPng(pngStream, png);
            try {
                int pal0   = 0;
                int palIdx = 0;
                png.palShades = false;
                if (png.trans != null)
                {
                    for (int k = 0; k < png.trans.Length; ++k)
                    {
                        int n = png.trans[k] & 0xff;
                        if (n == 0)
                        {
                            ++pal0;
                            palIdx = k;
                        }
                        if (n != 0 && n != 255)
                        {
                            png.palShades = true;
                            break;
                        }
                    }
                }
                if ((png.colorType & 4) != 0)
                {
                    png.palShades = true;
                }
                png.genBWMask = (!png.palShades && (pal0 > 1 || png.transRedGray >= 0));
                if (!png.palShades && !png.genBWMask && pal0 == 1)
                {
                    png.additional["Mask"] = String.Format("[{0} {1}]", palIdx, palIdx);
                }
                bool needDecode = (png.interlaceMethod == 1) || (png.bitDepth == 16) || ((png.colorType & 4) != 0) || png.
                                  palShades || png.genBWMask;
                switch (png.colorType)
                {
                case 0: {
                    png.inputBands = 1;
                    break;
                }

                case 2: {
                    png.inputBands = 3;
                    break;
                }

                case 3: {
                    png.inputBands = 1;
                    break;
                }

                case 4: {
                    png.inputBands = 2;
                    break;
                }

                case 6: {
                    png.inputBands = 4;
                    break;
                }
                }
                if (needDecode)
                {
                    DecodeIdat(png);
                }
                int components = png.inputBands;
                if ((png.colorType & 4) != 0)
                {
                    --components;
                }
                int bpc = png.bitDepth;
                if (bpc == 16)
                {
                    bpc = 8;
                }
                if (png.imageData != null)
                {
                    if (png.colorType == 3)
                    {
                        RawImageHelper.UpdateRawImageParameters(png.image, png.width, png.height, components, bpc, png.imageData);
                    }
                    else
                    {
                        RawImageHelper.UpdateRawImageParameters(png.image, png.width, png.height, components, bpc, png.imageData,
                                                                null);
                    }
                }
                else
                {
                    RawImageHelper.UpdateRawImageParameters(png.image, png.width, png.height, components, bpc, png.idat.ToArray
                                                                ());
                    png.image.SetDeflated(true);
                    IDictionary <String, Object> decodeparms = new Dictionary <String, Object>();
                    decodeparms["BitsPerComponent"] = png.bitDepth;
                    decodeparms["Predictor"]        = 15;
                    decodeparms["Columns"]          = png.width;
                    decodeparms["Colors"]           = (png.colorType == 3 || (png.colorType & 2) == 0) ? 1 : 3;
                    png.image.decodeParms           = decodeparms;
                }
                if (png.additional.Get("ColorSpace") == null)
                {
                    png.additional["ColorSpace"] = GetColorspace(png);
                }
                if (png.intent != null)
                {
                    png.additional["Intent"] = png.intent;
                }
                if (png.iccProfile != null)
                {
                    png.image.SetProfile(png.iccProfile);
                }
                if (png.palShades)
                {
                    RawImageData im2 = (RawImageData)ImageDataFactory.CreateRawImage(null);
                    RawImageHelper.UpdateRawImageParameters(im2, png.width, png.height, 1, 8, png.smask);
                    im2.MakeMask();
                    png.image.SetImageMask(im2);
                }
                if (png.genBWMask)
                {
                    RawImageData im2 = (RawImageData)ImageDataFactory.CreateRawImage(null);
                    RawImageHelper.UpdateRawImageParameters(im2, png.width, png.height, 1, 1, png.smask);
                    im2.MakeMask();
                    png.image.SetImageMask(im2);
                }
                png.image.SetDpi(png.dpiX, png.dpiY);
                png.image.SetXYRatio(png.XYRatio);
            }
            catch (Exception e) {
                throw new iText.IO.IOException(iText.IO.IOException.PngImageException, e);
            }
        }