1 /*====================================================================*
2  -  Copyright (C) 2001 Leptonica.  All rights reserved.
3  -
4  -  Redistribution and use in source and binary forms, with or without
5  -  modification, are permitted provided that the following conditions
6  -  are met:
7  -  1. Redistributions of source code must retain the above copyright
8  -     notice, this list of conditions and the following disclaimer.
9  -  2. Redistributions in binary form must reproduce the above
10  -     copyright notice, this list of conditions and the following
11  -     disclaimer in the documentation and/or other materials
12  -     provided with the distribution.
13  -
14  -  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
15  -  ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
16  -  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
17  -  A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL ANY
18  -  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  -  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  -  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21  -  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22  -  OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
23  -  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24  -  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  *====================================================================*/
26 
27 /*
28  *  pdfiotest.c
29  */
30 
31 #include <string.h>
32 #include "allheaders.h"
33 
34 static void GetImageMask(PIX *pixs, l_int32 res, BOXA **pboxa,
35                          const char *debugfile);
36 static PIX * QuantizeNonImageRegion(PIX *pixs, PIX *pixm, l_int32 levels);
37 
38 
main(int argc,char ** argv)39 int main(int    argc,
40          char **argv)
41 {
42 char         buffer[512];
43 char        *tempfile1, *tempfile2;
44 l_uint8     *data;
45 l_int32      i, j, w, h, seq, ret, same;
46 size_t       nbytes;
47 const char  *title;
48 BOX         *box;
49 BOXA        *boxa1, *boxa2;
50 L_BYTEA     *ba;
51 L_PDF_DATA  *lpd;
52 PIX         *pix1, *pix2, *pix3, *pix4, *pix5, *pix6;
53 PIX         *pixs, *pixt, *pixg, *pixgc, *pixc;
54 static char  mainName[] = "pdfiotest";
55 
56     if (argc != 1)
57         return ERROR_INT("syntax: pdfiotest", mainName, 1);
58 
59     l_pdfSetDateAndVersion(0);
60     setLeptDebugOK(1);
61     lept_mkdir("lept/pdf");
62 
63 #if 1
64     /* ---------------  Single image tests  ------------------- */
65     fprintf(stderr, "\n*** Writing single images as pdf files\n");
66 
67     convertToPdf("weasel2.4c.png", L_FLATE_ENCODE, 0, "/tmp/lept/pdf/file01.pdf",
68                  0, 0, 72, "weasel2.4c.png", NULL, 0);
69     convertToPdf("test24.jpg", L_JPEG_ENCODE, 0, "/tmp/lept/pdf/file02.pdf",
70                  0, 0, 72, "test24.jpg", NULL, 0);
71     convertToPdf("feyn.tif", L_G4_ENCODE, 0, "/tmp/lept/pdf/file03.pdf",
72                  0, 0, 300, "feyn.tif", NULL, 0);
73 
74     pixs = pixRead("feyn.tif");
75     pixConvertToPdf(pixs, L_G4_ENCODE, 0, "/tmp/lept/pdf/file04.pdf", 0, 0, 300,
76                     "feyn.tif", NULL, 0);
77     pixDestroy(&pixs);
78 
79     pixs = pixRead("test24.jpg");
80     pixConvertToPdf(pixs, L_JPEG_ENCODE, 5, "/tmp/lept/pdf/file05.pdf",
81                     0, 0, 72, "test24.jpg", NULL, 0);
82     pixDestroy(&pixs);
83 
84     pixs = pixRead("feyn.tif");
85     pixt = pixScaleToGray2(pixs);
86     pixWrite("/tmp/lept/pdf/feyn8.png", pixt, IFF_PNG);
87     convertToPdf("/tmp/lept/pdf/feyn8.png", L_JPEG_ENCODE, 0,
88                  "/tmp/lept/pdf/file06.pdf", 0, 0, 150, "feyn8.png", NULL, 0);
89     pixDestroy(&pixs);
90     pixDestroy(&pixt);
91 
92     convertToPdf("weasel4.16g.png", L_FLATE_ENCODE, 0,
93                  "/tmp/lept/pdf/file07.pdf", 0, 0, 30,
94                  "weasel4.16g.png", NULL, 0);
95 
96     pixs = pixRead("test24.jpg");
97     pixg = pixConvertTo8(pixs, 0);
98     box = boxCreate(100, 100, 100, 100);
99     pixc = pixClipRectangle(pixs, box, NULL);
100     pixgc = pixClipRectangle(pixg, box, NULL);
101     pixWrite("/tmp/lept/pdf/pix32.jpg", pixc, IFF_JFIF_JPEG);
102     pixWrite("/tmp/lept/pdf/pix8.jpg", pixgc, IFF_JFIF_JPEG);
103     convertToPdf("/tmp/lept/pdf/pix32.jpg", L_FLATE_ENCODE, 0,
104                  "/tmp/lept/pdf/file08.pdf", 0, 0, 72, "pix32.jpg", NULL, 0);
105     convertToPdf("/tmp/lept/pdf/pix8.jpg", L_FLATE_ENCODE, 0,
106                  "/tmp/lept/pdf/file09.pdf", 0, 0, 72, "pix8.jpg", NULL, 0);
107     pixDestroy(&pixs);
108     pixDestroy(&pixg);
109     pixDestroy(&pixc);
110     pixDestroy(&pixgc);
111     boxDestroy(&box);
112 #endif
113 
114 
115 #if 1
116     /* ---------------  Multiple image tests  ------------------- */
117     fprintf(stderr, "\n*** Writing multiple images as single page pdf files\n");
118 
119     pix1 = pixRead("feyn-fract.tif");
120     pix2 = pixRead("weasel8.240c.png");
121 
122 /*    l_pdfSetDateAndVersion(0); */
123         /* First, write the 1 bpp image through the mask onto the weasels */
124     for (i = 0; i < 5; i++) {
125         for (j = 0; j < 10; j++) {
126             seq = (i == 0 && j == 0) ? L_FIRST_IMAGE : L_NEXT_IMAGE;
127             title = (i == 0 && j == 0) ? "feyn-fract.tif" : NULL;
128             pixConvertToPdf(pix2, L_FLATE_ENCODE, 0, NULL, 100 * j,
129                             100 * i, 70, title, &lpd, seq);
130         }
131     }
132     pixConvertToPdf(pix1, L_G4_ENCODE, 0, "/tmp/lept/pdf/file10.pdf", 0, 0, 80,
133                     NULL, &lpd, L_LAST_IMAGE);
134 
135         /* Now, write the 1 bpp image over the weasels */
136     l_pdfSetG4ImageMask(0);
137     for (i = 0; i < 5; i++) {
138         for (j = 0; j < 10; j++) {
139             seq = (i == 0 && j == 0) ? L_FIRST_IMAGE : L_NEXT_IMAGE;
140             title = (i == 0 && j == 0) ? "feyn-fract.tif" : NULL;
141             pixConvertToPdf(pix2, L_FLATE_ENCODE, 0, NULL, 100 * j,
142                             100 * i, 70, title, &lpd, seq);
143         }
144     }
145     pixConvertToPdf(pix1, L_G4_ENCODE, 0, "/tmp/lept/pdf/file11.pdf", 0, 0, 80,
146                     NULL, &lpd, L_LAST_IMAGE);
147     l_pdfSetG4ImageMask(1);
148     pixDestroy(&pix1);
149     pixDestroy(&pix2);
150 #endif
151 
152 #if 1
153     /* -------- pdf convert segmented with no image regions -------- */
154     fprintf(stderr, "\n*** Writing segmented images without image regions\n");
155 
156     pix1 = pixRead("rabi.png");
157     pix2 = pixScaleToGray2(pix1);
158     pixWrite("/tmp/lept/pdf/rabi8.jpg", pix2, IFF_JFIF_JPEG);
159     pix3 = pixThresholdTo4bpp(pix2, 16, 1);
160     pixWrite("/tmp/lept/pdf/rabi4.png", pix3, IFF_PNG);
161     pixDestroy(&pix1);
162     pixDestroy(&pix2);
163     pixDestroy(&pix3);
164 
165         /* 1 bpp input */
166     convertToPdfSegmented("rabi.png", 300, L_G4_ENCODE, 128, NULL, 0, 0,
167                           NULL, "/tmp/lept/pdf/file12.pdf");
168     convertToPdfSegmented("rabi.png", 300, L_JPEG_ENCODE, 128, NULL, 0, 0,
169                           NULL, "/tmp/lept/pdf/file13.pdf");
170     convertToPdfSegmented("rabi.png", 300, L_FLATE_ENCODE, 128, NULL, 0, 0,
171                           NULL, "/tmp/lept/pdf/file14.pdf");
172 
173         /* 8 bpp input, no cmap */
174     convertToPdfSegmented("/tmp/lept/pdf/rabi8.jpg", 150, L_G4_ENCODE, 128,
175                           NULL, 0, 0, NULL, "/tmp/lept/pdf/file15.pdf");
176     convertToPdfSegmented("/tmp/lept/pdf/rabi8.jpg", 150, L_JPEG_ENCODE, 128,
177                           NULL, 0, 0, NULL, "/tmp/lept/pdf/file16.pdf");
178     convertToPdfSegmented("/tmp/lept/pdf/rabi8.jpg", 150, L_FLATE_ENCODE, 128,
179                           NULL, 0, 0, NULL, "/tmp/lept/pdf/file17.pdf");
180 
181         /* 4 bpp input, cmap */
182     convertToPdfSegmented("/tmp/lept/pdf/rabi4.png", 150, L_G4_ENCODE, 128,
183                           NULL, 0, 0, NULL, "/tmp/lept/pdf/file18.pdf");
184     convertToPdfSegmented("/tmp/lept/pdf/rabi4.png", 150, L_JPEG_ENCODE, 128,
185                           NULL, 0, 0, NULL, "/tmp/lept/pdf/file19.pdf");
186     convertToPdfSegmented("/tmp/lept/pdf/rabi4.png", 150, L_FLATE_ENCODE, 128,
187                           NULL, 0, 0, NULL, "/tmp/lept/pdf/file20.pdf");
188 
189 #endif
190 
191 #if 1
192     /* ---------- pdf convert segmented with image regions ---------- */
193     fprintf(stderr, "\n*** Writing segmented images with image regions\n");
194 
195         /* Get the image region(s) for rabi.png.  There are two
196          * small bogus regions at the top, but we'll keep them for
197          * the demonstration. */
198     pix1 = pixRead("rabi.png");
199     pixSetResolution(pix1, 300, 300);
200     pixGetDimensions(pix1, &w, &h, NULL);
201     pix2 = pixGenerateHalftoneMask(pix1, NULL, NULL, NULL);
202     pix3 = pixMorphSequence(pix2, "c20.1 + c1.20", 0);
203     boxa1 = pixConnComp(pix3, NULL, 8);
204     boxa2 = boxaTransform(boxa1, 0, 0, 0.5, 0.5);
205     pixDestroy(&pix1);
206     pixDestroy(&pix2);
207     pixDestroy(&pix3);
208 
209         /* 1 bpp input */
210     convertToPdfSegmented("rabi.png", 300, L_G4_ENCODE, 128, boxa1,
211                           0, 0.25, NULL, "/tmp/lept/pdf/file21.pdf");
212     convertToPdfSegmented("rabi.png", 300, L_JPEG_ENCODE, 128, boxa1,
213                           0, 0.25, NULL, "/tmp/lept/pdf/file22.pdf");
214     convertToPdfSegmented("rabi.png", 300, L_FLATE_ENCODE, 128, boxa1,
215                           0, 0.25, NULL, "/tmp/lept/pdf/file23.pdf");
216 
217         /* 8 bpp input, no cmap */
218     convertToPdfSegmented("/tmp/lept/pdf/rabi8.jpg", 150, L_G4_ENCODE, 128,
219                           boxa2, 0, 0.5, NULL, "/tmp/lept/pdf/file24.pdf");
220     convertToPdfSegmented("/tmp/lept/pdf/rabi8.jpg", 150, L_JPEG_ENCODE, 128,
221                           boxa2, 0, 0.5, NULL, "/tmp/lept/pdf/file25.pdf");
222     convertToPdfSegmented("/tmp/lept/pdf/rabi8.jpg", 150, L_FLATE_ENCODE, 128,
223                           boxa2, 0, 0.5, NULL, "/tmp/lept/pdf/file26.pdf");
224 
225         /* 4 bpp input, cmap */
226     convertToPdfSegmented("/tmp/lept/pdf/rabi4.png", 150, L_G4_ENCODE, 128,
227                           boxa2, 0, 0.5, NULL, "/tmp/lept/pdf/file27.pdf");
228     convertToPdfSegmented("/tmp/lept/pdf/rabi4.png", 150, L_JPEG_ENCODE, 128,
229                           boxa2, 0, 0.5, NULL, "/tmp/lept/pdf/file28.pdf");
230     convertToPdfSegmented("/tmp/lept/pdf/rabi4.png", 150, L_FLATE_ENCODE, 128,
231                           boxa2, 0, 0.5, NULL, "/tmp/lept/pdf/file29.pdf");
232 
233         /* 4 bpp input, cmap, data output */
234     data = NULL;
235     convertToPdfDataSegmented("/tmp/lept/pdf/rabi4.png", 150, L_G4_ENCODE,
236                               128, boxa2, 0, 0.5, NULL, &data, &nbytes);
237     l_binaryWrite("/tmp/lept/pdf/file30.pdf", "w", data, nbytes);
238     lept_free(data);
239     convertToPdfDataSegmented("/tmp/lept/pdf/rabi4.png", 150, L_JPEG_ENCODE,
240                               128, boxa2, 0, 0.5, NULL, &data, &nbytes);
241     l_binaryWrite("/tmp/lept/pdf/file31.pdf", "w", data, nbytes);
242     lept_free(data);
243     convertToPdfDataSegmented("/tmp/lept/pdf/rabi4.png", 150, L_FLATE_ENCODE,
244                               128, boxa2, 0, 0.5, NULL, &data, &nbytes);
245     l_binaryWrite("/tmp/lept/pdf/file32.pdf", "w", data, nbytes);
246     lept_free(data);
247 
248     boxaDestroy(&boxa1);
249     boxaDestroy(&boxa2);
250 #endif
251 
252 
253 #if 1
254     /* -------- pdf convert segmented from color image -------- */
255     fprintf(stderr, "\n*** Writing color segmented images\n");
256 
257     pix1 = pixRead("candelabrum.011.jpg");
258     pix2 = pixScale(pix1, 3.0, 3.0);
259     pixWrite("/tmp/lept/pdf/candelabrum3.jpg", pix2, IFF_JFIF_JPEG);
260     GetImageMask(pix2, 200, &boxa1, "/tmp/lept/pdf/seg1.jpg");
261     convertToPdfSegmented("/tmp/lept/pdf/candelabrum3.jpg", 200, L_G4_ENCODE,
262                           100, boxa1, 0, 0.25, NULL,
263                           "/tmp/lept/pdf/file33.pdf");
264     convertToPdfSegmented("/tmp/lept/pdf/candelabrum3.jpg", 200, L_JPEG_ENCODE,
265                           100, boxa1, 0, 0.25, NULL,
266                           "/tmp/lept/pdf/file34.pdf");
267     convertToPdfSegmented("/tmp/lept/pdf/candelabrum3.jpg", 200, L_FLATE_ENCODE,
268                           100, boxa1, 0, 0.25, NULL,
269                           "/tmp/lept/pdf/file35.pdf");
270 
271     pixDestroy(&pix1);
272     pixDestroy(&pix2);
273     boxaDestroy(&boxa1);
274 
275     pix1 = pixRead("lion-page.00016.jpg");
276     pix2 = pixScale(pix1, 3.0, 3.0);
277     pixWrite("/tmp/lept/pdf/lion16.jpg", pix2, IFF_JFIF_JPEG);
278     pix3 = pixRead("lion-mask.00016.tif");
279     boxa1 = pixConnComp(pix3, NULL, 8);
280     boxa2 = boxaTransform(boxa1, 0, 0, 3.0, 3.0);
281     convertToPdfSegmented("/tmp/lept/pdf/lion16.jpg", 200, L_G4_ENCODE,
282                           190, boxa2, 0, 0.5, NULL, "/tmp/lept/pdf/file36.pdf");
283     convertToPdfSegmented("/tmp/lept/pdf/lion16.jpg", 200, L_JPEG_ENCODE,
284                           190, boxa2, 0, 0.5, NULL, "/tmp/lept/pdf/file37.pdf");
285     convertToPdfSegmented("/tmp/lept/pdf/lion16.jpg", 200, L_FLATE_ENCODE,
286                           190, boxa2, 0, 0.5, NULL, "/tmp/lept/pdf/file38.pdf");
287 
288         /* Quantize the non-image part and flate encode.
289          * This is useful because it results in a smaller file than
290          * when you flate-encode the un-quantized non-image regions. */
291     pix4 = pixScale(pix3, 3.0, 3.0);  /* higher res mask, for combining */
292     pix5 = QuantizeNonImageRegion(pix2, pix4, 12);
293     pixWrite("/tmp/lept/pdf/lion16-quant.png", pix5, IFF_PNG);
294     convertToPdfSegmented("/tmp/lept/pdf/lion16-quant.png", 200, L_FLATE_ENCODE,
295                           190, boxa2, 0, 0.5, NULL, "/tmp/lept/pdf/file39.pdf");
296 
297     pixDestroy(&pix1);
298     pixDestroy(&pix2);
299     pixDestroy(&pix3);
300     pixDestroy(&pix4);
301     pixDestroy(&pix5);
302     boxaDestroy(&boxa1);
303     boxaDestroy(&boxa2);
304 #endif
305 
306 #if 1
307     /* ------------------ Test multipage pdf generation ----------------- */
308     fprintf(stderr, "\n*** Writing multipage pdfs from single page pdfs\n");
309 
310         /* Generate a multi-page pdf from all these files */
311     startTimer();
312     concatenatePdf("/tmp/lept/pdf", "file", "/tmp/lept/pdf/cat_lept.pdf");
313     fprintf(stderr,
314             "All files have been concatenated: /tmp/lept/pdf/cat_lept.pdf\n"
315                     "Concatenation time: %7.3f\n", stopTimer());
316 #endif
317 
318 #if 1
319     /* ----------- Test corruption recovery by concatenation ------------ */
320         /* Put two good pdf files in a directory */
321     lept_rmdir("lept/good");
322     lept_mkdir("lept/good");
323     lept_cp("testfile1.pdf", "lept/good", NULL, NULL);
324     lept_cp("testfile2.pdf", "lept/good", NULL, NULL);
325     concatenatePdf("/tmp/lept/good", "file", "/tmp/lept/pdf/good.pdf");
326 
327         /* Make a bad version with the pdf id removed, so that it is not
328          * recognized as a pdf */
329     lept_rmdir("lept/bad");
330     lept_mkdir("lept/bad");
331     ba = l_byteaInitFromFile("testfile2.pdf");
332     data = l_byteaGetData(ba, &nbytes);
333     l_binaryWrite("/tmp/lept/bad/testfile0.notpdf.pdf", "w",
334                   data + 10, nbytes - 10);
335 
336         /* Make a version with a corrupted trailer */
337     if (data)
338         data[2297] = '2';  /* munge trailer object 6: change 458 --> 428 */
339     l_binaryWrite("/tmp/lept/bad/testfile2.bad.pdf", "w", data, nbytes);
340     l_byteaDestroy(&ba);
341 
342         /* Copy testfile1.pdf to the /tmp/lept/bad directory.  Then
343          * run concat on the bad files.  The "not pdf" file should be
344          * ignored, and the corrupted pdf file should be properly parsed,
345          * so the resulting concatenated pdf files should be identical.  */
346     fprintf(stderr, "\nWe attempt to build from the bad directory\n");
347     lept_cp("testfile1.pdf", "lept/bad", NULL, NULL);
348     concatenatePdf("/tmp/lept/bad", "file", "/tmp/lept/pdf/bad.pdf");
349     filesAreIdentical("/tmp/lept/pdf/good.pdf", "/tmp/lept/pdf/bad.pdf", &same);
350     if (same)
351         fprintf(stderr, "Fixed: files are the same\n"
352                         "Attempt succeeded\n");
353     else
354         fprintf(stderr, "Busted: files are different\n");
355 #endif
356 
357 #if 0
358     fprintf(stderr, "\n*** pdftk writes multipage pdfs from images\n");
359     tempfile1 = genPathname("/tmp/lept/pdf", "file*.pdf");
360     tempfile2 = genPathname("/tmp/lept/pdf", "cat_pdftk.pdf");
361     snprintf(buffer, sizeof(buffer), "pdftk %s output %s",
362              tempfile1, tempfile2);
363     ret = system(buffer);  /* pdftk */
364     lept_free(tempfile1);
365     lept_free(tempfile2);
366 #endif
367 
368 #if 1
369     /* -- Test simple interface for generating multi-page pdf from images -- */
370     fprintf(stderr, "\n*** Writing multipage pdfs from images\n");
371 
372         /* Put four image files in a directory.  They will be encoded thus:
373          *     file1.png:  flate (8 bpp, only 10 colors)
374          *     file2.jpg:  dct (8 bpp, 256 colors because of the jpeg encoding)
375          *     file3.tif:  g4 (1 bpp)
376          *     file4.jpg:  dct (32 bpp)    */
377     lept_mkdir("lept/image");
378     pix1 = pixRead("feyn.tif");
379     pix2 = pixRead("rabi.png");
380     pix3 = pixScaleToGray3(pix1);
381     pix4 = pixScaleToGray3(pix2);
382     pix5 = pixScale(pix1, 0.33, 0.33);
383     pix6 = pixRead("test24.jpg");
384     pixWrite("/tmp/lept/image/file1.png", pix3, IFF_PNG);  /* 10 colors */
385     pixWrite("/tmp/lept/image/file2.jpg", pix4, IFF_JFIF_JPEG); /* 256 colors */
386     pixWrite("/tmp/lept/image/file3.tif", pix5, IFF_TIFF_G4);
387     pixWrite("/tmp/lept/image/file4.jpg", pix6, IFF_JFIF_JPEG);
388 
389     startTimer();
390     convertFilesToPdf("/tmp/lept/image", "file", 100, 0.8, 0, 75, "4 file test",
391                       "/tmp/lept/pdf/fourimages.pdf");
392     fprintf(stderr, "4-page pdf generated: /tmp/lept/pdf/fourimages.pdf\n"
393                     "Time: %7.3f\n", stopTimer());
394     pixDestroy(&pix1);
395     pixDestroy(&pix2);
396     pixDestroy(&pix3);
397     pixDestroy(&pix4);
398     pixDestroy(&pix5);
399     pixDestroy(&pix6);
400 #endif
401 
402     return 0;
403 }
404 
405 
406 static void
GetImageMask(PIX * pixs,l_int32 res,BOXA ** pboxa,const char * debugfile)407 GetImageMask(PIX         *pixs,
408              l_int32      res,
409              BOXA       **pboxa,
410              const char  *debugfile)
411 {
412 PIX   *pix1, *pix2, *pix3, *pix4;
413 PIXA  *pixa;
414 
415     pixSetResolution(pixs, 200, 200);
416     pix1 = pixConvertTo1(pixs, 100);
417     pix2 = pixGenerateHalftoneMask(pix1, NULL, NULL, NULL);
418     pix3 = pixMorphSequence(pix2, "c20.1 + c1.20", 0);
419     *pboxa = pixConnComp(pix3, NULL, 8);
420     if (debugfile) {
421         pixa = pixaCreate(0);
422         pixaAddPix(pixa, pixs, L_COPY);
423         pixaAddPix(pixa, pix1, L_INSERT);
424         pixaAddPix(pixa, pix2, L_INSERT);
425         pixaAddPix(pixa, pix3, L_INSERT);
426         pix4 = pixaDisplayTiledInRows(pixa, 32, 1800, 0.25, 0, 25, 2);
427         pixWrite(debugfile, pix4, IFF_JFIF_JPEG);
428         pixDisplay(pix4, 100, 100);
429         pixDestroy(&pix4);
430         pixaDestroy(&pixa);
431     } else {
432         pixDestroy(&pix1);
433         pixDestroy(&pix2);
434         pixDestroy(&pix3);
435     }
436 
437     return;
438 }
439 
440 static PIX *
QuantizeNonImageRegion(PIX * pixs,PIX * pixm,l_int32 levels)441 QuantizeNonImageRegion(PIX     *pixs,
442                        PIX     *pixm,
443                        l_int32  levels)
444 {
445 PIX  *pix1, *pix2, *pixd;
446 
447     pix1 = pixConvertTo8(pixs, 0);
448     pix2 = pixThresholdOn8bpp(pix1, levels, 1);
449     pixd = pixConvertTo32(pix2);  /* save in rgb */
450     pixCombineMasked(pixd, pixs, pixm);  /* rgb result */
451     pixDestroy(&pix1);
452     pixDestroy(&pix2);
453     return pixd;
454 }
455