Ejemplo n.º 1
0
 private void FindColorspace(PdfObject colorspace, bool allowIndexed)
 {
     if (PdfName.DEVICEGRAY.Equals(colorspace))
     {
         stride       = (width * bpc + 7) / 8;
         pngColorType = 0;
     }
     else if (PdfName.DEVICERGB.Equals(colorspace))
     {
         if (bpc == 8 || bpc == 16)
         {
             stride       = (width * bpc * 3 + 7) / 8;
             pngColorType = 2;
         }
     }
     else if (colorspace is PdfArray)
     {
         PdfArray  ca   = (PdfArray)colorspace;
         PdfObject tyca = ca.GetDirectObject(0);
         if (PdfName.CALGRAY.Equals(tyca))
         {
             stride       = (width * bpc + 7) / 8;
             pngColorType = 0;
         }
         else if (PdfName.CALRGB.Equals(tyca))
         {
             if (bpc == 8 || bpc == 16)
             {
                 stride       = (width * bpc * 3 + 7) / 8;
                 pngColorType = 2;
             }
         }
         else if (PdfName.ICCBASED.Equals(tyca))
         {
             PRStream pr = (PRStream)ca.GetDirectObject(1);
             int      n  = pr.GetAsNumber(PdfName.N).IntValue;
             if (n == 1)
             {
                 stride       = (width * bpc + 7) / 8;
                 pngColorType = 0;
                 icc          = PdfReader.GetStreamBytes(pr);
             }
             else if (n == 3)
             {
                 stride       = (width * bpc * 3 + 7) / 8;
                 pngColorType = 2;
                 icc          = PdfReader.GetStreamBytes(pr);
             }
         }
         else if (allowIndexed && PdfName.INDEXED.Equals(tyca))
         {
             FindColorspace(ca.GetDirectObject(1), false);
             if (pngColorType == 2)
             {
                 PdfObject id2 = ca.GetDirectObject(3);
                 if (id2 is PdfString)
                 {
                     palette = ((PdfString)id2).GetBytes();
                 }
                 else if (id2 is PRStream)
                 {
                     palette = PdfReader.GetStreamBytes(((PRStream)id2));
                 }
                 stride       = (width * bpc + 7) / 8;
                 pngColorType = 3;
             }
         }
     }
 }
