1 /*
2  * SpanDSP - a series of DSP components for telephony
3  *
4  * generate_sized_pages.c - Create a series of TIFF files in the various page sizes
5  *                          and resolutions.
6  *
7  * Written by Steve Underwood <steveu@coppice.org>
8  *
9  * Copyright (C) 2006 Steve Underwood
10  *
11  * All rights reserved.
12  *
13  * This program is free software; you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License version 2, as
15  * published by the Free Software Foundation.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25  */
26 
27 /*! \file */
28 
29 #if defined(HAVE_CONFIG_H)
30 #include "config.h"
31 #endif
32 
33 #include <stdio.h>
34 #include <inttypes.h>
35 #include <limits.h>
36 #include <unistd.h>
37 #include <fcntl.h>
38 #include <stdlib.h>
39 #include <time.h>
40 #include <memory.h>
41 #include <string.h>
42 #if defined(HAVE_TGMATH_H)
43 #include <tgmath.h>
44 #endif
45 #if defined(HAVE_MATH_H)
46 #include <math.h>
47 #endif
48 
49 #include "spandsp.h"
50 
51 struct
52 {
53     const char *name;
54     int x_res;
55     int y_res;
56     int width;
57     int length;
58     int squashing_factor;
59 } sequence[] =
60 {
61     {
62         "bilevel_R8_385_A4.tif",
63         T4_X_RESOLUTION_R8,
64         T4_Y_RESOLUTION_STANDARD,
65         T4_WIDTH_R8_A4,
66         1100,
67         1
68     },
69     {
70         "bilevel_R8_385_B4.tif",
71         T4_X_RESOLUTION_R8,
72         T4_Y_RESOLUTION_STANDARD,
73         T4_WIDTH_R8_B4,
74         1200,
75         1
76     },
77     {
78         "bilevel_R8_385_A3.tif",
79         T4_X_RESOLUTION_R8,
80         T4_Y_RESOLUTION_STANDARD,
81         T4_WIDTH_R8_A3,
82         1556,
83         1
84     },
85     {
86         "bilevel_R8_77_A4.tif",
87         T4_X_RESOLUTION_R8,
88         T4_Y_RESOLUTION_FINE,
89         T4_WIDTH_R8_A4,
90         1100*2,
91         1
92     },
93     {
94         "bilevel_R8_77_B4.tif",
95         T4_X_RESOLUTION_R8,
96         T4_Y_RESOLUTION_FINE,
97         T4_WIDTH_R8_B4,
98         1200*2,
99         1
100     },
101     {
102         "bilevel_R8_77_A3.tif",
103         T4_X_RESOLUTION_R8,
104         T4_Y_RESOLUTION_FINE,
105         T4_WIDTH_R8_A3,
106         1556*2,
107         1
108     },
109     {
110         "bilevel_R8_154_A4.tif",
111         T4_X_RESOLUTION_R8,
112         T4_Y_RESOLUTION_SUPERFINE,
113         T4_WIDTH_R8_A4,
114         1100*4,
115         1
116     },
117     {
118         "bilevel_R8_154_B4.tif",
119         T4_X_RESOLUTION_R8,
120         T4_Y_RESOLUTION_SUPERFINE,
121         T4_WIDTH_R8_B4,
122         1200*4,
123         1
124     },
125     {
126         "bilevel_R8_154_A3.tif",
127         T4_X_RESOLUTION_R8,
128         T4_Y_RESOLUTION_SUPERFINE,
129         T4_WIDTH_R8_A3,
130         1556*4,
131         1
132     },
133     {
134         "bilevel_R16_154_A4.tif",
135         T4_X_RESOLUTION_R16,
136         T4_Y_RESOLUTION_SUPERFINE,
137         T4_WIDTH_R16_A4,
138         1100*4,
139         1
140     },
141     {
142         "bilevel_R16_154_B4.tif",
143         T4_X_RESOLUTION_R16,
144         T4_Y_RESOLUTION_SUPERFINE,
145         T4_WIDTH_R16_B4,
146         1200*4,
147         1
148     },
149     {
150         "bilevel_R16_154_A3.tif",
151         T4_X_RESOLUTION_R16,
152         T4_Y_RESOLUTION_SUPERFINE,
153         T4_WIDTH_R16_A3,
154         1556*4,
155         1
156     },
157     {
158         "bilevel_200_100_A4.tif",
159         T4_X_RESOLUTION_200,
160         T4_Y_RESOLUTION_100,
161         T4_WIDTH_200_A4,
162         1100,
163         1
164     },
165     {
166         "bilevel_200_100_B4.tif",
167         T4_X_RESOLUTION_200,
168         T4_Y_RESOLUTION_100,
169         T4_WIDTH_200_B4,
170         1200,
171         1
172     },
173     {
174         "bilevel_200_100_A3.tif",
175         T4_X_RESOLUTION_200,
176         T4_Y_RESOLUTION_100,
177         T4_WIDTH_200_A3,
178         1556,
179         1
180     },
181     {
182         "bilevel_200_200_A4.tif",
183         T4_X_RESOLUTION_200,
184         T4_Y_RESOLUTION_200,
185         T4_WIDTH_200_A4,
186         1100*2,
187         1
188     },
189     {
190         "bilevel_200_200_B4.tif",
191         T4_X_RESOLUTION_200,
192         T4_Y_RESOLUTION_200,
193         T4_WIDTH_200_B4,
194         1200*2,
195         1
196     },
197     {
198         "bilevel_200_200_A3.tif",
199         T4_X_RESOLUTION_200,
200         T4_Y_RESOLUTION_200,
201         T4_WIDTH_200_A3,
202         1556*2,
203         1
204     },
205     {
206         "bilevel_200_400_A4.tif",
207         T4_X_RESOLUTION_200,
208         T4_Y_RESOLUTION_400,
209         T4_WIDTH_200_A4,
210         1100*4,
211         1
212     },
213     {
214         "bilevel_200_400_B4.tif",
215         T4_X_RESOLUTION_200,
216         T4_Y_RESOLUTION_400,
217         T4_WIDTH_200_B4,
218         1200*4,
219         1
220     },
221     {
222         "bilevel_200_400_A3.tif",
223         T4_X_RESOLUTION_200,
224         T4_Y_RESOLUTION_400,
225         T4_WIDTH_200_A3,
226         1556*4,
227         1
228     },
229     {
230         "bilevel_300_300_A4.tif",
231         T4_X_RESOLUTION_300,
232         T4_Y_RESOLUTION_300,
233         T4_WIDTH_300_A4,
234         1100*3,
235         1
236     },
237     {
238         "bilevel_300_300_B4.tif",
239         T4_X_RESOLUTION_300,
240         T4_Y_RESOLUTION_300,
241         T4_WIDTH_300_B4,
242         1200*3,
243         1
244     },
245     {
246         "bilevel_300_300_A3.tif",
247         T4_X_RESOLUTION_300,
248         T4_Y_RESOLUTION_300,
249         T4_WIDTH_300_A3,
250         1556*3,
251         1
252     },
253     {
254         "bilevel_300_600_A4.tif",
255         T4_X_RESOLUTION_300,
256         T4_Y_RESOLUTION_600,
257         T4_WIDTH_300_A4,
258         1100*6,
259         1
260     },
261     {
262         "bilevel_300_600_B4.tif",
263         T4_X_RESOLUTION_300,
264         T4_Y_RESOLUTION_600,
265         T4_WIDTH_300_B4,
266         1200*6,
267         1
268     },
269     {
270         "bilevel_300_600_A3.tif",
271         T4_X_RESOLUTION_300,
272         T4_Y_RESOLUTION_600,
273         T4_WIDTH_300_A3,
274         1556*6,
275         1
276     },
277     {
278         "bilevel_400_400_A4.tif",
279         T4_X_RESOLUTION_400,
280         T4_Y_RESOLUTION_400,
281         T4_WIDTH_400_A4,
282         1100*4,
283         1
284     },
285     {
286         "bilevel_400_400_B4.tif",
287         T4_X_RESOLUTION_400,
288         T4_Y_RESOLUTION_400,
289         T4_WIDTH_400_B4,
290         1200*4,
291         1
292     },
293     {
294         "bilevel_400_400_A3.tif",
295         T4_X_RESOLUTION_400,
296         T4_Y_RESOLUTION_400,
297         T4_WIDTH_400_A3,
298         1556*4,
299         1
300     },
301     {
302         "bilevel_400_800_A4.tif",
303         T4_X_RESOLUTION_400,
304         T4_Y_RESOLUTION_800,
305         T4_WIDTH_400_A4,
306         1100*8,
307         1
308     },
309     {
310         "bilevel_400_800_B4.tif",
311         T4_X_RESOLUTION_400,
312         T4_Y_RESOLUTION_800,
313         T4_WIDTH_400_B4,
314         1200*8,
315         1
316     },
317     {
318         "bilevel_400_800_A3.tif",
319         T4_X_RESOLUTION_400,
320         T4_Y_RESOLUTION_800,
321         T4_WIDTH_400_A3,
322         1556*8,
323         1
324     },
325     {
326         "bilevel_600_600_A4.tif",
327         T4_X_RESOLUTION_600,
328         T4_Y_RESOLUTION_600,
329         T4_WIDTH_600_A4,
330         1100*6,
331         1
332     },
333     {
334         "bilevel_600_600_B4.tif",
335         T4_X_RESOLUTION_600,
336         T4_Y_RESOLUTION_600,
337         T4_WIDTH_600_B4,
338         1200*6,
339         1
340     },
341     {
342         "bilevel_600_600_A3.tif",
343         T4_X_RESOLUTION_600,
344         T4_Y_RESOLUTION_600,
345         T4_WIDTH_600_A3,
346         1556*6,
347         1
348     },
349     {
350         "bilevel_600_1200_A4.tif",
351         T4_X_RESOLUTION_600,
352         T4_Y_RESOLUTION_1200,
353         T4_WIDTH_600_A4,
354         1100*12,
355         1
356     },
357     {
358         "bilevel_600_1200_B4.tif",
359         T4_X_RESOLUTION_600,
360         T4_Y_RESOLUTION_1200,
361         T4_WIDTH_600_B4,
362         1200*12,
363         1
364     },
365     {
366         "bilevel_600_1200_A3.tif",
367         T4_X_RESOLUTION_600,
368         T4_Y_RESOLUTION_1200,
369         T4_WIDTH_600_A3,
370         1556*12,
371         1
372     },
373     {
374         "bilevel_1200_1200_A4.tif",
375         T4_X_RESOLUTION_1200,
376         T4_Y_RESOLUTION_1200,
377         T4_WIDTH_1200_A4,
378         1100*12,
379         1
380     },
381     {
382         "bilevel_1200_1200_B4.tif",
383         T4_X_RESOLUTION_1200,
384         T4_Y_RESOLUTION_1200,
385         T4_WIDTH_1200_B4,
386         1200*12,
387         1
388     },
389     {
390         "bilevel_1200_1200_A3.tif",
391         T4_X_RESOLUTION_1200,
392         T4_Y_RESOLUTION_1200,
393         T4_WIDTH_1200_A3,
394         1556*12,
395         1
396     },
397     {
398         "bilevel_R8_77SQ_A4.tif",
399         T4_X_RESOLUTION_R8,
400         T4_Y_RESOLUTION_STANDARD,
401         T4_WIDTH_R8_A4,
402         1100,
403         2
404     },
405     {
406         "bilevel_R8_77SQ_B4.tif",
407         T4_X_RESOLUTION_R8,
408         T4_Y_RESOLUTION_STANDARD,
409         T4_WIDTH_R8_B4,
410         1200,
411         2
412     },
413     {
414         "bilevel_R8_77SQ_A3.tif",
415         T4_X_RESOLUTION_R8,
416         T4_Y_RESOLUTION_STANDARD,
417         T4_WIDTH_R8_A3,
418         1556,
419         2
420     },
421     {
422         "bilevel_R8_154SQSQ_A4.tif",
423         T4_X_RESOLUTION_R8,
424         T4_Y_RESOLUTION_STANDARD,
425         T4_WIDTH_R8_A4,
426         1100,
427         4
428     },
429     {
430         "bilevel_R8_154SQSQ_B4.tif",
431         T4_X_RESOLUTION_R8,
432         T4_Y_RESOLUTION_STANDARD,
433         T4_WIDTH_R8_B4,
434         1200,
435         4
436     },
437     {
438         "bilevel_R8_154SQSQ_A3.tif",
439         T4_X_RESOLUTION_R8,
440         T4_Y_RESOLUTION_STANDARD,
441         T4_WIDTH_R8_A3,
442         1556,
443         4
444     },
445     {
446         "bilevel_R8_154SQ_A4.tif",
447         T4_X_RESOLUTION_R8,
448         T4_Y_RESOLUTION_FINE,
449         T4_WIDTH_R8_A4,
450         1100*2,
451         2
452     },
453     {
454         "bilevel_R8_154SQ_B4.tif",
455         T4_X_RESOLUTION_R8,
456         T4_Y_RESOLUTION_FINE,
457         T4_WIDTH_R8_B4,
458         1200*2,
459         2
460     },
461     {
462         "bilevel_R8_154SQ_A3.tif",
463         T4_X_RESOLUTION_R8,
464         T4_Y_RESOLUTION_FINE,
465         T4_WIDTH_R8_A3,
466         1556*2,
467         2
468     },
469     {
470         "bilevel_200_200SQ_A4.tif",
471         T4_X_RESOLUTION_200,
472         T4_Y_RESOLUTION_100,
473         T4_WIDTH_200_A4,
474         1100,
475         2
476     },
477     {
478         "bilevel_200_200SQ_B4.tif",
479         T4_X_RESOLUTION_200,
480         T4_Y_RESOLUTION_100,
481         T4_WIDTH_200_B4,
482         1200,
483         2
484     },
485     {
486         "bilevel_200_200SQ_A3.tif",
487         T4_X_RESOLUTION_200,
488         T4_Y_RESOLUTION_100,
489         T4_WIDTH_200_A3,
490         1556,
491         2
492     },
493     {
494         "bilevel_200_400SQSQ_A4.tif",
495         T4_X_RESOLUTION_200,
496         T4_Y_RESOLUTION_100,
497         T4_WIDTH_200_A4,
498         1100,
499         4
500     },
501     {
502         "bilevel_200_400SQSQ_B4.tif",
503         T4_X_RESOLUTION_200,
504         T4_Y_RESOLUTION_100,
505         T4_WIDTH_200_B4,
506         1200,
507         4
508     },
509     {
510         "bilevel_200_400SQSQ_A3.tif",
511         T4_X_RESOLUTION_200,
512         T4_Y_RESOLUTION_100,
513         T4_WIDTH_200_A3,
514         1556,
515         4
516     },
517     {
518         "bilevel_200_400SQ_A4.tif",
519         T4_X_RESOLUTION_200,
520         T4_Y_RESOLUTION_200,
521         T4_WIDTH_200_A4,
522         1100*2,
523         2
524     },
525     {
526         "bilevel_200_400SQ_B4.tif",
527         T4_X_RESOLUTION_200,
528         T4_Y_RESOLUTION_200,
529         T4_WIDTH_200_B4,
530         1200*2,
531         2
532     },
533     {
534         "bilevel_200_400SQ_A3.tif",
535         T4_X_RESOLUTION_200,
536         T4_Y_RESOLUTION_200,
537         T4_WIDTH_200_A3,
538         1556*2,
539         2
540     },
541     {
542         NULL,
543         0,
544         0,
545         0,
546         0,
547         0
548     },
549 };
550 
set_pixel(uint8_t buf[],int row,int pixel)551 static void set_pixel(uint8_t buf[], int row, int pixel)
552 {
553     row--;
554     buf[row*1728/8 + pixel/8] |= (0x80 >> (pixel & 0x07));
555 }
556 /*- End of function --------------------------------------------------------*/
557 
set_pixel_range(uint8_t buf[],int row,int start,int end)558 static void set_pixel_range(uint8_t buf[], int row, int start, int end)
559 {
560     int i;
561 
562     for (i = start;  i <= end;  i++)
563         set_pixel(buf, row, i);
564 }
565 /*- End of function --------------------------------------------------------*/
566 
567 #if 0
568 static void clear_pixel(uint8_t buf[], int row, int pixel)
569 {
570     row--;
571     buf[row*1728/8 + pixel/8] &= ~(0x80 >> (pixel & 0x07));
572 }
573 /*- End of function --------------------------------------------------------*/
574 
575 static void clear_pixel_range(uint8_t buf[], int row, int start, int end)
576 {
577     int i;
578 
579     for (i = start;  i <= end;  i++)
580         clear_pixel(buf, row, i);
581 }
582 /*- End of function --------------------------------------------------------*/
583 #endif
584 
clear_row(uint8_t buf[],int width)585 static void clear_row(uint8_t buf[], int width)
586 {
587     memset(buf, 0, width/8 + 1);
588 }
589 /*- End of function --------------------------------------------------------*/
590 
main(int argc,char * argv[])591 int main(int argc, char *argv[])
592 {
593     int row;
594     uint8_t image_buffer[8192];
595     TIFF *tiff_file;
596     struct tm *tm;
597     time_t now;
598     char buf[133];
599     float x_resolution;
600     float y_resolution;
601     int i;
602     int j;
603     int k;
604     int opt;
605     int compression;
606     int photo_metric;
607     int fill_order;
608     int output_t4_options;
609 
610     compression = COMPRESSION_CCITT_T6;
611     output_t4_options = 0;
612     photo_metric = PHOTOMETRIC_MINISWHITE;
613     fill_order = FILLORDER_LSB2MSB;
614     while ((opt = getopt(argc, argv, "126ir")) != -1)
615     {
616         switch (opt)
617         {
618         case '1':
619             compression = COMPRESSION_CCITT_T4;
620             output_t4_options = GROUP3OPT_FILLBITS;
621             break;
622         case '2':
623             compression = COMPRESSION_CCITT_T4;
624             output_t4_options = GROUP3OPT_FILLBITS | GROUP3OPT_2DENCODING;
625             break;
626         case '6':
627             compression = COMPRESSION_CCITT_T6;
628             output_t4_options = 0;
629             break;
630         case 'i':
631             photo_metric = PHOTOMETRIC_MINISBLACK;
632             break;
633         case 'r':
634             fill_order = FILLORDER_MSB2LSB;
635             break;
636         default:
637             //usage();
638             exit(2);
639             break;
640         }
641     }
642 
643     for (i = 0;  sequence[i].name;  i++)
644     {
645         if ((tiff_file = TIFFOpen(sequence[i].name, "w")) == NULL)
646             exit(2);
647 
648         /* Prepare the directory entry fully before writing the image, or libtiff complains */
649         TIFFSetField(tiff_file, TIFFTAG_COMPRESSION, compression);
650         if (output_t4_options)
651             TIFFSetField(tiff_file, TIFFTAG_T4OPTIONS, output_t4_options);
652         TIFFSetField(tiff_file, TIFFTAG_FAXMODE, FAXMODE_CLASSF);
653         TIFFSetField(tiff_file, TIFFTAG_IMAGEWIDTH, sequence[i].width);
654         TIFFSetField(tiff_file, TIFFTAG_BITSPERSAMPLE, 1);
655         TIFFSetField(tiff_file, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
656         TIFFSetField(tiff_file, TIFFTAG_SAMPLESPERPIXEL, 1);
657         TIFFSetField(tiff_file, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
658         TIFFSetField(tiff_file, TIFFTAG_PHOTOMETRIC, photo_metric);
659         TIFFSetField(tiff_file, TIFFTAG_FILLORDER, fill_order);
660 
661         x_resolution = sequence[i].x_res/100.0f;
662         y_resolution = sequence[i].y_res/100.0f;
663         TIFFSetField(tiff_file, TIFFTAG_XRESOLUTION, floorf(x_resolution*2.54f + 0.5f));
664         TIFFSetField(tiff_file, TIFFTAG_YRESOLUTION, floorf(y_resolution*2.54f + 0.5f));
665         TIFFSetField(tiff_file, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH);
666 
667         if (gethostname(buf, sizeof(buf)) == 0)
668             TIFFSetField(tiff_file, TIFFTAG_HOSTCOMPUTER, buf);
669 
670         TIFFSetField(tiff_file, TIFFTAG_SOFTWARE, "Spandsp");
671         TIFFSetField(tiff_file, TIFFTAG_IMAGEDESCRIPTION, "Diagonally striped test image");
672         TIFFSetField(tiff_file, TIFFTAG_MAKE, "soft-switch.org");
673         TIFFSetField(tiff_file, TIFFTAG_MODEL, "testy");
674 
675         time(&now);
676         tm = localtime(&now);
677         sprintf(buf,
678     	        "%4d/%02d/%02d %02d:%02d:%02d",
679                 tm->tm_year + 1900,
680                 tm->tm_mon + 1,
681                 tm->tm_mday,
682                 tm->tm_hour,
683                 tm->tm_min,
684                 tm->tm_sec);
685         TIFFSetField(tiff_file, TIFFTAG_DATETIME, buf);
686 
687         TIFFSetField(tiff_file, TIFFTAG_ROWSPERSTRIP, sequence[i].length);
688         TIFFSetField(tiff_file, TIFFTAG_IMAGELENGTH, sequence[i].length);
689         TIFFSetField(tiff_file, TIFFTAG_PAGENUMBER, 0, 1);
690         TIFFSetField(tiff_file, TIFFTAG_CLEANFAXDATA, CLEANFAXDATA_CLEAN);
691         TIFFSetField(tiff_file, TIFFTAG_IMAGEWIDTH, sequence[i].width);
692         TIFFCheckpointDirectory(tiff_file);
693 
694         /* Write the image first.... */
695         /* Produce a pattern of diagonal bands */
696         for (row = 0;  row < sequence[i].length;  row++)
697         {
698             clear_row(image_buffer, sequence[i].width);
699             for (j = 0;  j < sequence[i].squashing_factor;  j++)
700             {
701                 k = row*sequence[i].squashing_factor + j;
702                 if (((k/sequence[i].width) & 1) == 0)
703                     set_pixel_range(image_buffer, 1, k%sequence[i].width, sequence[i].width - 1);
704                 else
705                     set_pixel_range(image_buffer, 1, 0, k%sequence[i].width);
706             }
707             if (TIFFWriteScanline(tiff_file, image_buffer, row, 0) < 0)
708             {
709                 printf("Write error at row %d.\n", row);
710                 exit(2);
711             }
712         }
713         /* ....then the directory entry, and libtiff is happy. */
714         TIFFWriteDirectory(tiff_file);
715         TIFFClose(tiff_file);
716     }
717     return 0;
718 }
719 /*- End of function --------------------------------------------------------*/
720 /*- End of file ------------------------------------------------------------*/
721