/// <summary> /// Retrieves the specifed dictionary object as an object encoded with DCTDecode filter (JPEG). /// </summary> /// <param name="dictionary">The dictionary to extract the object from.</param> /// <returns>The image retrieve from the dictionary. If not found or an invalid image, then null is returned.</returns> private static Image ImageFromDCTDecode(PdfDictionary dictionary) { // DCTDecode a lossy filter based on the JPEG standard // We can just load directly from the stream. MemoryStream stream = new MemoryStream(dictionary.Stream.Value); return (Bitmap.FromStream(stream)); }
static bool ExportImage(PdfDictionary image, ref int count) { bool ret = false; try { string filter = image.Elements.GetName("/Filter"); switch (filter) { case "/DCTDecode": ret = ExportJpegImage(image, ref count); break; /* case "/FlateDecode": ExportAsPngImage(image, ref count); break;*/ default: ret = true; break; } } catch (Exception)//in case its an object array so we need first to decompress it { byte[] stream = image.Stream.Value; PdfSharp.Pdf.Filters.FlateDecode aug = new PdfSharp.Pdf.Filters.FlateDecode(); stream = aug.Decode(stream); ret = ExportJpegImage(stream, ref count); } return ret; }
static void ExportJpegImage(PdfDictionary image, ref int count) { byte[] stream = image.Stream.Value; using (FileStream fs = new FileStream(String.Format("Image{0}.jpg", count++), FileMode.Create, FileAccess.Write)) { fs.Write(stream, 0, stream.Length); } }
internal PdfPage(PdfDictionary dict) : base(dict) { // Set Orientation depending on /Rotate. int rotate = Elements.GetInteger(InheritablePageKeys.Rotate); if (Math.Abs((rotate / 90)) % 2 == 1) _orientation = PageOrientation.Landscape; }
/// <summary> /// </summary> public PdfContentWriter(DocumentRenderingContext context, PdfDictionary contentDictionary) { if (!(contentDictionary is IContentStream)) throw new ArgumentException("contentDictionary must implement IContentStream."); this.context = context; this.contentDictionary = contentDictionary; this.contentStreamDictionary = (IContentStream)contentDictionary; this.renderMode = RenderMode.Default; //this.colorMode = page.document.Options.ColorMode; //this.options = options; this.content = new StringBuilder(); this.graphicsState = new PdfGraphicsState(this); }
static void ExportImage(PdfDictionary image, ref int count) { string filter = image.Elements.GetName("/Filter"); switch (filter) { case "/DCTDecode": ExportJpegImage(image, ref count); break; case "/FlateDecode": ExportAsPngImage(image, ref count); break; } }
static void ExportJpegImage(PdfDictionary image, ref int count) { // Fortunately JPEG has native support in PDF and exporting an image is just writing the stream to a file. byte[] stream = image.Stream.Value; FileStream fs = new FileStream(String.Format("F:\\Image{0}.jpeg", count++), FileMode.Create, FileAccess.Write); BinaryWriter bw = new BinaryWriter(fs); bw.Write(stream); bw.Close(); }
public PdfCIDFont(PdfDocument document, PdfFontDescriptor fontDescriptor, byte[] fontData) : base(document) { Elements.SetName(Keys.Type, "/Font"); Elements.SetName(Keys.Subtype, "/CIDFontType2"); PdfDictionary cid = new PdfDictionary(); cid.Elements.SetString("/Ordering", "Identity"); cid.Elements.SetString("/Registry", "Adobe"); cid.Elements.SetInteger("/Supplement", 0); Elements.SetValue(Keys.CIDSystemInfo, cid); this.fontDescriptor = fontDescriptor; Owner.irefTable.Add(fontDescriptor); Elements[Keys.FontDescriptor] = fontDescriptor.Reference; FontEncoding = PdfFontEncoding.Unicode; FontEmbedding = PdfFontEmbedding.Always; }
static void ExportImage(PdfDictionary image, ref int count) { string filter = image.Elements.GetName(PdfImage.Keys.Filter); switch (filter) { case "/DCTDecode": ExportJpegImage(image, ref count); break; case "": case "/FlateDecode": ExportUnfilterableImage(image, ref count); break; case "/CCITTFaxDecode": case "/RunLengthDecode,": default: throw new NotSupportedException(); } }
public PdfCIDFont(PdfDocument document, PdfFontDescriptor fontDescriptor, XFont font) : base(document) { Elements.SetName(Keys.Type, "/Font"); Elements.SetName(Keys.Subtype, "/CIDFontType2"); // This code is foobar. A PDF literal containing strings is not encrypted, but decryped when opening the PDF file. //Elements.SetValue(Keys.CIDSystemInfo, // new PdfLiteral("<< /Ordering (Identity) /Registry (Adobe) /Supplement 0>>")); // Must use real objects because PDF literals containing strings is not encrypted. That causes an error // when the file is decrypted. PdfDictionary cid = new PdfDictionary(); cid.Elements.SetString("/Ordering", "Identity"); cid.Elements.SetString("/Registry", "Adobe"); cid.Elements.SetInteger("/Supplement", 0); Elements.SetValue(Keys.CIDSystemInfo, cid); this.fontDescriptor = fontDescriptor; Owner.irefTable.Add(fontDescriptor); Elements[Keys.FontDescriptor] = fontDescriptor.Reference; FontEncoding = font.PdfOptions.FontEncoding; FontEmbedding = font.PdfOptions.FontEmbedding; }
PdfDictionary CreateDictionary(Type type, PdfDictionary oldDictionary) { ConstructorInfo ctorInfo; PdfDictionary dict; if (oldDictionary == null) { // Use contstructor with signature 'Ctor(PdfDocument owner)'. ctorInfo = type.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[] { typeof(PdfDocument) }, null); Debug.Assert(ctorInfo != null, "No appropriate constructor found for type: " + type.Name); dict = ctorInfo.Invoke(new object[] { this.owner.Owner }) as PdfDictionary; } else { // Use contstructor with signature 'Ctor(PdfDictionary dict)'. ctorInfo = type.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[] { typeof(PdfDictionary) }, null); Debug.Assert(ctorInfo != null, "No appropriate constructor found for type: " + type.Name); dict = ctorInfo.Invoke(new object[] { oldDictionary }) as PdfDictionary; } return dict; }
/// <summary> /// Add all inheritable values from the specified page to the specified values structure. /// </summary> internal static void InheritValues(PdfDictionary page, ref InheritedValues values) { PdfItem item = page.Elements[InheritablePageKeys.Resources]; if (item != null) { PdfReference reference = item as PdfReference; if (reference != null) values.Resources = (PdfDictionary)(reference.Value); else values.Resources = (PdfDictionary)item; } item = page.Elements[InheritablePageKeys.MediaBox]; if (item != null) values.MediaBox = new PdfRectangle(item); item = page.Elements[InheritablePageKeys.CropBox]; if (item != null) values.CropBox = new PdfRectangle(item); item = page.Elements[InheritablePageKeys.Rotate]; if (item != null) { if (item is PdfReference) item = ((PdfReference)item).Value; values.Rotate = (PdfInteger)item; } }
/// <summary> /// Initializes a new instance from an existing dictionary. Used for object type transformation. /// </summary> public PdfOutline(PdfDictionary dict) : base(dict) { Initialize(); }
/// <summary> /// Initializes a new instance of the <see cref="PdfAnnotation"/> class. /// </summary> internal PdfAnnotation(PdfDictionary dict) : base(dict) { }
/// <summary> /// Initializes the item based on the specified PdfDictionary. /// </summary> /// <param name="dictionary">The dictionary to use for initialization.</param> private void Initialize(PdfDictionary dictionary) { if (dictionary == null) throw new ArgumentNullException("dictionary", "The PDF dictionary item to extract image meta data from was null."); if (!dictionary.IsImage()) throw new ArgumentException("The specified dictionary does not represent an image.", "dictionary"); Height = dictionary.Elements.GetInteger("/Height"); Width = dictionary.Elements.GetInteger("/Width"); BitsPerPixel = dictionary.Elements.GetInteger("/BitsPerComponent"); Length = dictionary.Elements.GetInteger("/Length"); PdfItem colorSpace = null; if (dictionary.Elements.TryGetValue("/ColorSpace", out colorSpace)) { ColorSpace = PdfDictionaryColorSpace.Parse(colorSpace); } else ColorSpace = new PdfRGBColorSpace(); // Default to RGB Color Space }
/// <summary> /// Retrieves the specifed dictionary object as an object encoded with FlateDecode filter. /// </summary> /// <remarks> /// FlateDecode a commonly used filter based on the zlib/deflate algorithm (a.k.a. gzip, but not zip) /// defined in RFC 1950 and RFC 1951; introduced in PDF 1.2; it can use one of two groups of predictor /// functions for more compact zlib/deflate compression: Predictor 2 from the TIFF 6.0 specification /// and predictors (filters) from the PNG specification (RFC 2083) /// </remarks> /// <param name="dictionary">The dictionary to extract the object from.</param> /// <returns>The image retrieve from the dictionary. If not found or an invalid image, then null is returned.</returns> private static Image ImageFromFlateDecode(PdfDictionary dictionary) { PdfDictionaryImageMetaData imageData = new PdfDictionaryImageMetaData(dictionary); // FlateDecode can be either indexed or a traditional ColorSpace bool isIndexed = imageData.ColorSpace.IsIndexed; PixelFormat format = GetPixelFormat(imageData.ColorSpace, imageData.BitsPerPixel, isIndexed); Bitmap bitmap = new Bitmap(imageData.Width, imageData.Height, format); // If indexed, retrieve and assign the color palette for the item. if ((isIndexed) && (imageData.ColorSpace.IsRGB)) bitmap.Palette = ((PdfIndexedRGBColorSpace) imageData.ColorSpace).ToColorPalette(); else if (imageData.ColorSpace is PdfGrayColorSpace) bitmap.Palette = ((PdfGrayColorSpace)imageData.ColorSpace).ToColorPalette(imageData.BitsPerPixel); // If not an indexed color, the .NET image component expects pixels to be in BGR order. However, our PDF stream is in RGB order. byte[] stream = (format == PixelFormat.Format24bppRgb) ? ConvertRGBStreamToBGR(dictionary.Stream.UnfilteredValue) : dictionary.Stream.UnfilteredValue; BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, imageData.Width, imageData.Height), ImageLockMode.WriteOnly, format); // We can't just copy the bytes directly; the BitmapData .NET class has a stride (padding) associated with it. int bitsPerPixel = ((((int)format >> 8) & 0xFF)); int length = (int)Math.Ceiling(bitmapData.Width * bitsPerPixel / 8.0); for (int y = 0, height = bitmapData.Height; y < height; y++) { int offset = y * length; Marshal.Copy(stream, offset, bitmapData.Scan0 + (y * bitmapData.Stride), length); } bitmap.UnlockBits(bitmapData); return (bitmap); }
/// <summary> /// Initializes a new instance of the <see cref="PdfContent"/> class. /// </summary> /// <param name="dict">The dict.</param> public PdfContent(PdfDictionary dict) // HACK PdfContent : base(dict) { // A PdfContent dictionary is always unfiltered. Decode(); }
internal void SetOwner(PdfDictionary dict) { ChangeOwner(dict); }
/// <summary> /// Retrieves the specifed dictionary object as an object encoded with CCITTFaxDecode filter (TIFF). /// </summary> /// <param name="dictionary">The dictionary to extract the object from.</param> /// <returns>The image retrieve from the dictionary. If not found or an invalid image, then null is returned.</returns> private static Image ImageFromCCITTFaxDecode(PdfDictionary dictionary) { Image image = null; PdfDictionaryImageMetaData imageData = new PdfDictionaryImageMetaData(dictionary); PixelFormat format = GetPixelFormat(imageData.ColorSpace, imageData.BitsPerPixel, true); Bitmap bitmap = new Bitmap(imageData.Width, imageData.Height, format); // Determine if BLACK=1, create proper indexed color palette. CCITTFaxDecodeParameters ccittFaxDecodeParameters = new CCITTFaxDecodeParameters(dictionary.Elements["/DecodeParms"].Get() as PdfDictionary); if (ccittFaxDecodeParameters.BlackIs1) bitmap.Palette = PdfIndexedColorSpace.CreateColorPalette(Color.Black, Color.White); else bitmap.Palette = PdfIndexedColorSpace.CreateColorPalette(Color.White, Color.Black); using (MemoryStream stream = new MemoryStream(GetTiffImageBufferFromCCITTFaxDecode(imageData, dictionary.Stream.Value))) { using (Tiff tiff = Tiff.ClientOpen("<INLINE>", "r", stream, new TiffStream())) { if (tiff == null) return (null); int stride = tiff.ScanlineSize(); byte[] buffer = new byte[stride]; for (int i = 0; i < imageData.Height; i++) { tiff.ReadScanline(buffer, i); Rectangle imgRect = new Rectangle(0, i, imageData.Width, 1); BitmapData imgData = bitmap.LockBits(imgRect, ImageLockMode.WriteOnly, PixelFormat.Format1bppIndexed); Marshal.Copy(buffer, 0, imgData.Scan0, buffer.Length); bitmap.UnlockBits(imgData); } } } return (bitmap); }
PdfItem CreateValue(Type type, PdfDictionary oldValue) { ConstructorInfo ctorInfo = type.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[] { typeof(PdfDocument) }, null); PdfObject obj = ctorInfo.Invoke(new object[] { this.owner.Owner }) as PdfObject; if (oldValue != null) { obj.Reference = oldValue.Reference; obj.Reference.Value = obj; if (obj is PdfDictionary) { PdfDictionary dict = (PdfDictionary)obj; dict.elements = ((PdfDictionary)oldValue).elements; } } return obj; }
private static PdfDictionary ProcessFilters(PdfDictionary dictionary) { PdfDictionary result; // Create a dictionary mapping (i.e. switch statement) to process the expected filters. var map = new Dictionary<string, Func<byte[], byte[]>>() { { "/FlateDecode", (d) => { var decoder = new FlateDecode(); return (decoder.Decode(d)); } } }; // Get all of the filters. var filters = ((PdfArray)dictionary.Elements["/Filter"]) .Elements.Where(e => e.IsName()) .Select(e => ((PdfName)e).Value) .ToList(); // If only one filter in array. Just rewrite the /Filter if (filters.Count == 1) { result = dictionary.Clone(); result.Elements["/Filter"] = new PdfName(filters[0]); return (result); } // Process each filter in order. The last filter should be the actual encoded image. byte[] data = dictionary.Stream.Value; for(int index = 0; index < (filters.Count - 1); index++) { if (! map.ContainsKey(filters[index])) { throw new NotSupportedException(String.Format("Encountered embedded image with multiple filters: \"{0}\". Unable to process the filter: \"{1}\".", String.Join(",", filters), filters[index])); } data = map[filters[index]].Invoke(data); } result = new PdfDictionary(); result.Elements.Add("/Filter", new PdfName(filters.Last())); foreach (var element in dictionary.Elements.Where(e => !String.Equals(e.Key, "/Filter", StringComparison.OrdinalIgnoreCase))) { result.Elements.Add(element.Key, element.Value); } result.CreateStream(data); return(result); }
/// <summary> /// Initializes a new instance from an existing dictionary. Used for object type transformation. /// </summary> protected PdfDictionary(PdfDictionary dict) : base(dict) { if (dict.elements != null) dict.elements.ChangeOwner(this); if (dict.stream != null) dict.stream.SetOwner(this); }
/// <param name="dictionary">The dictionary object o parse.</param> public PdfDictionaryImageMetaData(PdfDictionary dictionary) { Initialize(dictionary); }
private IScannedImage ExportAsPngImage(PdfPage page, PdfDictionary image) { int width = image.Elements.GetInteger(PdfImage.Keys.Width); int height = image.Elements.GetInteger(PdfImage.Keys.Height); int bitsPerComponent = image.Elements.GetInteger(PdfImage.Keys.BitsPerComponent); var buffer = image.Stream.UnfilteredValue; Bitmap bitmap; ScanBitDepth bitDepth; switch (bitsPerComponent) { case 8: bitmap = new Bitmap(width, height, PixelFormat.Format24bppRgb); bitDepth = ScanBitDepth.C24Bit; RgbToBitmapUnmanaged(height, width, bitmap, buffer); break; case 1: bitmap = new Bitmap(width, height, PixelFormat.Format1bppIndexed); bitDepth = ScanBitDepth.BlackWhite; BlackAndWhiteToBitmapUnmanaged(height, width, bitmap, buffer); break; default: throw new NotImplementedException("Unsupported image encoding (expected 24 bpp or 1bpp)"); } using (bitmap) { bitmap.SetResolution(bitmap.Width / (float)page.Width.Inch, bitmap.Height / (float)page.Height.Inch); return scannedImageFactory.Create(bitmap, bitDepth, true); } }
/// <param name="dictionary">The dictionary element to parse / retrieve.</param> public CCITTFaxDecodeParameters(PdfDictionary dictionary):this() { if (dictionary == null) return; if (dictionary.Elements.ContainsKey(_K)) { K = dictionary.Elements.GetInteger(_K); } if (dictionary.Elements.ContainsKey(END_OF_LINE)) { EndOfLine = dictionary.Elements.GetBoolean(END_OF_LINE); } if (dictionary.Elements.ContainsKey(ENCODED_BYTE_ALIGN)) { EncodedByteAlign = dictionary.Elements.GetBoolean(ENCODED_BYTE_ALIGN); } if (dictionary.Elements.ContainsKey(COLUMNS)) { Columns = dictionary.Elements.GetInteger(COLUMNS); } if (dictionary.Elements.ContainsKey(ROWS)) { Rows = dictionary.Elements.GetInteger(ROWS); } if (dictionary.Elements.ContainsKey(END_OF_BLOCK)) { EndOfBlock = dictionary.Elements.GetBoolean(END_OF_BLOCK); } if (dictionary.Elements.ContainsKey(BLACK_IS_1)) { BlackIs1 = dictionary.Elements.GetBoolean(BLACK_IS_1); } if (dictionary.Elements.ContainsKey(DAMAGED_ROWS_BEFORE_ERROR)) { DamagedRowsBeforeError = dictionary.Elements.GetInteger(DAMAGED_ROWS_BEFORE_ERROR); } }
private void ShrinkJpegImage(PdfDictionary image, int quality) { try { string filter = image.Elements.GetName("/Filter"); if (filter != "/DCTDecode") return; Stream originalImageStream = new MemoryStream(image.Stream.Value); Image originalJpegImage = Image.FromStream(originalImageStream); byte[] newJpegImage = SaveJpeg(originalJpegImage, quality); image.Stream.Value = newJpegImage; } catch (Exception) { return; } }
/// <summary> /// Writes the stream of the specified dictionary. /// </summary> public void WriteStream(PdfDictionary value, bool omitStream) { StackItem stackItem = (StackItem)this.stack[this.stack.Count - 1]; Debug.Assert(stackItem.Object is PdfDictionary); Debug.Assert(stackItem.Object.IsIndirect); stackItem.HasStream = true; if (this.lastCat == CharCat.NewLine) WriteRaw(">>\nstream\n"); else WriteRaw(" >>\nstream\n"); if (omitStream) WriteRaw(" «...stream content omitted...»\n"); // useful for debugging only else { byte[] bytes = value.Stream.Value; if (bytes.Length != 0) { if (this.securityHandler != null) { bytes = (byte[])bytes.Clone(); bytes = this.securityHandler.EncryptBytes(bytes); } Write(bytes); if (this.lastCat != CharCat.NewLine) WriteRaw('\n'); } } WriteRaw("endstream\n"); }
internal override void WriteObject(PdfWriter writer) { // HACK: temporarily flip media box if Landscape PdfRectangle mediaBox = MediaBox; // TODO: Take /Rotate into account if (_orientation == PageOrientation.Landscape) MediaBox = new PdfRectangle(mediaBox.X1, mediaBox.Y1, mediaBox.Y2, mediaBox.X2); #if true // Add transparency group to prevent rendering problems of Adobe viewer. // Update (PDFsharp 1.50 beta 3): Add transparency group only of ColorMode is defined. // Rgb is the default for the ColorMode, but if user sets it to Undefined then // we respect this and skip the transparency group. TransparencyUsed = true; // TODO: check XObjects if (TransparencyUsed && !Elements.ContainsKey(Keys.Group) && _document.Options.ColorMode != PdfColorMode.Undefined) { PdfDictionary group = new PdfDictionary(); _elements["/Group"] = group; if (_document.Options.ColorMode != PdfColorMode.Cmyk) group.Elements.SetName("/CS", "/DeviceRGB"); else group.Elements.SetName("/CS", "/DeviceCMYK"); group.Elements.SetName("/S", "/Transparency"); //False is default: group.Elements["/I"] = new PdfBoolean(false); //False is default: group.Elements["/K"] = new PdfBoolean(false); } #endif #if DEBUG_ PdfItem item = Elements["/MediaBox"]; if (item != null) item.GetType(); #endif base.WriteObject(writer); if (_orientation == PageOrientation.Landscape) MediaBox = mediaBox; }
internal PdfCustomValue(PdfDictionary dict) : base(dict) { // TODO: uncompress stream }
/// <summary> /// Inherit values from parent node. /// </summary> internal static void InheritValues(PdfDictionary page, InheritedValues values) { // HACK: I'M ABSOLUTELY NOT SURE WHETHER THIS CODE COVERS ALL CASES. if (values.Resources != null) { PdfDictionary resources; PdfItem res = page.Elements[InheritablePageKeys.Resources]; if (res is PdfReference) { resources = (PdfDictionary)((PdfReference)res).Value.Clone(); resources.Document = page.Owner; } else resources = (PdfDictionary)res; if (resources == null) { resources = values.Resources.Clone(); resources.Document = page.Owner; page.Elements.Add(InheritablePageKeys.Resources, resources); } else { foreach (PdfName name in values.Resources.Elements.KeyNames) { if (!resources.Elements.ContainsKey(name.Value)) { PdfItem item = values.Resources.Elements[name]; if (item is PdfObject) item = item.Clone(); resources.Elements.Add(name.ToString(), item); } } } } if (values.MediaBox != null && page.Elements[InheritablePageKeys.MediaBox] == null) page.Elements[InheritablePageKeys.MediaBox] = values.MediaBox; if (values.CropBox != null && page.Elements[InheritablePageKeys.CropBox] == null) page.Elements[InheritablePageKeys.CropBox] = values.CropBox; if (values.Rotate != null && page.Elements[InheritablePageKeys.Rotate] == null) page.Elements[InheritablePageKeys.Rotate] = values.Rotate; }