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);
    }
Example #2
0
    /// <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);
    }