Ejemplo n.º 2
0
        public byte[] GetImageAsBytes()
        {
            if (streamBytes == null)
            {
                return(null);
            }
            if (!decoded)
            {
                // if the stream hasn't been decoded, check to see if it is a single stage JPG or JPX encoded stream.  If it is,
                // then we can just use stream as-is
                PdfName filter = dictionary.GetAsName(PdfName.FILTER);
                if (filter == null)
                {
                    PdfArray filterArray = dictionary.GetAsArray(PdfName.FILTER);
                    if (filterArray.Size == 1)
                    {
                        filter = filterArray.GetAsName(0);
                    }
                    else
                    {
                        throw new UnsupportedPdfException("Multi-stage filters not supported here (" + filterArray + ")");
                    }
                }
                if (PdfName.DCTDECODE.Equals(filter))
                {
                    fileType = TYPE_JPG;
                    return(streamBytes);
                }
                else if (PdfName.JPXDECODE.Equals(filter))
                {
                    fileType = TYPE_JP2;
                    return(streamBytes);
                }
                throw new UnsupportedPdfException("Unsupported stream filter " + filter);
            }
            pngColorType = -1;
            width        = dictionary.GetAsNumber(PdfName.WIDTH).IntValue;
            height       = dictionary.GetAsNumber(PdfName.HEIGHT).IntValue;
            bpc          = dictionary.GetAsNumber(PdfName.BITSPERCOMPONENT).IntValue;
            pngBitDepth  = bpc;
            PdfObject colorspace = dictionary.GetDirectObject(PdfName.COLORSPACE);

            palette = null;
            icc     = null;
            stride  = 0;
            FindColorspace(colorspace, true);
            MemoryStream ms = new MemoryStream();

            if (pngColorType < 0)
            {
                if (bpc != 8)
                {
                    return(null);
                }
                if (PdfName.DEVICECMYK.Equals(colorspace))
                {
                }
                else if (colorspace is PdfArray)
                {
                    PdfArray  ca   = (PdfArray)colorspace;
                    PdfObject tyca = ca.GetDirectObject(0);
                    if (!PdfName.ICCBASED.Equals(tyca))
                    {
                        return(null);
                    }
                    PRStream pr = (PRStream)ca.GetDirectObject(1);
                    int      n  = pr.GetAsNumber(PdfName.N).IntValue;
                    if (n != 4)
                    {
                        return(null);
                    }
                    icc = PdfReader.GetStreamBytes(pr);
                }
                else
                {
                    return(null);
                }
                stride = 4 * width;
                TiffWriter wr = new TiffWriter();
                wr.AddField(new TiffWriter.FieldShort(TIFFConstants.TIFFTAG_SAMPLESPERPIXEL, 4));
                wr.AddField(new TiffWriter.FieldShort(TIFFConstants.TIFFTAG_BITSPERSAMPLE, new int[] { 8, 8, 8, 8 }));
                wr.AddField(new TiffWriter.FieldShort(TIFFConstants.TIFFTAG_PHOTOMETRIC, TIFFConstants.PHOTOMETRIC_SEPARATED));
                wr.AddField(new TiffWriter.FieldLong(TIFFConstants.TIFFTAG_IMAGEWIDTH, width));
                wr.AddField(new TiffWriter.FieldLong(TIFFConstants.TIFFTAG_IMAGELENGTH, height));
                wr.AddField(new TiffWriter.FieldShort(TIFFConstants.TIFFTAG_COMPRESSION, TIFFConstants.COMPRESSION_LZW));
                wr.AddField(new TiffWriter.FieldShort(TIFFConstants.TIFFTAG_PREDICTOR, TIFFConstants.PREDICTOR_HORIZONTAL_DIFFERENCING));
                wr.AddField(new TiffWriter.FieldLong(TIFFConstants.TIFFTAG_ROWSPERSTRIP, height));
                wr.AddField(new TiffWriter.FieldRational(TIFFConstants.TIFFTAG_XRESOLUTION, new int[] { 300, 1 }));
                wr.AddField(new TiffWriter.FieldRational(TIFFConstants.TIFFTAG_YRESOLUTION, new int[] { 300, 1 }));
                wr.AddField(new TiffWriter.FieldShort(TIFFConstants.TIFFTAG_RESOLUTIONUNIT, TIFFConstants.RESUNIT_INCH));
                wr.AddField(new TiffWriter.FieldAscii(TIFFConstants.TIFFTAG_SOFTWARE, Document.Version));
                MemoryStream comp = new MemoryStream();
                TiffWriter.CompressLZW(comp, 2, streamBytes, height, 4, stride);
                byte[] buf = comp.ToArray();
                wr.AddField(new TiffWriter.FieldImage(buf));
                wr.AddField(new TiffWriter.FieldLong(TIFFConstants.TIFFTAG_STRIPBYTECOUNTS, buf.Length));
                if (icc != null)
                {
                    wr.AddField(new TiffWriter.FieldUndefined(TIFFConstants.TIFFTAG_ICCPROFILE, icc));
                }
                wr.WriteFile(ms);
                fileType = TYPE_TIF;
                return(ms.ToArray());
            }
            PngWriter png = new PngWriter(ms);

            png.WriteHeader(width, height, pngBitDepth, pngColorType);
            if (icc != null)
            {
                png.WriteIccProfile(icc);
            }
            if (palette != null)
            {
                png.WritePalette(palette);
            }
            png.WriteData(streamBytes, stride);
            png.WriteEnd();
            fileType = TYPE_PNG;
            return(ms.ToArray());
        }
