Esempio n. 1
0
        public override byte[] Decode(Bytes.Buffer data, PdfDirectObject parameters, IDictionary <PdfName, PdfDirectObject> header)
        {
            // get decode parameters
            PdfDictionary decodeParms    = parameters as PdfDictionary;
            var           ccittFaxParams = new CCITTFaxParams(
                K: decodeParms.GetInt(PdfName.K),
                endOfLine: decodeParms.GetBool(PdfName.EndOfLine),
                encodedByteAlign: decodeParms.GetBool(PdfName.EncodedByteAlign),
                columns: decodeParms.GetInt(PdfName.Columns),
                rows: decodeParms.GetInt(PdfName.Rows),
                endOfBlock: decodeParms.GetBool(PdfName.EndOfBlock),
                blackIs1: decodeParms.GetBool(PdfName.BlackIs1)
                );
            var decoder = new CCITTFaxDecoder(data, ccittFaxParams);

            using (var output = new Bytes.Buffer())
            {
                var currentByte = 0;
                while ((currentByte = decoder.ReadNextChar()) > -1)
                {
                    output.Append(FiltersExtension.ToByte(currentByte));
                }
                return(output.GetBuffer());
            }
        }
Esempio n. 2
0
        public override byte[] Decode(Bytes.Buffer data, PdfDirectObject parameters, IDictionary <PdfName, PdfDirectObject> header)
        {
            var jbig2Image = new Jbig2Image();

            var chunks = new List <ImageChunk>();

            if (parameters is PdfDictionary parametersDict)
            {
                var globalsStream = parametersDict.Resolve(PdfName.JBIG2Globals);
                if (globalsStream is PdfStream pdfStream)
                {
                    var globals = pdfStream.ExtractBody(true).GetBuffer();
                    chunks.Add(new ImageChunk(data: globals, start: 0, end: globals.Length));
                }
            }
            var buffer = data.GetBuffer();

            chunks.Add(new ImageChunk(data: buffer, start: 0, end: buffer.Length));
            var imageData  = jbig2Image.ParseChunks(chunks);
            var dataLength = imageData.Length;

            // JBIG2 had black as 1 and white as 0, inverting the colors
            for (var i = 0; i < dataLength; i++)
            {
                imageData[i] ^= 0xff;
            }
            return(imageData);
        }
