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 ------------------------------------------------------------*/ |
