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()); } }
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); }
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()); }
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)); } }
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())); }
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); }
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); }
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()); } }
/// <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); }
// 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); }
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()); } }
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()); }
public override byte[] Encode(Bytes.Buffer data, PdfDirectObject parameters, IDictionary <PdfName, PdfDirectObject> header) { return(data.GetBuffer()); }