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); }