Ejemplo n.º 3
0
        /**
         * decodes the bytes currently captured in the streamBytes and replaces it with an image representation of the bytes
         * (this will either be a png or a tiff, depending on the color depth of the image)
         * @throws IOException
         */
        private void DecodeImageBytes()
        {
            if (streamContentType != null)
            {
                throw new ArgumentException(MessageLocalization.GetComposedMessage("Decoding.can't.happen.on.this.type.of.stream.(.1.)", streamContentType.FileExtension));
            }
            pngColorType = -1;
            PdfArray decode = dictionary.GetAsArray(PdfName.DECODE);

            width       = dictionary.GetAsNumber(PdfName.WIDTH).IntValue;
            height      = dictionary.GetAsNumber(PdfName.HEIGHT).IntValue;
            bpc         = dictionary.GetAsNumber(PdfName.BITSPERCOMPONENT).IntValue;
            pngBitDepth = bpc;
            PdfObject colorspace = dictionary.GetDirectObject(PdfName.COLORSPACE);

            if (colorspace is PdfName && colorSpaceDic != null)
            {
                PdfObject csLookup = colorSpaceDic.GetDirectObject((PdfName)colorspace);
                if (csLookup != null)
                {
                    colorspace = csLookup;
                }
            }

            palette = null;
            icc     = null;
            stride  = 0;
            FindColorspace(colorspace, true);
            MemoryStream ms = new MemoryStream();

            if (pngColorType < 0)
            {
                if (bpc != 8)
                {
                    throw new UnsupportedPdfException(MessageLocalization.GetComposedMessage("the.color.depth.1.is.not.supported", bpc));
                }
                if (PdfName.DEVICECMYK.Equals(colorspace))
                {
                }
                else if (colorspace is PdfArray)
                {
                    PdfArray  ca   = (PdfArray)colorspace;
                    PdfObject tyca = ca.GetDirectObject(0);
                    if (!PdfName.ICCBASED.Equals(tyca))
                    {
                        throw new UnsupportedPdfException(MessageLocalization.GetComposedMessage("the.color.space.1.is.not.supported", colorspace));
                    }
                    PRStream pr = (PRStream)ca.GetDirectObject(1);
                    int      n  = pr.GetAsNumber(PdfName.N).IntValue;
                    if (n != 4)
                    {
                        throw new UnsupportedPdfException(MessageLocalization.GetComposedMessage("N.value.1.is.not.supported", n));
                    }
                    icc = PdfReader.GetStreamBytes(pr);
                }
                else
                {
                    throw new UnsupportedPdfException(MessageLocalization.GetComposedMessage("the.color.space.1.is.not.supported", colorspace));
                }
                stride = 4 * width;
                TiffWriter wr = new TiffWriter();
                wr.AddField(new TiffWriter.FieldShort(TIFFConstants.TIFFTAG_SAMPLESPERPIXEL, 4));
                wr.AddField(new TiffWriter.FieldShort(TIFFConstants.TIFFTAG_BITSPERSAMPLE, new int[] { 8, 8, 8, 8 }));
                wr.AddField(new TiffWriter.FieldShort(TIFFConstants.TIFFTAG_PHOTOMETRIC, TIFFConstants.PHOTOMETRIC_SEPARATED));
                wr.AddField(new TiffWriter.FieldLong(TIFFConstants.TIFFTAG_IMAGEWIDTH, width));
                wr.AddField(new TiffWriter.FieldLong(TIFFConstants.TIFFTAG_IMAGELENGTH, height));
                wr.AddField(new TiffWriter.FieldShort(TIFFConstants.TIFFTAG_COMPRESSION, TIFFConstants.COMPRESSION_LZW));
                wr.AddField(new TiffWriter.FieldShort(TIFFConstants.TIFFTAG_PREDICTOR, TIFFConstants.PREDICTOR_HORIZONTAL_DIFFERENCING));
                wr.AddField(new TiffWriter.FieldLong(TIFFConstants.TIFFTAG_ROWSPERSTRIP, height));
                wr.AddField(new TiffWriter.FieldRational(TIFFConstants.TIFFTAG_XRESOLUTION, new int[] { 300, 1 }));
                wr.AddField(new TiffWriter.FieldRational(TIFFConstants.TIFFTAG_YRESOLUTION, new int[] { 300, 1 }));
                wr.AddField(new TiffWriter.FieldShort(TIFFConstants.TIFFTAG_RESOLUTIONUNIT, TIFFConstants.RESUNIT_INCH));
                wr.AddField(new TiffWriter.FieldAscii(TIFFConstants.TIFFTAG_SOFTWARE, Version.GetInstance().GetVersion));
                MemoryStream comp = new MemoryStream();
                TiffWriter.CompressLZW(comp, 2, imageBytes, height, 4, stride);
                byte[] buf = comp.ToArray();
                wr.AddField(new TiffWriter.FieldImage(buf));
                wr.AddField(new TiffWriter.FieldLong(TIFFConstants.TIFFTAG_STRIPBYTECOUNTS, buf.Length));
                if (icc != null)
                {
                    wr.AddField(new TiffWriter.FieldUndefined(TIFFConstants.TIFFTAG_ICCPROFILE, icc));
                }
                wr.WriteFile(ms);
                streamContentType = ImageBytesType.CCITT;
                imageBytes        = ms.ToArray();
                return;
            }
            else
            {
                PngWriter png = new PngWriter(ms);
                if (decode != null)
                {
                    if (pngBitDepth == 1)
                    {
                        // if the decode array is 1,0, then we need to invert the image
                        if (decode.GetAsNumber(0).IntValue == 1 && decode.GetAsNumber(1).IntValue == 0)
                        {
                            int len = imageBytes.Length;
                            for (int t = 0; t < len; ++t)
                            {
                                imageBytes[t] ^= 0xff;
                            }
                        }
                        else
                        {
                            // if the decode array is 0,1, do nothing.  It's possible that the array could be 0,0 or 1,1 - but that would be silly, so we'll just ignore that case
                        }
                    }
                    else
                    {
                        // todo: add decode transformation for other depths
                    }
                }
                png.WriteHeader(width, height, pngBitDepth, pngColorType);
                if (icc != null)
                {
                    png.WriteIccProfile(icc);
                }
                if (palette != null)
                {
                    png.WritePalette(palette);
                }
                png.WriteData(imageBytes, stride);
                png.WriteEnd();
                streamContentType = ImageBytesType.PNG;
                imageBytes        = ms.ToArray();
            }
        }