Esempio n. 3
0
        private byte[] DoLZWDecode(Bytes.Buffer input, int earlyChange)
        {
            List <byte[]> codeTable = new List <byte[]>();
            int           chunk     = 9;
            var           decoded   = new Bytes.Buffer();
            long          nextCommand;
            long          prevCommand = -1;

            try
            {
                while ((nextCommand = input.ReadBits(chunk)) != EOD)
                {
                    if (nextCommand == CLEAR_TABLE)
                    {
                        chunk       = 9;
                        codeTable   = CreateCodeTable();
                        prevCommand = -1;
                    }
                    else
                    {
                        if (nextCommand < codeTable.Count)
                        {
                            byte[] data      = codeTable[(int)nextCommand];
                            byte   firstByte = data[0];
                            decoded.Write(data);
                            if (prevCommand != -1)
                            {
                                CheckIndexBounds(codeTable, prevCommand, input);
                                data = codeTable[(int)prevCommand];
                                byte[] newData = data.CopyOf(data.Length + 1);
                                newData[data.Length] = firstByte;
                                codeTable.Add(newData);
                            }
                        }
                        else
                        {
                            CheckIndexBounds(codeTable, prevCommand, input);
                            byte[] data    = codeTable[(int)prevCommand];
                            byte[] newData = data.CopyOf(data.Length + 1);
                            newData[data.Length] = data[0];
                            decoded.Write(newData);
                            codeTable.Add(newData);
                        }

                        chunk       = CalculateChunk(codeTable.Count, earlyChange);
                        prevCommand = nextCommand;
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine("warn: Premature EOF input LZW stream, EOD code missing " + ex);
            }
            return(decoded.GetBuffer());
        }
Esempio n. 4
0
 public override byte[] Decode(Bytes.Buffer data, PdfDirectObject parameters, IDictionary <PdfName, PdfDirectObject> header)
 {
     using (MemoryStream outputStream = new MemoryStream())
         using (MemoryStream inputStream = new MemoryStream(data.GetBuffer(), 0, (int)data.Length))
             using (DeflateStream inputFilter = new DeflateStream(inputStream, CompressionMode.Decompress))
             {
                 inputStream.Position = 2; // Skips zlib's 2-byte header [RFC 1950] [FIX:0.0.8:JCT].
                 Transform(inputFilter, outputStream);
                 inputFilter.Close();
                 return(DecodePredictor(outputStream.ToArray(), parameters, header));
             }
 }
Esempio n. 5
0
        public override byte[] Encode(Bytes.Buffer data, PdfDirectObject parameters, IDictionary <PdfName, PdfDirectObject> header)
        {
            byte[] decodedBlock = new byte[4];
            byte[] encodedBlock = new byte[5];

            StringBuilder buffer  = new StringBuilder((int)(data.Length * (encodedBlock.Length / decodedBlock.Length)));
            int           linePos = 0;

            if (EnforceMarks)
            {
                AppendString(buffer, PrefixMark, ref linePos);
            }

            int  count = 0;
            uint tuple = 0;

            foreach (byte dataByte in data.GetBuffer())
            {
                if (count >= decodedBlock.Length - 1)
                {
                    tuple |= dataByte;
                    if (tuple == 0)
                    {
                        AppendChar(buffer, 'z', ref linePos);
                    }
                    else
                    {
                        EncodeBlock(encodedBlock, buffer, ref tuple, ref linePos);
                    }
                    tuple = 0;
                    count = 0;
                }
                else
                {
                    tuple |= (uint)(dataByte << (24 - (count * 8)));
                    count++;
                }
            }

            // if we have some bytes left over at the end..
            if (count > 0)
            {
                EncodeBlock(encodedBlock, count + 1, buffer, ref tuple, ref linePos);
            }

            if (EnforceMarks)
            {
                AppendString(buffer, SuffixMark, ref linePos);
            }

            return(ASCIIEncoding.UTF8.GetBytes(buffer.ToString()));
        }
Esempio n. 6
0
        public override byte[] Decode(Bytes.Buffer data, PdfDirectObject parameters, IDictionary <PdfName, PdfDirectObject> header)
        {
            var imageParams = header;
            //var width = imageParams.Resolve(PdfName.Width) as PdfInteger;
            //var height = imageParams.Resolve(PdfName.Height) as PdfInteger;
            var bpp      = imageParams[PdfName.BitsPerComponent] as PdfInteger;
            var flag     = imageParams[PdfName.ImageMask] as PdfBoolean;
            var jpxImage = new JpxImage();

            jpxImage.Parse(data.GetBuffer());

            var width           = jpxImage.width;
            var height          = jpxImage.height;
            var componentsCount = jpxImage.componentsCount;
            var tileCount       = jpxImage.tiles.Count;
            var buffer          = (byte[])null;

            if (tileCount == 1)
            {
                buffer = jpxImage.tiles[0].items;
            }
            else
            {
                buffer = new byte[width * height * componentsCount];

                for (var k = 0; k < tileCount; k++)
                {
                    var tileComponents = jpxImage.tiles[k];
                    var tileWidth      = tileComponents.Width;
                    var tileHeight     = tileComponents.Height;
                    var tileLeft       = tileComponents.Left;
                    var tileTop        = tileComponents.Top;

                    var src          = tileComponents.items;
                    var srcPosition  = 0;
                    var dataPosition = (width * tileTop + tileLeft) * componentsCount;
                    var imgRowSize   = width * componentsCount;
                    var tileRowSize  = tileWidth * componentsCount;

                    for (var j = 0; j < tileHeight; j++)
                    {
                        var rowBytes = src.SubArray(srcPosition, srcPosition + tileRowSize);
                        buffer.Set(rowBytes, dataPosition);
                        srcPosition  += tileRowSize;
                        dataPosition += imgRowSize;
                    }
                }
            }
            return(buffer);
        }
Esempio n. 7
0
        public override byte[] Decode(Bytes.Buffer data, PdfDirectObject parameters, IDictionary <PdfName, PdfDirectObject> header)
        {
            var imageParams      = header;
            var dictHeight       = ((IPdfNumber)(header[PdfName.Height] ?? header[PdfName.H])).IntValue;
            var dictWidth        = ((IPdfNumber)(header[PdfName.Width] ?? header[PdfName.W])).IntValue;
            var bitsPerComponent = ((IPdfNumber)imageParams[PdfName.BitsPerComponent])?.IntValue ?? 8;
            var flag             = imageParams[PdfName.ImageMask] as PdfBoolean;
            var jpegOptions      = new JpegOptions(decodeTransform: null, colorTransform: null);

            // Checking if values need to be transformed before conversion.
            var decodeObj = imageParams[PdfName.Decode] ?? imageParams[PdfName.D];
            var decodeArr = decodeObj?.Resolve() as PdfArray;

            if (false && decodeArr != null)
            {
                var decode          = decodeArr.Select(p => ((IPdfNumber)p).IntValue).ToArray();
                var decodeArrLength = decodeArr.Count;
                var transform       = new int[decodeArr.Count];
                var transformNeeded = false;
                var maxValue        = (1 << bitsPerComponent) - 1;
                for (var i = 0; i < decodeArrLength; i += 2)
                {
                    transform[i]     = ((decode[i + 1] - decode[i]) * 256) | 0;
                    transform[i + 1] = (decode[i] * maxValue) | 0;
                    if (transform[i] != 256 || transform[i + 1] != 0)
                    {
                        transformNeeded = true;
                    }
                }
                if (transformNeeded)
                {
                    jpegOptions.DecodeTransform = transform;
                }
            }
            // Fetching the 'ColorTransform' entry, if it exists.
            if (parameters is PdfDictionary paramDict)
            {
                var colorTransform = paramDict[PdfName.ColorTransform];
                if (colorTransform is IPdfNumber number)
                {
                    jpegOptions.ColorTransform = number.IntValue;
                }
            }
            var jpegImage = new JpegImage(jpegOptions);

            jpegImage.Parse(data.GetBuffer());
            var buffer = jpegImage.GetData(width: dictWidth, height: dictHeight, forceRGB: false, isSourcePDF: true);

            return(buffer);
        }
Esempio n. 8
0
 public override byte[] Encode(Bytes.Buffer data, PdfDirectObject parameters, IDictionary <PdfName, PdfDirectObject> header)
 {
     using (MemoryStream inputStream = new MemoryStream(data.GetBuffer(), 0, (int)data.Length))
         using (MemoryStream outputStream = new MemoryStream())
             using (DeflateStream outputFilter = new DeflateStream(outputStream, CompressionMode.Compress, true))
             {
                 // Add zlib's 2-byte header [RFC 1950] [FIX:0.0.8:JCT]!
                 outputStream.WriteByte(0x78); // CMF = {CINFO (bits 7-4) = 7; CM (bits 3-0) = 8} = 0x78.
                 outputStream.WriteByte(0xDA); // FLG = {FLEVEL (bits 7-6) = 3; FDICT (bit 5) = 0; FCHECK (bits 4-0) = {31 - ((CMF * 256 + FLG - FCHECK) Mod 31)} = 26} = 0xDA.
                 Transform(inputStream, outputFilter);
                 outputFilter.Close();
                 return(outputStream.ToArray());
             }
 }
Esempio n. 9
0
        /// <summary>
        /// Decodes the specified data.
        /// </summary>
        public override byte[] Decode(Bytes.Buffer data, PdfDirectObject parameters, IDictionary <PdfName, PdfDirectObject> header)
        {
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }
            var dataBuffer = data.GetBuffer();
            var length     = dataBuffer.Length;

            dataBuffer = RemoveWhiteSpace(dataBuffer, 0, length);
            int count = dataBuffer.Length;

            // Ignore EOD (end of data) character.
            // EOD can be anywhere in the stream, but makes sense only at the end of the stream.
            if (count > 0 && dataBuffer[count - 1] == '>')
            {
                --count;
            }
            if (count % 2 == 1)
            {
                count++;
                byte[] temp = dataBuffer;
                dataBuffer = new byte[count];
                temp.CopyTo(dataBuffer, 0);
            }
            count >>= 1;
            byte[] bytes = new byte[count];
            for (int i = 0, j = 0; i < count; i++)
            {
                // Must support 0-9, A-F, a-f - "Any other characters cause an error."
                byte hi = dataBuffer[j++];
                byte lo = dataBuffer[j++];
                if (hi >= 'a' && hi <= 'f')
                {
                    hi -= 32;
                }
                if (lo >= 'a' && lo <= 'f')
                {
                    lo -= 32;
                }
                // TODO Throw on invalid characters. Stop when encountering EOD. Add one more byte if EOD is the lo byte.
                bytes[i] = (byte)((hi > '9' ? hi - '7' /*'A' + 10*/: hi - '0') * 16 + (lo > '9' ? lo - '7' /*'A' + 10*/: lo - '0'));
            }
            return(bytes);
        }
Esempio n. 10
0
        // Reference: 3.3.1  ASCIIHexDecode Filter / Page 69

        /// <summary>
        /// Encodes the specified data.
        /// </summary>
        public override byte[] Encode(Bytes.Buffer data, PdfDirectObject parameters, IDictionary <PdfName, PdfDirectObject> header)
        {
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }
            var dataBuffer = data.GetBuffer();
            var length     = dataBuffer.Length;

            byte[] bytes = new byte[2 * length];
            for (int i = 0, j = 0; i < length; i++)
            {
                byte b = dataBuffer[i];
                bytes[j++] = (byte)((b >> 4) + ((b >> 4) < 10 ? (byte)'0' : (byte)('A' - 10)));
                bytes[j++] = (byte)((b & 0xF) + ((b & 0xF) < 10 ? (byte)'0' : (byte)('A' - 10)));
            }
            return(bytes);
        }
