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> /// Prepares the object to get saved. /// </summary> internal override void PrepareForSave() { base.PrepareForSave(); #if DEBUG if (this.fontDescriptor.descriptor.fontData.loca == null) { GetType(); } #endif // CID fonts must be always embedded. PDFsharp embedds automatically a subset. FontData subSet = null; if (this.fontDescriptor.descriptor.fontData.loca == null) subSet = this.fontDescriptor.descriptor.fontData; else subSet = this.fontDescriptor.descriptor.fontData.CreateFontSubSet(this.cmapInfo.GlyphIndices, true); byte[] fontData = subSet.Data; #if DEBUG_ TrueTypeFontSubSet fss = new TrueTypeFontSubSet("", this.cmapInfo.descriptor.fontData, this.cmapInfo.GlyphIndices, 0, false, false); byte[] fontSubSet = fss.Process(); fss.CompareBytes(fontSubSet, fontProgram); #endif PdfDictionary fontStream = new PdfDictionary(this.Owner); this.Owner.Internals.AddObject(fontStream); this.fontDescriptor.Elements[PdfFontDescriptor.Keys.FontFile2] = fontStream.Reference; fontStream.Elements["/Length1"] = new PdfInteger(fontData.Length); if (!this.Owner.Options.NoCompression) { fontData = Filtering.FlateDecode.Encode(fontData); fontStream.Elements["/Filter"] = new PdfName("/FlateDecode"); } fontStream.Elements["/Length"] = new PdfInteger(fontData.Length); fontStream.CreateStream(fontData); }