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