comparison spandsp-0.0.6pre17/test-data/etsi/fax/generate_etsi_300_242_pages.c @ 4:26cd8f1ef0b1

import spandsp-0.0.6pre17
author Peter Meerwald <pmeerw@cosy.sbg.ac.at>
date Fri, 25 Jun 2010 15:50:58 +0200
parents
children
comparison
equal deleted inserted replaced
3:c6c5a16ce2f2 4:26cd8f1ef0b1
1 /*
2 * SpanDSP - a series of DSP components for telephony
3 *
4 * generate_etsi_300_242_pages.c - Create the test pages defined in ETSI ETS 300 242.
5 *
6 * Written by Steve Underwood <steveu@coppice.org>
7 *
8 * Copyright (C) 2006 Steve Underwood
9 *
10 * All rights reserved.
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2, as
14 * published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 * $Id: generate_etsi_300_242_pages.c,v 1.5 2009/03/23 14:34:13 steveu Exp $
26 */
27
28 /*! \file */
29
30 #if defined(HAVE_CONFIG_H)
31 #include "config.h"
32 #endif
33
34 #include <stdio.h>
35 #include <inttypes.h>
36 #include <limits.h>
37 #include <unistd.h>
38 #include <fcntl.h>
39 #include <stdlib.h>
40 #include <time.h>
41 #include <memory.h>
42 #include <string.h>
43 #if defined(HAVE_TGMATH_H)
44 #include <tgmath.h>
45 #endif
46 #if defined(HAVE_MATH_H)
47 #include <math.h>
48 #endif
49
50 #include "spandsp.h"
51
52 struct
53 {
54 const char *name;
55 int x_res;
56 int y_res;
57 int width;
58 int length;
59 int compression;
60 int type;
61 } sequence[] =
62 {
63 {
64 "etsi_300_242_a4_diago1.tif",
65 T4_X_RESOLUTION_R8,
66 T4_Y_RESOLUTION_STANDARD,
67 T4_WIDTH_R8_A4,
68 1100,
69 COMPRESSION_CCITT_T4,
70 0
71 },
72 {
73 "etsi_300_242_a4_diago2.tif",
74 T4_X_RESOLUTION_R8,
75 T4_Y_RESOLUTION_STANDARD,
76 T4_WIDTH_R8_A4,
77 1100,
78 COMPRESSION_CCITT_T4,
79 1
80 },
81 {
82 "etsi_300_242_a4_duration1.tif",
83 T4_X_RESOLUTION_R8,
84 T4_Y_RESOLUTION_STANDARD,
85 T4_WIDTH_R8_A4,
86 1100,
87 COMPRESSION_CCITT_T4,
88 2
89 },
90 {
91 "etsi_300_242_a4_duration2.tif",
92 T4_X_RESOLUTION_R8,
93 T4_Y_RESOLUTION_STANDARD,
94 T4_WIDTH_R8_A4,
95 1100,
96 COMPRESSION_CCITT_T4,
97 3
98 },
99 {
100 "etsi_300_242_a4_error.tif",
101 T4_X_RESOLUTION_R8,
102 T4_Y_RESOLUTION_STANDARD,
103 T4_WIDTH_R8_A4,
104 1100,
105 COMPRESSION_CCITT_T4,
106 4
107 },
108 {
109 "etsi_300_242_a4_impress.tif",
110 T4_X_RESOLUTION_R8,
111 T4_Y_RESOLUTION_STANDARD,
112 T4_WIDTH_R8_A4,
113 1100,
114 COMPRESSION_CCITT_T4,
115 5
116 },
117 {
118 "etsi_300_242_a4_stairstep.tif",
119 T4_X_RESOLUTION_R8,
120 T4_Y_RESOLUTION_STANDARD,
121 T4_WIDTH_R8_A4,
122 1100,
123 COMPRESSION_CCITT_T4,
124 6
125 },
126 {
127 "etsi_300_242_a4_white.tif",
128 T4_X_RESOLUTION_R8,
129 T4_Y_RESOLUTION_STANDARD,
130 T4_WIDTH_R8_A4,
131 1100,
132 COMPRESSION_CCITT_T4,
133 7
134 },
135 {
136 "etsi_300_242_a4_white_2p.tif",
137 T4_X_RESOLUTION_R8,
138 T4_Y_RESOLUTION_STANDARD,
139 T4_WIDTH_R8_A4,
140 1100,
141 COMPRESSION_CCITT_T4,
142 7
143 },
144 { /* Second page of the above file */
145 "",
146 T4_X_RESOLUTION_R8,
147 T4_Y_RESOLUTION_STANDARD,
148 T4_WIDTH_R8_A4,
149 1100,
150 COMPRESSION_CCITT_T4,
151 7
152 },
153 {
154 "etsi_300_242_a4_impress_white.tif",
155 T4_X_RESOLUTION_R8,
156 T4_Y_RESOLUTION_STANDARD,
157 T4_WIDTH_R8_A4,
158 1100,
159 COMPRESSION_CCITT_T4,
160 5
161 },
162 { /* Second page of the above file */
163 "",
164 T4_X_RESOLUTION_R8,
165 T4_Y_RESOLUTION_STANDARD,
166 T4_WIDTH_R8_A4,
167 1100,
168 COMPRESSION_CCITT_T4,
169 7
170 },
171 {
172 NULL,
173 0,
174 0,
175 0,
176 0
177 },
178 };
179
180 int photo_metric = PHOTOMETRIC_MINISWHITE;
181 int fill_order = FILLORDER_LSB2MSB;
182
183 static void clear_row(uint8_t buf[], int width)
184 {
185 memset(buf, 0, width/8 + 1);
186 }
187 /*- End of function --------------------------------------------------------*/
188
189 static void set_pixel(uint8_t buf[], int row, int pixel)
190 {
191 row--;
192 buf[row*1728/8 + pixel/8] |= (0x80 >> (pixel & 0x07));
193 }
194 /*- End of function --------------------------------------------------------*/
195
196 static void clear_pixel(uint8_t buf[], int row, int pixel)
197 {
198 row--;
199 buf[row*1728/8 + pixel/8] &= ~(0x80 >> (pixel & 0x07));
200 }
201 /*- End of function --------------------------------------------------------*/
202
203 static void set_pixel_range(uint8_t buf[], int row, int start, int end)
204 {
205 int i;
206
207 for (i = start; i <= end; i++)
208 set_pixel(buf, row, i);
209 }
210 /*- End of function --------------------------------------------------------*/
211
212 static void clear_pixel_range(uint8_t buf[], int row, int start, int end)
213 {
214 int i;
215
216 for (i = start; i <= end; i++)
217 clear_pixel(buf, row, i);
218 }
219 /*- End of function --------------------------------------------------------*/
220
221 static int create_white_page(TIFF *tiff_file)
222 {
223 uint8_t image_buffer[8192];
224 int row;
225
226 /* TSB-85 WHITE page. */
227 for (row = 0; row < 1100; row++)
228 {
229 clear_row(image_buffer, 1728);
230 if (TIFFWriteScanline(tiff_file, image_buffer, row, 0) < 0)
231 {
232 printf("Write error at row %d.\n", row);
233 exit(2);
234 }
235 }
236 return 1100;
237 }
238 /*- End of function --------------------------------------------------------*/
239
240 static int create_stairstep_page(TIFF *tiff_file)
241 {
242 uint8_t image_buffer[8192];
243 int row;
244 int start_pixel;
245 int i;
246
247 /* TSB-85 STAIRSTEP page. */
248 start_pixel = 0;
249 for (row = 0; row < 1728; row++)
250 {
251 clear_row(image_buffer, 1728);
252 set_pixel_range(image_buffer, 1, start_pixel, start_pixel + 63);
253 if (photo_metric != PHOTOMETRIC_MINISWHITE)
254 {
255 for (i = 0; i < 1728/8; i++)
256 image_buffer[i] = ~image_buffer[i];
257 }
258 #if 0
259 if (fill_order != FILLORDER_LSB2MSB)
260 bit_reverse(image_buffer, image_buffer, 1728/8);
261 #endif
262 if (TIFFWriteScanline(tiff_file, image_buffer, row, 0) < 0)
263 {
264 printf("Write error at row %d.\n", row);
265 exit(2);
266 }
267 start_pixel += 64;
268 if (start_pixel >= 1728)
269 start_pixel = 0;
270 }
271 return 1728;
272 }
273 /*- End of function --------------------------------------------------------*/
274
275 static int create_diago1_page(TIFF *tiff_file)
276 {
277 uint8_t image_buffer[1728/8];
278 int row;
279
280 /* ETSI ETS 300 242 B.5.1 One dimensional coding test chart - the DIAGO1 page. */
281 for (row = 0; row < 1001; row++)
282 {
283 clear_row(image_buffer, 1728);
284 set_pixel_range(image_buffer, 1, row, 1727);
285 if (TIFFWriteScanline(tiff_file, image_buffer, row, 0) < 0)
286 {
287 printf("Write error at row %d.\n", row);
288 exit(2);
289 }
290 }
291 clear_row(image_buffer, 1728);
292 set_pixel_range(image_buffer, 1, 0, 1727);
293 if (TIFFWriteScanline(tiff_file, image_buffer, row, 0) < 0)
294 {
295 printf("Write error at row %d.\n", row);
296 exit(2);
297 }
298 return 1002;
299 }
300 /*- End of function --------------------------------------------------------*/
301
302 static int create_diago2_page(TIFF *tiff_file)
303 {
304 uint8_t image_buffer[1728/8];
305 int row;
306
307 /* ETSI ETS 300 242 B.5.1 One dimensional coding test chart - the DIAGO2 page. */
308 for (row = 0; row < 1001; row++)
309 {
310 clear_row(image_buffer, 1728);
311 set_pixel_range(image_buffer, 1, row + 728, 1727);
312 if (TIFFWriteScanline(tiff_file, image_buffer, row, 0) < 0)
313 {
314 printf("Write error at row %d.\n", row);
315 exit(2);
316 }
317 }
318 clear_row(image_buffer, 1728);
319 set_pixel_range(image_buffer, 1, 0, 1727);
320 if (TIFFWriteScanline(tiff_file, image_buffer, row, 0) < 0)
321 {
322 printf("Write error at row %d.\n", row);
323 exit(2);
324 }
325 return 1002;
326 }
327 /*- End of function --------------------------------------------------------*/
328
329 static int create_impress_page(TIFF *tiff_file)
330 {
331 int j;
332 int row;
333 uint8_t *page;
334
335 /* ETSI ETS 300 242 B.5.2 Printing resolution - the IMPRESS page */
336 if ((page = malloc(1079*1728/8)) == NULL)
337 return 0;
338 memset(page, 0, 1079*1728/8);
339
340 set_pixel_range(page, 1, 0, 1727);
341 for (row = 2; row <= 78; row++)
342 {
343 set_pixel_range(page, row, 850, 850 + 27);
344 set_pixel_range(page, row, 850 + 27 + 745, 850 + 27 + 745 + 26);
345 }
346 for (row = 80; row <= 117; row++)
347 {
348 for (j = 0; j < 1728; j += 2)
349 set_pixel(page, row, j);
350 }
351 for (row = 118; row <= 155; row++)
352 {
353 for (j = 1; j < 1728; j += 2)
354 set_pixel(page, row, j);
355 }
356 for (row = 194; row <= 231; row += 2)
357 set_pixel_range(page, row, 0, 1727);
358 for (row = 270; row <= 276; row++)
359 set_pixel_range(page, row, 60, 60 + 1607);
360 for (j = 0; j < 1728; j += 27)
361 set_pixel(page, 315, j);
362 for (row = 354; row <= 480; row++)
363 set_pixel_range(page, row, 209, 768);
364 for (row = 358; row <= 476; row++)
365 clear_pixel_range(page, row, 488, 489);
366 clear_pixel_range(page, 417, 217, 760);
367
368 for (row = 354; row <= 357; row++)
369 set_pixel_range(page, row, 962, 1521);
370 for (row = 477; row <= 480; row++)
371 set_pixel_range(page, row, 962, 1521);
372 for (row = 358; row <= 476; row++)
373 set_pixel_range(page, row, 962, 969);
374 for (row = 358; row <= 476; row++)
375 set_pixel_range(page, row, 1514, 1521);
376 for (row = 358; row <= 476; row++)
377 set_pixel(page, row, 1241);
378 set_pixel_range(page, 417, 970, 1513);
379
380 for (row = 354; row <= 1079; row++)
381 set_pixel(page, row, 864);
382 for (row = 157; row <= 926; row++)
383 set_pixel_range(page, row, 884, 899);
384 for (row = 0; row < 1079; row++)
385 {
386 if (TIFFWriteScanline(tiff_file, page + row*1728/8, row, 0) < 0)
387 {
388 printf("Write error at row %d.\n", row);
389 exit(2);
390 }
391 }
392 free(page);
393 return 1079;
394 }
395 /*- End of function --------------------------------------------------------*/
396
397 static int create_duration1_page(TIFF *tiff_file)
398 {
399 uint8_t image_buffer[1728/8];
400 int row;
401 int i;
402
403 /* ETSI ETS 300 242 B.5.3 Acceptance of total coded scan line duration - the DURATION1 page */
404 row = 0;
405 clear_row(image_buffer, 1728);
406 set_pixel_range(image_buffer, 1, 0, 1727);
407 if (TIFFWriteScanline(tiff_file, image_buffer, row++, 0) < 0)
408 {
409 printf("Write error at row %d.\n", row);
410 exit(2);
411 }
412 for ( ; row < 117; row++)
413 {
414 clear_row(image_buffer, 1728);
415 if (TIFFWriteScanline(tiff_file, image_buffer, row, 0) < 0)
416 {
417 printf("Write error at row %d.\n", row);
418 exit(2);
419 }
420 }
421 clear_row(image_buffer, 1728);
422 set_pixel_range(image_buffer, 1, 0, 1727);
423 if (TIFFWriteScanline(tiff_file, image_buffer, row++, 0) < 0)
424 {
425 printf("Write error at row %d.\n", row);
426 exit(2);
427 }
428 clear_row(image_buffer, 1728);
429 for (i = 1; i < 1728; i += 2)
430 set_pixel(image_buffer, 1, i);
431 if (TIFFWriteScanline(tiff_file, image_buffer, row++, 0) < 0)
432 {
433 printf("Write error at row %d.\n", row);
434 exit(2);
435 }
436 clear_row(image_buffer, 1728);
437 set_pixel_range(image_buffer, 1, 0, 1727);
438 if (TIFFWriteScanline(tiff_file, image_buffer, row++, 0) < 0)
439 {
440 printf("Write error at row %d.\n", row);
441 exit(2);
442 }
443 for ( ; row < 236; row++)
444 {
445 clear_row(image_buffer, 1728);
446 if (TIFFWriteScanline(tiff_file, image_buffer, row, 0) < 0)
447 {
448 printf("Write error at row %d.\n", row);
449 exit(2);
450 }
451 }
452 clear_row(image_buffer, 1728);
453 set_pixel_range(image_buffer, 1, 0, 1727);
454 if (TIFFWriteScanline(tiff_file, image_buffer, row, 0) < 0)
455 {
456 printf("Write error at row %d.\n", row);
457 exit(2);
458 }
459 return 237;
460 }
461 /*- End of function --------------------------------------------------------*/
462
463 static int create_duration2_page(TIFF *tiff_file)
464 {
465 return create_duration1_page(tiff_file);
466 }
467 /*- End of function --------------------------------------------------------*/
468
469 static int create_error_page(TIFF *tiff_file)
470 {
471 uint8_t image_buffer[1728/8];
472 int row;
473 int start_pixel;
474 int i;
475
476 /* ETSI ETS 300 242 B.5.4 Copy quality criteria - the ERROR page. */
477 for (row = 0; row < 68; row++)
478 {
479 clear_row(image_buffer, 1728);
480 if (TIFFWriteScanline(tiff_file, image_buffer, row, 0) < 0)
481 {
482 printf("Write error at row %d.\n", row);
483 exit(2);
484 }
485 }
486
487 clear_row(image_buffer, 1728);
488 set_pixel_range(image_buffer, 1, 0, 1727);
489 if (TIFFWriteScanline(tiff_file, image_buffer, row++, 0) < 0)
490 {
491 printf("Write error at row %d.\n", row);
492 exit(2);
493 }
494
495 clear_row(image_buffer, 1728);
496 if (TIFFWriteScanline(tiff_file, image_buffer, row++, 0) < 0)
497 {
498 printf("Write error at row %d.\n", row);
499 exit(2);
500 }
501
502 for (i = 0; i < 10; i++)
503 {
504 for (start_pixel = 16; start_pixel <= 1616; start_pixel += 64)
505 {
506 clear_row(image_buffer, 1728);
507 set_pixel_range(image_buffer, 1, start_pixel, start_pixel + 63);
508 if (TIFFWriteScanline(tiff_file, image_buffer, row, 0) < 0)
509 {
510 printf("Write error at row %d.\n", row);
511 exit(2);
512 }
513 row++;
514 }
515 }
516
517 clear_row(image_buffer, 1728);
518 if (TIFFWriteScanline(tiff_file, image_buffer, row++, 0) < 0)
519 {
520 printf("Write error at row %d.\n", row);
521 exit(2);
522 }
523
524 clear_row(image_buffer, 1728);
525 set_pixel_range(image_buffer, 1, 0, 1727);
526 if (TIFFWriteScanline(tiff_file, image_buffer, row++, 0) < 0)
527 {
528 printf("Write error at row %d.\n", row);
529 exit(2);
530 }
531
532 for (row = 332; row < 400; row++)
533 {
534 clear_row(image_buffer, 1728);
535 if (TIFFWriteScanline(tiff_file, image_buffer, row, 0) < 0)
536 {
537 printf("Write error at row %d.\n", row);
538 exit(2);
539 }
540 }
541
542 return 400;
543 }
544 /*- End of function --------------------------------------------------------*/
545
546 int main(int argc, char *argv[])
547 {
548 int row;
549 TIFF *tiff_file;
550 struct tm *tm;
551 time_t now;
552 char buf[133];
553 float x_resolution;
554 float y_resolution;
555 int i;
556 int image_length;
557 int opt;
558 int compression;
559
560 compression = T4_COMPRESSION_ITU_T6;
561 photo_metric = PHOTOMETRIC_MINISWHITE;
562 fill_order = FILLORDER_LSB2MSB;
563 while ((opt = getopt(argc, argv, "126ir")) != -1)
564 {
565 switch (opt)
566 {
567 case '1':
568 compression = T4_COMPRESSION_ITU_T4_1D;
569 break;
570 case '2':
571 compression = T4_COMPRESSION_ITU_T4_2D;
572 break;
573 case '6':
574 compression = T4_COMPRESSION_ITU_T6;
575 break;
576 case 'i':
577 photo_metric = PHOTOMETRIC_MINISBLACK;
578 break;
579 case 'r':
580 fill_order = FILLORDER_MSB2LSB;
581 break;
582 default:
583 //usage();
584 exit(2);
585 break;
586 }
587 }
588
589 tiff_file = NULL;
590 for (i = 0; sequence[i].name; i++)
591 {
592 if (sequence[i].name[0])
593 {
594 if (tiff_file)
595 TIFFClose(tiff_file);
596 if ((tiff_file = TIFFOpen(sequence[i].name, "w")) == NULL)
597 exit(2);
598 }
599 /* Prepare the directory entry fully before writing the image, or libtiff complains */
600 TIFFSetField(tiff_file, TIFFTAG_COMPRESSION, sequence[i].compression);
601 if (sequence[i].compression == COMPRESSION_CCITT_T4)
602 {
603 TIFFSetField(tiff_file, TIFFTAG_T4OPTIONS, GROUP3OPT_FILLBITS); // | GROUP3OPT_2DENCODING);
604 TIFFSetField(tiff_file, TIFFTAG_FAXMODE, FAXMODE_CLASSF);
605 }
606 TIFFSetField(tiff_file, TIFFTAG_IMAGEWIDTH, sequence[i].width);
607 TIFFSetField(tiff_file, TIFFTAG_BITSPERSAMPLE, 1);
608 TIFFSetField(tiff_file, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
609 TIFFSetField(tiff_file, TIFFTAG_SAMPLESPERPIXEL, 1);
610 TIFFSetField(tiff_file, TIFFTAG_ROWSPERSTRIP, -1L);
611 TIFFSetField(tiff_file, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
612 TIFFSetField(tiff_file, TIFFTAG_PHOTOMETRIC, photo_metric);
613 TIFFSetField(tiff_file, TIFFTAG_FILLORDER, fill_order);
614 x_resolution = sequence[i].x_res/100.0f;
615 y_resolution = sequence[i].y_res/100.0f;
616 TIFFSetField(tiff_file, TIFFTAG_XRESOLUTION, floorf(x_resolution*2.54f + 0.5f));
617 TIFFSetField(tiff_file, TIFFTAG_YRESOLUTION, floorf(y_resolution*2.54f + 0.5f));
618 TIFFSetField(tiff_file, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH);
619
620 TIFFSetField(tiff_file, TIFFTAG_SOFTWARE, "spandsp");
621 if (gethostname(buf, sizeof(buf)) == 0)
622 TIFFSetField(tiff_file, TIFFTAG_HOSTCOMPUTER, buf);
623
624 TIFFSetField(tiff_file, TIFFTAG_IMAGEDESCRIPTION, "Blank test image");
625 TIFFSetField(tiff_file, TIFFTAG_MAKE, "soft-switch.org");
626 TIFFSetField(tiff_file, TIFFTAG_MODEL, "test data");
627
628 time(&now);
629 tm = localtime(&now);
630 sprintf(buf,
631 "%4d/%02d/%02d %02d:%02d:%02d",
632 tm->tm_year + 1900,
633 tm->tm_mon + 1,
634 tm->tm_mday,
635 tm->tm_hour,
636 tm->tm_min,
637 tm->tm_sec);
638 TIFFSetField(tiff_file, TIFFTAG_DATETIME, buf);
639 image_length = sequence[i].length;
640
641 /* Write the image first.... */
642 row = 0;
643 switch (sequence[i].type)
644 {
645 case 0:
646 /* The DIAGO1 page */
647 image_length = create_diago1_page(tiff_file);
648 break;
649 case 1:
650 /* The DIAGO2 page */
651 image_length = create_diago2_page(tiff_file);
652 break;
653 case 2:
654 /* The DURATION1 page */
655 image_length = create_duration1_page(tiff_file);
656 break;
657 case 3:
658 /* The DURATION2 page */
659 image_length = create_duration2_page(tiff_file);
660 break;
661 case 4:
662 /* The ERROR page */
663 image_length = create_error_page(tiff_file);
664 break;
665 case 5:
666 /* The IMPRESS page */
667 image_length = create_impress_page(tiff_file);
668 break;
669 case 6:
670 /* A stairstep of 64 pixel dashes */
671 image_length = create_stairstep_page(tiff_file);
672 break;
673 case 7:
674 /* A white A4 page */
675 image_length = create_white_page(tiff_file);
676 break;
677 }
678 /* ....then the directory entry, and libtiff is happy. */
679 TIFFSetField(tiff_file, TIFFTAG_IMAGELENGTH, image_length);
680 TIFFSetField(tiff_file, TIFFTAG_PAGENUMBER, 0, 1);
681 TIFFSetField(tiff_file, TIFFTAG_CLEANFAXDATA, CLEANFAXDATA_CLEAN);
682
683 TIFFWriteDirectory(tiff_file);
684 }
685 if (tiff_file)
686 TIFFClose(tiff_file);
687 return 0;
688 }
689 /*- End of function --------------------------------------------------------*/
690 /*- End of file ------------------------------------------------------------*/

Repositories maintained by Peter Meerwald, pmeerw@pmeerw.net.