Mercurial > hg > audiostuff
comparison spandsp-0.0.6pre17/tests/t4_tests.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 * t4_tests.c - ITU T.4 FAX image to and from TIFF file tests | |
5 * | |
6 * Written by Steve Underwood <steveu@coppice.org> | |
7 * | |
8 * Copyright (C) 2003 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: t4_tests.c,v 1.69.4.1 2009/12/19 09:47:57 steveu Exp $ | |
26 */ | |
27 | |
28 /*! \file */ | |
29 | |
30 /*! \page t4_tests_page T.4 tests | |
31 \section t4_tests_page_sec_1 What does it do | |
32 These tests exercise the image compression and decompression methods defined | |
33 in ITU specifications T.4 and T.6. | |
34 */ | |
35 | |
36 #if defined(HAVE_CONFIG_H) | |
37 #include "config.h" | |
38 #endif | |
39 | |
40 #include <stdlib.h> | |
41 #include <stdio.h> | |
42 #include <fcntl.h> | |
43 #include <unistd.h> | |
44 #include <memory.h> | |
45 | |
46 //#if defined(WITH_SPANDSP_INTERNALS) | |
47 #define SPANDSP_EXPOSE_INTERNAL_STRUCTURES | |
48 //#endif | |
49 | |
50 #include "spandsp.h" | |
51 | |
52 #define IN_FILE_NAME "../test-data/itu/fax/itutests.tif" | |
53 #define OUT_FILE_NAME "t4_tests_receive.tif" | |
54 | |
55 #define XSIZE 1728 | |
56 | |
57 t4_state_t send_state; | |
58 t4_state_t receive_state; | |
59 | |
60 /* The following are some test cases from T.4 */ | |
61 #define FILL_70 " " | |
62 #define FILL_80 " " | |
63 #define FILL_100 " " | |
64 #define FILL_670 FILL_100 FILL_100 FILL_100 FILL_100 FILL_100 FILL_100 FILL_70 | |
65 #define FILL_980 FILL_100 FILL_100 FILL_100 FILL_100 FILL_100 FILL_100 FILL_100 FILL_100 FILL_100 FILL_80 | |
66 | |
67 static const char t4_test_patterns[][1728 + 1] = | |
68 { | |
69 "XXXXXX " FILL_980 " XXX XXX X " FILL_670 " XXXX", | |
70 "XXXXXX " FILL_980 " XXX X " FILL_670 " XXXX", | |
71 /* Line start should code to V(0). Line middle codes to VR(3) VL(2) V(0). Line end should code to V(0) V(0). */ | |
72 | |
73 " XXXX " FILL_980 " XXXXXXX " FILL_670 " XX ", | |
74 "XXXXX " FILL_980 "XX XX " FILL_670 " XXXX", | |
75 /* Line start should code to VL(1). Line middle codes to H(7,2). Line end should code to V(0) VR(2) */ | |
76 | |
77 "XXX " FILL_980 " XX XX XX XXX " FILL_670 " X ", | |
78 " " FILL_980 " X XXX XXXX " FILL_670 " X XX", | |
79 /* Line start should code to P. Line middle codes to P VL(1) V(0) H(3,4) P. Line end codes to V(0) VL(2) V(0). */ | |
80 | |
81 "XXXXX " FILL_980 " " FILL_670 " XXXX", | |
82 " XXX " FILL_980 " " FILL_670 " XX ", | |
83 /* Line start should code to VR(2). Line end codes to V(0) VL(2) V(0). */ | |
84 | |
85 " XX " FILL_980 " " FILL_670 " X XXX", | |
86 "XXX X " FILL_980 " " FILL_670 " X ", | |
87 /* Line start should code to H(0,3) VR(1). Line end codes to V(0) VR(3). */ | |
88 | |
89 " " FILL_980 " " FILL_670 " XX ", | |
90 " " FILL_980 " " FILL_670 " ", | |
91 /* Line end codes to P V(0) a'0. */ | |
92 | |
93 " " FILL_980 " " FILL_670 " XXXXXXXXXX", | |
94 " " FILL_980 " " FILL_670 " XXXXXX XXXXXX", | |
95 /* Line end codes to H(2,6). */ | |
96 | |
97 " " FILL_980 " " FILL_670 " XX XXXXX", | |
98 " " FILL_980 " " FILL_670 " XX ", | |
99 /* Line end codes to V(0) H(7,0). */ | |
100 }; | |
101 | |
102 static void dump_image_as_xxx(t4_state_t *state) | |
103 { | |
104 uint8_t *s; | |
105 int i; | |
106 int j; | |
107 int k; | |
108 | |
109 /* Dump the entire image as text 'X's and spaces */ | |
110 printf("Image (%d x %d):\n", receive_state.image_width, receive_state.image_length); | |
111 s = state->image_buffer; | |
112 for (i = 0; i < state->image_length; i++) | |
113 { | |
114 for (j = 0; j < state->bytes_per_row; j++) | |
115 { | |
116 for (k = 0; k < 8; k++) | |
117 { | |
118 printf((state->image_buffer[i*state->bytes_per_row + j] & (0x80 >> k)) ? "X" : " "); | |
119 } | |
120 } | |
121 printf("\n"); | |
122 } | |
123 } | |
124 /*- End of function --------------------------------------------------------*/ | |
125 | |
126 static void display_page_stats(t4_state_t *s) | |
127 { | |
128 t4_stats_t stats; | |
129 | |
130 t4_get_transfer_statistics(s, &stats); | |
131 printf("Pages = %d\n", stats.pages_transferred); | |
132 printf("Image size = %d pels x %d pels\n", stats.width, stats.length); | |
133 printf("Image resolution = %d pels/m x %d pels/m\n", stats.x_resolution, stats.y_resolution); | |
134 printf("Bad rows = %d\n", stats.bad_rows); | |
135 printf("Longest bad row run = %d\n", stats.longest_bad_row_run); | |
136 printf("Bits per row - min %d, max %d\n", s->min_row_bits, s->max_row_bits); | |
137 } | |
138 /*- End of function --------------------------------------------------------*/ | |
139 | |
140 static int row_read_handler(void *user_data, uint8_t buf[], size_t len) | |
141 { | |
142 int i; | |
143 int j; | |
144 const char *s; | |
145 static int row = 0; | |
146 | |
147 /* Send the test pattern. */ | |
148 s = t4_test_patterns[row++]; | |
149 if (row >= 16) | |
150 return 0; | |
151 memset(buf, 0, len); | |
152 for (i = 0; i < len; i++) | |
153 { | |
154 for (j = 0; j < 8; j++) | |
155 { | |
156 if (*s++ != ' ') | |
157 buf[i] |= (0x80 >> j); | |
158 } | |
159 } | |
160 if (*s) | |
161 printf("Oops - '%c' at end of row %d\n", *s, row); | |
162 return len; | |
163 } | |
164 /*- End of function --------------------------------------------------------*/ | |
165 | |
166 static int row_write_handler(void *user_data, const uint8_t buf[], size_t len) | |
167 { | |
168 int i; | |
169 int j; | |
170 const char *s; | |
171 static int row = 0; | |
172 uint8_t ref[8192]; | |
173 | |
174 /* Verify that what is received matches the test pattern. */ | |
175 if (len == 0) | |
176 return 0; | |
177 s = t4_test_patterns[row++]; | |
178 if (row >= 16) | |
179 row = 0; | |
180 memset(ref, 0, len); | |
181 for (i = 0; i < len; i++) | |
182 { | |
183 for (j = 0; j < 8; j++) | |
184 { | |
185 if (*s++ != ' ') | |
186 ref[i] |= (0x80 >> j); | |
187 } | |
188 } | |
189 if (*s) | |
190 printf("Oops - '%c' at end of row %d\n", *s, row); | |
191 if (memcmp(buf, ref, len)) | |
192 { | |
193 printf("Test failed at row %d\n", row); | |
194 exit(2); | |
195 } | |
196 return len; | |
197 } | |
198 /*- End of function --------------------------------------------------------*/ | |
199 | |
200 static int detect_page_end(int bit, int page_ended) | |
201 { | |
202 static int consecutive_eols; | |
203 static int max_consecutive_eols; | |
204 static int consecutive_zeros; | |
205 static int consecutive_ones; | |
206 static int eol_zeros; | |
207 static int eol_ones; | |
208 static int expected_eols; | |
209 static int end_marks; | |
210 | |
211 /* Check the EOLs are added properly to the end of an image. We can't rely on the | |
212 decoder giving the right answer, as a full set of EOLs is not needed for the | |
213 decoder to work. */ | |
214 if (bit == -1000000) | |
215 { | |
216 /* Reset */ | |
217 consecutive_eols = 0; | |
218 max_consecutive_eols = 0; | |
219 consecutive_zeros = 0; | |
220 consecutive_ones = 0; | |
221 end_marks = 0; | |
222 | |
223 eol_zeros = 11; | |
224 eol_ones = (page_ended == T4_COMPRESSION_ITU_T4_2D) ? 2 : 1; | |
225 expected_eols = (page_ended == T4_COMPRESSION_ITU_T6) ? 2 : 6; | |
226 return FALSE; | |
227 } | |
228 | |
229 /* Monitor whether the EOLs are there in the correct amount */ | |
230 if (bit == 0) | |
231 { | |
232 consecutive_zeros++; | |
233 consecutive_ones = 0; | |
234 } | |
235 else if (bit == 1) | |
236 { | |
237 if (++consecutive_ones == eol_ones) | |
238 { | |
239 if (consecutive_eols == 0 && consecutive_zeros >= eol_zeros) | |
240 consecutive_eols++; | |
241 else if (consecutive_zeros == eol_zeros) | |
242 consecutive_eols++; | |
243 else | |
244 consecutive_eols = 0; | |
245 consecutive_zeros = 0; | |
246 consecutive_ones = 0; | |
247 } | |
248 if (max_consecutive_eols < consecutive_eols) | |
249 max_consecutive_eols = consecutive_eols; | |
250 } | |
251 else if (bit == SIG_STATUS_END_OF_DATA) | |
252 { | |
253 if (end_marks == 0) | |
254 { | |
255 if (max_consecutive_eols != expected_eols) | |
256 { | |
257 printf("Only %d EOLs (should be %d)\n", max_consecutive_eols, expected_eols); | |
258 return 2; | |
259 } | |
260 consecutive_zeros = 0; | |
261 consecutive_eols = 0; | |
262 max_consecutive_eols = 0; | |
263 } | |
264 if (!page_ended) | |
265 { | |
266 /* We might need to push a few bits to get the receiver to report the | |
267 end of page condition (at least with T.6). */ | |
268 if (++end_marks > 50) | |
269 { | |
270 printf("Receiver missed the end of page mark\n"); | |
271 return 2; | |
272 } | |
273 return 0; | |
274 } | |
275 return 1; | |
276 } | |
277 return 0; | |
278 } | |
279 /*- End of function --------------------------------------------------------*/ | |
280 | |
281 int main(int argc, char *argv[]) | |
282 { | |
283 static const int compression_sequence[] = | |
284 { | |
285 //T4_COMPRESSION_NONE, | |
286 T4_COMPRESSION_ITU_T4_1D, | |
287 T4_COMPRESSION_ITU_T4_2D, | |
288 T4_COMPRESSION_ITU_T6, | |
289 //T4_COMPRESSION_ITU_T85, | |
290 //T4_COMPRESSION_ITU_T43, | |
291 //T4_COMPRESSION_ITU_T45, | |
292 //T4_COMPRESSION_ITU_T81, | |
293 //T4_COMPRESSION_ITU_SYCC_T81 | |
294 }; | |
295 int sends; | |
296 int page_no; | |
297 int bit; | |
298 int end_of_page; | |
299 int end_marks; | |
300 int res; | |
301 int compression; | |
302 int compression_step; | |
303 int add_page_headers; | |
304 int min_row_bits; | |
305 int restart_pages; | |
306 int block_size; | |
307 char buf[1024]; | |
308 uint8_t block[1024]; | |
309 const char *in_file_name; | |
310 const char *decode_file_name; | |
311 int opt; | |
312 int i; | |
313 int bit_error_rate; | |
314 int dump_as_xxx; | |
315 int tests_failed; | |
316 unsigned int last_pkt_no; | |
317 unsigned int pkt_no; | |
318 int page_ended; | |
319 FILE *file; | |
320 | |
321 tests_failed = 0; | |
322 compression = -1; | |
323 compression_step = 0; | |
324 add_page_headers = FALSE; | |
325 restart_pages = FALSE; | |
326 in_file_name = IN_FILE_NAME; | |
327 decode_file_name = NULL; | |
328 /* Use a non-zero default minimum row length to ensure we test the consecutive EOLs part | |
329 properly. */ | |
330 min_row_bits = 50; | |
331 block_size = 0; | |
332 bit_error_rate = 0; | |
333 dump_as_xxx = FALSE; | |
334 while ((opt = getopt(argc, argv, "126b:d:ehri:m:x")) != -1) | |
335 { | |
336 switch (opt) | |
337 { | |
338 case '1': | |
339 compression = T4_COMPRESSION_ITU_T4_1D; | |
340 compression_step = -1; | |
341 break; | |
342 case '2': | |
343 compression = T4_COMPRESSION_ITU_T4_2D; | |
344 compression_step = -1; | |
345 break; | |
346 case '6': | |
347 compression = T4_COMPRESSION_ITU_T6; | |
348 compression_step = -1; | |
349 break; | |
350 case 'b': | |
351 block_size = atoi(optarg); | |
352 if (block_size > 1024) | |
353 block_size = 1024; | |
354 break; | |
355 case 'd': | |
356 decode_file_name = optarg; | |
357 break; | |
358 case 'e': | |
359 bit_error_rate = 0x3FF; | |
360 break; | |
361 case 'h': | |
362 add_page_headers = TRUE; | |
363 break; | |
364 case 'r': | |
365 restart_pages = TRUE; | |
366 break; | |
367 case 'i': | |
368 in_file_name = optarg; | |
369 break; | |
370 case 'm': | |
371 min_row_bits = atoi(optarg); | |
372 break; | |
373 case 'x': | |
374 dump_as_xxx = TRUE; | |
375 break; | |
376 default: | |
377 //usage(); | |
378 exit(2); | |
379 break; | |
380 } | |
381 } | |
382 /* Create a send and a receive end */ | |
383 memset(&send_state, 0, sizeof(send_state)); | |
384 memset(&receive_state, 0, sizeof(receive_state)); | |
385 | |
386 end_of_page = FALSE; | |
387 if (decode_file_name) | |
388 { | |
389 if (compression < 0) | |
390 compression = T4_COMPRESSION_ITU_T4_1D; | |
391 /* Receive end puts TIFF to a new file. We assume the receive width here. */ | |
392 if (t4_rx_init(&receive_state, OUT_FILE_NAME, T4_COMPRESSION_ITU_T4_2D) == NULL) | |
393 { | |
394 printf("Failed to init T.4 rx\n"); | |
395 exit(2); | |
396 } | |
397 span_log_set_level(&receive_state.logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME | SPAN_LOG_FLOW); | |
398 t4_rx_set_rx_encoding(&receive_state, compression); | |
399 t4_rx_set_x_resolution(&receive_state, T4_X_RESOLUTION_R8); | |
400 //t4_rx_set_y_resolution(&receive_state, T4_Y_RESOLUTION_FINE); | |
401 t4_rx_set_y_resolution(&receive_state, T4_Y_RESOLUTION_STANDARD); | |
402 t4_rx_set_image_width(&receive_state, XSIZE); | |
403 | |
404 page_no = 1; | |
405 t4_rx_start_page(&receive_state); | |
406 last_pkt_no = 0; | |
407 file = fopen(decode_file_name, "r"); | |
408 while (fgets(buf, 1024, file)) | |
409 { | |
410 if (sscanf(buf, "HDLC: FCD: 06 %x", &pkt_no) == 1) | |
411 { | |
412 /* Useful for breaking up T.38 ECM logs */ | |
413 for (i = 0; i < 256; i++) | |
414 { | |
415 if (sscanf(&buf[18 + 3*i], "%x", (unsigned int *) &bit) != 1) | |
416 break; | |
417 if ((end_of_page = t4_rx_put_byte(&receive_state, bit))) | |
418 break; | |
419 } | |
420 } | |
421 else if (sscanf(buf, "HDLC: %x", &pkt_no) == 1) | |
422 { | |
423 /* Useful for breaking up HDLC decodes of ECM logs */ | |
424 for (i = 0; i < 256; i++) | |
425 { | |
426 if (sscanf(&buf[19 + 3*i], "%x", (unsigned int *) &bit) != 1) | |
427 break; | |
428 if ((end_of_page = t4_rx_put_byte(&receive_state, bit))) | |
429 break; | |
430 } | |
431 } | |
432 else if (strlen(buf) > 62 && sscanf(buf + 57, "Rx %d: IFP %x %x", &pkt_no, (unsigned int *) &bit, (unsigned int *) &bit) == 3) | |
433 { | |
434 /* Useful for breaking up T.38 non-ECM logs */ | |
435 if (pkt_no != last_pkt_no + 1) | |
436 printf("Packet %u\n", pkt_no); | |
437 last_pkt_no = pkt_no; | |
438 for (i = 0; i < 256; i++) | |
439 { | |
440 if (sscanf(&buf[57 + 29 + 3*i], "%x", (unsigned int *) &bit) != 1) | |
441 break; | |
442 bit = bit_reverse8(bit); | |
443 if ((end_of_page = t4_rx_put_byte(&receive_state, bit))) | |
444 break; | |
445 } | |
446 } | |
447 else if (sscanf(buf, "%08x %02x %02x %02x", (unsigned int *) &bit, (unsigned int *) &bit, (unsigned int *) &bit, (unsigned int *) &bit) == 4) | |
448 { | |
449 for (i = 0; i < 16; i++) | |
450 { | |
451 if (sscanf(&buf[10 + 3*i], "%x", (unsigned int *) &bit) != 1) | |
452 break; | |
453 bit = bit_reverse8(bit); | |
454 if ((end_of_page = t4_rx_put_byte(&receive_state, bit))) | |
455 break; | |
456 } | |
457 } | |
458 else if (sscanf(buf, "Rx bit %*d - %d", &bit) == 1) | |
459 { | |
460 if ((end_of_page = t4_rx_put_bit(&receive_state, bit))) | |
461 { | |
462 printf("End of page detected\n"); | |
463 break; | |
464 } | |
465 } | |
466 } | |
467 fclose(file); | |
468 if (dump_as_xxx) | |
469 dump_image_as_xxx(&receive_state); | |
470 t4_rx_end_page(&receive_state); | |
471 display_page_stats(&receive_state); | |
472 t4_rx_release(&receive_state); | |
473 } | |
474 else | |
475 { | |
476 #if 1 | |
477 printf("Testing image_function->compress->decompress->image_function\n"); | |
478 /* Send end gets image from a function */ | |
479 if (t4_tx_init(&send_state, in_file_name, -1, -1) == NULL) | |
480 { | |
481 printf("Failed to init T.4 tx\n"); | |
482 exit(2); | |
483 } | |
484 span_log_set_level(&send_state.logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME | SPAN_LOG_FLOW); | |
485 t4_tx_set_row_read_handler(&send_state, row_read_handler, NULL); | |
486 t4_tx_set_min_row_bits(&send_state, min_row_bits); | |
487 t4_tx_set_local_ident(&send_state, "111 2222 3333"); | |
488 | |
489 /* Receive end puts TIFF to a function. */ | |
490 if (t4_rx_init(&receive_state, OUT_FILE_NAME, T4_COMPRESSION_ITU_T4_2D) == NULL) | |
491 { | |
492 printf("Failed to init T.4 rx\n"); | |
493 exit(2); | |
494 } | |
495 span_log_set_level(&receive_state.logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME | SPAN_LOG_FLOW); | |
496 t4_rx_set_row_write_handler(&receive_state, row_write_handler, NULL); | |
497 t4_rx_set_image_width(&receive_state, t4_tx_get_image_width(&send_state)); | |
498 t4_rx_set_x_resolution(&receive_state, t4_tx_get_x_resolution(&send_state)); | |
499 t4_rx_set_y_resolution(&receive_state, t4_tx_get_y_resolution(&send_state)); | |
500 | |
501 /* Now send and receive the test data with all compression modes. */ | |
502 page_no = 1; | |
503 /* If we are stepping around the compression schemes, reset to the start of the sequence. */ | |
504 if (compression_step > 0) | |
505 compression_step = 0; | |
506 for (;;) | |
507 { | |
508 end_marks = 0; | |
509 if (compression_step >= 0) | |
510 { | |
511 compression = compression_sequence[compression_step++]; | |
512 if (compression_step > 3) | |
513 break; | |
514 } | |
515 t4_tx_set_tx_encoding(&send_state, compression); | |
516 t4_rx_set_rx_encoding(&receive_state, compression); | |
517 | |
518 if (t4_tx_start_page(&send_state)) | |
519 break; | |
520 t4_rx_start_page(&receive_state); | |
521 do | |
522 { | |
523 bit = t4_tx_get_bit(&send_state); | |
524 if (bit == SIG_STATUS_END_OF_DATA) | |
525 { | |
526 if (++end_marks > 50) | |
527 { | |
528 printf("Receiver missed the end of page mark\n"); | |
529 tests_failed++; | |
530 break; | |
531 } | |
532 } | |
533 end_of_page = t4_rx_put_bit(&receive_state, bit & 1); | |
534 } | |
535 while (!end_of_page); | |
536 t4_tx_end_page(&send_state); | |
537 t4_rx_end_page(&receive_state); | |
538 if (compression_step < 0) | |
539 break; | |
540 } | |
541 t4_tx_release(&send_state); | |
542 t4_rx_release(&receive_state); | |
543 #endif | |
544 #if 1 | |
545 printf("Testing TIFF->compress->decompress->TIFF cycle\n"); | |
546 /* Send end gets TIFF from a file */ | |
547 if (t4_tx_init(&send_state, in_file_name, -1, -1) == NULL) | |
548 { | |
549 printf("Failed to init T.4 send\n"); | |
550 exit(2); | |
551 } | |
552 span_log_set_level(&send_state.logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME | SPAN_LOG_FLOW); | |
553 t4_tx_set_min_row_bits(&send_state, min_row_bits); | |
554 t4_tx_set_local_ident(&send_state, "111 2222 3333"); | |
555 | |
556 /* Receive end puts TIFF to a new file. */ | |
557 if (t4_rx_init(&receive_state, OUT_FILE_NAME, T4_COMPRESSION_ITU_T4_2D) == NULL) | |
558 { | |
559 printf("Failed to init T.4 rx for '%s'\n", OUT_FILE_NAME); | |
560 exit(2); | |
561 } | |
562 span_log_set_level(&receive_state.logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_SHOW_SAMPLE_TIME | SPAN_LOG_FLOW); | |
563 t4_rx_set_x_resolution(&receive_state, t4_tx_get_x_resolution(&send_state)); | |
564 t4_rx_set_y_resolution(&receive_state, t4_tx_get_y_resolution(&send_state)); | |
565 t4_rx_set_image_width(&receive_state, t4_tx_get_image_width(&send_state)); | |
566 | |
567 /* Now send and receive all the pages in the source TIFF file */ | |
568 page_no = 1; | |
569 sends = 0; | |
570 /* If we are stepping around the compression schemes, reset to the start of the sequence. */ | |
571 if (compression_step > 0) | |
572 compression_step = 0; | |
573 for (;;) | |
574 { | |
575 end_marks = 0; | |
576 /* Add a header line to alternate pages, if required */ | |
577 if (add_page_headers && (sends & 2)) | |
578 t4_tx_set_header_info(&send_state, "Header"); | |
579 else | |
580 t4_tx_set_header_info(&send_state, NULL); | |
581 if (restart_pages && (sends & 1)) | |
582 { | |
583 /* Use restart, to send the page a second time */ | |
584 if (t4_tx_restart_page(&send_state)) | |
585 break; | |
586 } | |
587 else | |
588 { | |
589 if (compression_step >= 0) | |
590 { | |
591 compression = compression_sequence[compression_step++]; | |
592 if (compression_step > 2) | |
593 compression_step = 0; | |
594 } | |
595 t4_tx_set_tx_encoding(&send_state, compression); | |
596 t4_rx_set_rx_encoding(&receive_state, compression); | |
597 | |
598 if (t4_tx_start_page(&send_state)) | |
599 break; | |
600 } | |
601 t4_rx_start_page(&receive_state); | |
602 detect_page_end(-1000000, compression); | |
603 page_ended = FALSE; | |
604 if (block_size == 0) | |
605 { | |
606 for (;;) | |
607 { | |
608 bit = t4_tx_get_bit(&send_state); | |
609 /* Monitor whether the EOLs are there in the correct amount */ | |
610 if ((res = detect_page_end(bit, page_ended))) | |
611 { | |
612 tests_failed += (res - 1); | |
613 break; | |
614 } | |
615 if (!page_ended) | |
616 { | |
617 if (bit_error_rate) | |
618 { | |
619 if ((rand() % bit_error_rate) == 0) | |
620 bit ^= 1; | |
621 } | |
622 if (t4_rx_put_bit(&receive_state, bit & 1)) | |
623 page_ended = TRUE; | |
624 } | |
625 } | |
626 /* Now throw junk at the receive context, to ensure stuff occuring | |
627 after the end of page condition has no bad effect. */ | |
628 for (i = 0; i < 1000; i++) | |
629 { | |
630 t4_rx_put_bit(&receive_state, (rand() >> 10) & 1); | |
631 } | |
632 } | |
633 else if (block_size == 1) | |
634 { | |
635 do | |
636 { | |
637 bit = t4_tx_get_byte(&send_state); | |
638 if ((bit & 0x100)) | |
639 { | |
640 if (++end_marks > 50) | |
641 { | |
642 printf("Receiver missed the end of page mark\n"); | |
643 tests_failed++; | |
644 break; | |
645 } | |
646 } | |
647 end_of_page = t4_rx_put_byte(&receive_state, bit & 0xFF); | |
648 } | |
649 while (!end_of_page); | |
650 } | |
651 else | |
652 { | |
653 do | |
654 { | |
655 bit = t4_tx_get_chunk(&send_state, block, block_size); | |
656 if (bit > 0) | |
657 end_of_page = t4_rx_put_chunk(&receive_state, block, bit); | |
658 if (bit < block_size) | |
659 { | |
660 if (++end_marks > 50) | |
661 { | |
662 printf("Receiver missed the end of page mark\n"); | |
663 tests_failed++; | |
664 break; | |
665 } | |
666 } | |
667 } | |
668 while (!end_of_page); | |
669 } | |
670 if (dump_as_xxx) | |
671 dump_image_as_xxx(&receive_state); | |
672 display_page_stats(&receive_state); | |
673 if (!restart_pages || (sends & 1)) | |
674 t4_tx_end_page(&send_state); | |
675 t4_rx_end_page(&receive_state); | |
676 sends++; | |
677 } | |
678 t4_tx_release(&send_state); | |
679 t4_rx_release(&receive_state); | |
680 /* And we should now have a matching received TIFF file. Note this will only match | |
681 at the image level. TIFF files allow a lot of ways to express the same thing, | |
682 so bit matching of the files is not the normal case. */ | |
683 fflush(stdout); | |
684 sprintf(buf, "tiffcmp -t %s %s", in_file_name, OUT_FILE_NAME); | |
685 if (tests_failed || system(buf)) | |
686 { | |
687 printf("Tests failed\n"); | |
688 exit(2); | |
689 } | |
690 #endif | |
691 printf("Tests passed\n"); | |
692 } | |
693 return 0; | |
694 } | |
695 /*- End of function --------------------------------------------------------*/ | |
696 /*- End of file ------------------------------------------------------------*/ |