1//
2// Copyright (c) 2001-2020 by PDFTron Systems Inc. All Rights Reserved.
3//
4
5using System;
6using System.IO;
7using System.Threading.Tasks;
8using Windows.Foundation;
9
10using pdftron.PDF;
11using pdftron.SDF;
12
13using pdftron.Common;
14using PDFNetUniversalSamples.ViewModels;
15using pdftron.Filters;
16using Windows.Storage.Streams;
17
18namespace PDFNetSamples
19{
20 /// <summary>
21 /// This sample project illustrates how to recompress bi-tonal images in an
22 /// existing PDF document using JBIG2 compression. The sample is not intended
23 /// to be a generic PDF optimization tool.
24 ///
25 /// Also a sample page compressed using CCITT Fax compression is located under
26 /// 'PDFNet/Samples/TestFiles' folder.
27 /// </summary>
28 class JBIG2Test : Sample
29 {
30 private string FILE_NAME = "US061222892-a.pdf";
31
32 public JBIG2Test() :
33 base("JBIG2", "This sample recompress bi-tonal images in an existing PDF document using JBIG2 compression.")
34 { }
35
36 public override IAsyncAction RunAsync()
37 {
38 return Task.Run(new System.Action(async () =>
39 {
40 WriteLine("--------------------------------");
41 WriteLine("Starting JBIG2 Compression Test...");
42 WriteLine("--------------------------------\n");
43
44 PDFDoc pdf_doc = new PDFDoc(Path.Combine(InputPath, FILE_NAME));
45 pdf_doc.InitSecurityHandler();
46
47 SDFDoc cos_doc = pdf_doc.GetSDFDoc();
48
49 int num_objs = cos_doc.XRefSize();
50
51 // Loop through all cross reference table objects
52 for (int i = 1; i < num_objs; ++i)
53 {
54 Obj obj = cos_doc.GetObj(i);
55 if (obj != null && !obj.IsFree() && obj.IsStream())
56 {
57 // Process only images
58 DictIterator itr = obj.Find("Subtype");
59 if (!itr.HasNext() || itr.Value().GetName() != "Image")
60 continue;
61
62 pdftron.PDF.Image input_image = new pdftron.PDF.Image(obj);
63 pdftron.PDF.Image new_image = null;
64
65 // Process only gray-scale images
66 if (input_image.GetComponentNum() != 1)
67 continue;
68
69 int bpc = input_image.GetBitsPerComponent();
70 if (bpc != 1) // Recompress 1 BPC images
71 continue;
72
73 // Skip images that are already compressed using JBIG2
74 itr = obj.Find("Filter");
75 if (itr.HasNext() && itr.Value().IsName() &&
76 itr.Value().GetName() == "JBIG2Decode")
77 continue;
78
79 FilterReader reader = new FilterReader(obj.GetDecodedStream());
80
81 ObjSet hint_set = new ObjSet();
82
83 Obj hint = hint_set.CreateArray();
84 hint.PushBackName("JBIG2");
85 hint.PushBackName("Lossless");
86 hint.PushBackName("Threshold");
87 hint.PushBackNumber(0.4);
88 hint.PushBackName("SharePages");
89 hint.PushBackNumber(10000);
90
91 new_image = pdftron.PDF.Image.Create(
92 cos_doc,
93 reader,
94 input_image.GetImageWidth(),
95 input_image.GetImageHeight(),
96 1,
97 ColorSpace.CreateDeviceGray(),
98 hint);
99
100 Obj new_img_obj = new_image.GetSDFObj();
101
102 // Copy any important entries from the image dictionary
103 itr = obj.Find("ImageMask");
104 if (itr.HasNext()) new_img_obj.Put("ImageMask", itr.Value());
105
106 itr = obj.Find("Mask");
107 if (itr.HasNext()) new_img_obj.Put("Mask", itr.Value());
108
109 cos_doc.Swap(i, new_image.GetSDFObj().GetObjNum());
110 }
111 }
112
113 await pdf_doc.SaveAsync(Path.Combine(OutputPath, FILE_NAME), SDFDocSaveOptions.e_remove_unused).AsTask().ConfigureAwait(false);
114
115 WriteLine("Saved " + Path.Combine(OutputPath, FILE_NAME));
116
117 await AddFileToOutputList(Path.Combine(OutputPath, FILE_NAME));
118
119 WriteLine("--------------------------------");
120 WriteLine("Done JBIG2 Compression Test.");
121 WriteLine("--------------------------------\n");
122
123 })).AsAsyncAction();
124 }
125 }
126}