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}