1//
2// Copyright (c) 2001-2021 by PDFTron Systems Inc. All Rights Reserved.
3//
4
5using System;
6using System.Drawing;
7using System.Collections;
8
9using pdftron;
10using pdftron.Common;
11using pdftron.Filters;
12using pdftron.SDF;
13using pdftron.PDF;
14
15using NUnit.Framework;
16
17namespace MiscellaneousSamples
18{
19 /// <summary>
20 /// This sample project illustrates how to recompress bi-tonal images in an
21 /// existing PDF document using JBIG2 compression. The sample is not intended
22 /// to be a generic PDF optimization tool.
23 ///
24 /// You can download a sample scanned document using the following link:
25 /// http://www.pdftron.com/net/samplecode/data/US061222892.pdf
26 ///
27 /// Also a sample page compressed using CCITT Fax compression is located under
28 /// 'PDFNet/Samples/TestFiles' folder.
29 /// </summary>
30 [TestFixture]
31 public class JBIG2Test
32 {
33
34
35 /// <summary>
36 /// The main entry point for the application.
37 /// </summary>
38 [Test]
39 public static void Sample()
40 {
41 // Initialize PDFNet before calling any other PDFNet function.
42
43 const string input_path = "TestFiles/";
44 string input_filename = "US061222892-a.pdf";
45
46 PDFDoc pdf_doc = new PDFDoc(Utils.GetAssetTempFile(input_path + input_filename));
47 pdf_doc.InitSecurityHandler();
48
49 SDFDoc cos_doc = pdf_doc.GetSDFDoc();
50 int num_objs = cos_doc.XRefSize();
51
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 Obj hint = hint_set.CreateArray();
83 hint.PushBackName("JBIG2");
84 hint.PushBackName("Lossless");
85 hint.PushBackName("Threshold");
86 hint.PushBackNumber(0.4);
87 hint.PushBackName("SharePages");
88 hint.PushBackNumber(10000);
89
90 new_image = pdftron.PDF.Image.Create(
91 cos_doc,
92 reader,
93 input_image.GetImageWidth(),
94 input_image.GetImageHeight(),
95 1,
96 ColorSpace.CreateDeviceGray(),
97 hint // A hint to image encoder to use JBIG2 compression
98 );
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 pdf_doc.Save(Utils.CreateExternalFile("US061222892_JBIG2.pdf"), SDFDoc.SaveOptions.e_remove_unused);
114 pdf_doc.Close();
115 }
116 }
117}