Esempio n. 11
0
        public override byte[] Encode(Bytes.Buffer rawData, PdfDirectObject parameters, IDictionary <PdfName, PdfDirectObject> header)
        {
            List <byte[]> codeTable = CreateCodeTable();
            int           chunk     = 9;

            byte[] inputPattern = null;
            using (var output = new Bytes.Buffer())
            {
                output.WriteBits(CLEAR_TABLE, chunk);
                int foundCode = -1;
                int r;
                while ((r = rawData.ReadByte()) != -1)
                {
                    byte by = (byte)r;
                    if (inputPattern == null)
                    {
                        inputPattern = new byte[] { by };
                        foundCode    = by & 0xff;
                    }
                    else
                    {
                        inputPattern = inputPattern.SubArray(0, inputPattern.Length + 1);
                        inputPattern[inputPattern.Length - 1] = by;
                        int newFoundCode = FindPatternCode(codeTable, inputPattern);
                        if (newFoundCode == -1)
                        {
                            // use previous
                            chunk = CalculateChunk(codeTable.Count - 1, 1);
                            output.WriteBits(foundCode, chunk);
                            // create new table entry
                            codeTable.Add(inputPattern);

                            if (codeTable.Count == 4096)
                            {
                                // code table is full
                                output.WriteBits(CLEAR_TABLE, chunk);
                                codeTable = CreateCodeTable();
                            }

                            inputPattern = new byte[] { by };
                            foundCode    = by & 0xff;
                        }
                        else
                        {
                            foundCode = newFoundCode;
                        }
                    }
                }
                if (foundCode != -1)
                {
                    chunk = CalculateChunk(codeTable.Count - 1, 1);
                    output.WriteBits(foundCode, chunk);
                }

                // PPDFBOX-1977: the decoder wouldn't know that the encoder would output
                // an EOD as code, so he would have increased his own code table and
                // possibly adjusted the chunk. Therefore, the encoder must behave as
                // if the code table had just grown and thus it must be checked it is
                // needed to adjust the chunk, based on an increased table size parameter
                chunk = CalculateChunk(codeTable.Count, 1);

                output.WriteBits(EOD, chunk);

                // pad with 0
                output.WriteBits(0, 7);

                // must do or file will be empty :-(
                return(output.GetBuffer());
            }
        }
Esempio n. 12
0
        public override byte[] Decode(Bytes.Buffer data, PdfDirectObject parameters, IDictionary <PdfName, PdfDirectObject> header)
        {
            byte[] decodedBlock = new byte[4];
            byte[] encodedBlock = new byte[5];
            uint   tuple        = 0;

            string dataString = Encoding.ASCII.GetString(data.GetBuffer()).Trim();

            // Stripping prefix and suffix...
            if (dataString.StartsWith(PrefixMark))
            {
                dataString = dataString.Substring(PrefixMark.Length);
            }
            if (dataString.EndsWith(SuffixMark))
            {
                dataString = dataString.Substring(0, dataString.Length - SuffixMark.Length);
            }

            MemoryStream stream      = new MemoryStream();
            int          count       = 0;
            bool         processChar = false;

            foreach (char dataChar in dataString)
            {
                switch (dataChar)
                {
                case 'z':
                    if (count != 0)
                    {
                        throw new Exception("The character 'z' is invalid inside an ASCII85 block.");
                    }

                    decodedBlock[0] = 0;
                    decodedBlock[1] = 0;
                    decodedBlock[2] = 0;
                    decodedBlock[3] = 0;
                    stream.Write(decodedBlock, 0, decodedBlock.Length);
                    processChar = false;
                    break;

                case '\n':
                case '\r':
                case '\t':
                case '\0':
                case '\f':
                case '\b':
                    processChar = false;
                    break;

                default:
                    if (dataChar < '!' || dataChar > 'u')
                    {
                        throw new Exception("Bad character '" + dataChar + "' found. ASCII85 only allows characters '!' to 'u'.");
                    }

                    processChar = true;
                    break;
                }

                if (processChar)
                {
                    tuple += ((uint)(dataChar - AsciiOffset) * Pow85[count]);
                    count++;
                    if (count == encodedBlock.Length)
                    {
                        DecodeBlock(decodedBlock, ref tuple);
                        stream.Write(decodedBlock, 0, decodedBlock.Length);
                        tuple = 0;
                        count = 0;
                    }
                }
            }

            // Bytes left over at the end?
            if (count != 0)
            {
                if (count == 1)
                {
                    throw new Exception("The last block of ASCII85 data cannot be a single byte.");
                }

                count--;
                tuple += Pow85[count];
                DecodeBlock(decodedBlock, count, ref tuple);
                for (int i = 0; i < count; i++)
                {
                    stream.WriteByte(decodedBlock[i]);
                }
            }

            return(stream.ToArray());
        }
Esempio n. 13
0
 public override byte[] Encode(Bytes.Buffer data, PdfDirectObject parameters, IDictionary <PdfName, PdfDirectObject> header)
 {
     return(data.GetBuffer());
 }