T.85 compression has now been added to the FAX engine in spandsp

This commit is contained in:
Steve Underwood committed 2012-07-15 13:37:39 +08:00
1 parent 232fe67722
commit 4bcdafec68
35 files changed
+4625 -2819

No files matched your search

+5 -2
View File
@@ -109,6 +109,7 @@ noinst_PROGRAMS = ademco_contactid_tests \
t38_decode \
t38_non_ecm_buffer_tests \
t4_tests \
t4_t6_tests \
t81_t82_arith_coding_tests \
t85_tests \
time_scale_tests \
@@ -125,8 +126,7 @@ noinst_PROGRAMS = ademco_contactid_tests \
v42bis_tests \
v8_tests \
vector_float_tests \
vector_int_tests \
tsb85_tests
vector_int_tests
noinst_HEADERS = echo_monitor.h \
fax_tester.h \
@@ -314,6 +314,9 @@ t38_non_ecm_buffer_tests_LDADD = $(LIBDIR) -lspandsp
t4_tests_SOURCES = t4_tests.c
t4_tests_LDADD = $(LIBDIR) -lspandsp
t4_t6_tests_SOURCES = t4_t6_tests.c
t4_t6_tests_LDADD = $(LIBDIR) -lspandsp
t81_t82_arith_coding_tests_SOURCES = t81_t82_arith_coding_tests.c
t81_t82_arith_coding_tests_LDADD = $(LIBDIR) -lspandsp
+1 -1
View File
@@ -89,7 +89,7 @@ int decode_test = FALSE;
int rx_bits = 0;
t30_state_t t30_dummy;
t4_state_t t4_rx_state;
t4_rx_state_t t4_rx_state;
int t4_up = FALSE;
hdlc_rx_state_t hdlcrx;
+27 -12
View File
@@ -508,19 +508,18 @@ then
fi
echo t4_tests completed OK
#rm -f t4_t6_tests_receive.tif
#./t4_t6_tests >$STDOUT_DEST 2>$STDERR_DEST
#RETVAL=$?
#if [ $RETVAL != 0 ]
#then
# echo t4_t6_tests failed!
# exit $RETVAL
#fi
#echo t4_t6_tests completed OK
echo t4_t6_tests not enabled
rm -f t4_t6_tests_receive.tif
./t4_t6_tests >$STDOUT_DEST 2>$STDERR_DEST
RETVAL=$?
if [ $RETVAL != 0 ]
then
echo t4_t6_tests failed!
exit $RETVAL
fi
echo t4_t6_tests completed OK
rm -f t81_t82_arith_coding_tests_receive.tif
./t4_tests >$STDOUT_DEST 2>$STDERR_DEST
./t81_t82_arith_coding_tests >$STDOUT_DEST 2>$STDERR_DEST
RETVAL=$?
if [ $RETVAL != 0 ]
then
@@ -578,6 +577,22 @@ echo tone_detect_tests not enabled
#echo tone_generate_tests completed OK
echo tone_generate_tests not enabled
./tsb85_tests.sh >/dev/null
RETVAL=$?
if [ $RETVAL != 0 ]
then
echo ./tsb85_tests.sh failed!
exit $RETVAL
fi
./tsb85_extra_tests.sh
RETVAL=$?
if [ $RETVAL != 0 ]
then
echo ./tsb85_extra_tests.sh failed!
exit $RETVAL
fi
echo tsb85_tests.sh completed OK
for OPTS in "-b 14400 -s -42 -n -66" "-b 12000 -s -42 -n -61" "-b 9600 -s -42 -n -59" "-b 7200 -s -42 -n -56"
do
./v17_tests ${OPTS} >$STDOUT_DEST 2>$STDERR_DEST
@@ -615,7 +630,7 @@ do
done
echo v27ter_tests completed OK
for OPTS in "-b 9600 -s -42 -n -62" "-b 7200 -s -42 -n -59" "-b 4800 -s -42 -n -55"
for OPTS in "-b 9600 -s -42 -n -62" "-b 7200 -s -42 -n -59" "-b 4800 -s -42 -n -54"
do
./v29_tests ${OPTS} >$STDOUT_DEST 2>$STDERR_DEST
RETVAL=$?
+439
View File
@@ -0,0 +1,439 @@
/*
* SpanDSP - a series of DSP components for telephony
*
* t4_t6_tests.c - ITU T.4 and T.6 FAX image compression and decompression tests
*
* Written by Steve Underwood <steveu@coppice.org>
*
* Copyright (C) 2003, 2009 Steve Underwood
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2, as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*! \file */
/*! \page t4_t6_tests_page T.4 and T.6 image compress and decompression tests
\section t4_t6_tests_page_sec_1 What does it do
These tests exercise the image compression and decompression methods defined
in ITU specifications T.4 and T.6.
*/
#if defined(HAVE_CONFIG_H)
#include "config.h"
#endif
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <memory.h>
//#if defined(WITH_SPANDSP_INTERNALS)
#define SPANDSP_EXPOSE_INTERNAL_STRUCTURES
//#endif
#include "spandsp.h"
#define XSIZE 1728
t4_t6_encode_state_t send_state;
t4_t6_decode_state_t receive_state;
/* The following are some test cases from T.4 */
#define FILL_70 " "
#define FILL_80 " "
#define FILL_100 " "
#define FILL_670 FILL_100 FILL_100 FILL_100 FILL_100 FILL_100 FILL_100 FILL_70
#define FILL_980 FILL_100 FILL_100 FILL_100 FILL_100 FILL_100 FILL_100 FILL_100 FILL_100 FILL_100 FILL_80
#define TEST_ROWS 16
static const char t4_t6_test_patterns[TEST_ROWS][XSIZE + 1] =
{
"XXXXXX " FILL_980 " XXX XXX X " FILL_670 " XXXX",
"XXXXXX " FILL_980 " XXX X " FILL_670 " XXXX",
/* 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). */
" XXXX " FILL_980 " XXXXXXX " FILL_670 " XX ",
"XXXXX " FILL_980 "XX XX " FILL_670 " XXXX",
/* Line start should code to VL(1). Line middle codes to H(7,2). Line end should code to V(0) VR(2) */
"XXX " FILL_980 " XX XX XX XXX " FILL_670 " X ",
" " FILL_980 " X XXX XXXX " FILL_670 " X XX",
/* 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). */
"XXXXX " FILL_980 " " FILL_670 " XXXX",
" XXX " FILL_980 " " FILL_670 " XX ",
/* Line start should code to VR(2). Line end codes to V(0) VL(2) V(0). */
" XX " FILL_980 " " FILL_670 " X XXX",
"XXX X " FILL_980 " " FILL_670 " X ",
/* Line start should code to H(0,3) VR(1). Line end codes to V(0) VR(3). */
" " FILL_980 " " FILL_670 " XX ",
" " FILL_980 " " FILL_670 " ",
/* Line end codes to P V(0) a'0. */
" " FILL_980 " " FILL_670 " XXXXXXXXXX",
" " FILL_980 " " FILL_670 " XXXXXX XXXXXX",
/* Line end codes to H(2,6). */
" " FILL_980 " " FILL_670 " XX XXXXX",
" " FILL_980 " " FILL_670 " XX ",
/* Line end codes to V(0) H(7,0). */
};
#if 0
static void dump_image_as_xxx(const uint8_t buf[], int bytes_per_row, int len)
{
const uint8_t *s;
int i;
int j;
int k;
/* Dump the entire image as text 'X's and spaces */
printf("Image (%d pixels x %d pixels):\n", bytes_per_row*8, len/bytes_per_row);
s = buf;
for (i = 0; i < len; i++)
{
for (j = 0; j < bytes_per_row; j++)
{
for (k = 0; k < 8; k++)
printf((buf[i*bytes_per_row + j] & (0x80 >> k)) ? "X" : " ");
}
printf("\n");
}
}
/*- End of function --------------------------------------------------------*/
#endif
static int row_read_handler(void *user_data, uint8_t buf[], size_t len)
{
int i;
int j;
const char *s;
static int row = 0;
/* Send the test pattern. */
if (row >= TEST_ROWS)
{
row = 0;
return 0;
}
s = t4_t6_test_patterns[row++];
memset(buf, 0, len);
for (i = 0; i < len; i++)
{
for (j = 0; j < 8; j++)
{
if (*s++ != ' ')
buf[i] |= (0x80 >> j);
}
}
if (*s)
printf("Oops - '%c' at end of row %d\n", *s, row);
return len;
}
/*- End of function --------------------------------------------------------*/
static int row_write_handler(void *user_data, const uint8_t buf[], size_t len)
{
int i;
int j;
const char *s;
static int row = 0;
uint8_t ref[8192];
/* Verify that what is received matches the test pattern. */
//printf("Row %d\n", row);
if (len == 0)
return 0;
s = t4_t6_test_patterns[row++];
if (row >= TEST_ROWS)
row = 0;
memset(ref, 0, len);
for (i = 0; i < len; i++)
{
for (j = 0; j < 8; j++)
{
if (*s++ != ' ')
ref[i] |= (0x80 >> j);
}
}
if (*s)
printf("Oops - '%c' at end of row %d\n", *s, row);
if (memcmp(buf, ref, len))
{
printf("Test failed at row %d\n", row);
exit(2);
}
return 0;
}
/*- End of function --------------------------------------------------------*/
static int detect_page_end(int bit, int page_ended)
{
static int consecutive_eols;
static int max_consecutive_eols;
static int consecutive_zeros;
static int consecutive_ones;
static int eol_zeros;
static int eol_ones;
static int expected_eols;
static int end_marks;
/* Check the EOLs are added properly to the end of an image. We can't rely on the
decoder giving the right answer, as a full set of EOLs is not needed for the
decoder to work. */
if (bit == -1000000)
{
/* Reset */
consecutive_eols = 0;
max_consecutive_eols = 0;
consecutive_zeros = 0;
consecutive_ones = 0;
end_marks = 0;
eol_zeros = 11;
eol_ones = (page_ended == T4_COMPRESSION_ITU_T4_2D) ? 2 : 1;
expected_eols = (page_ended == T4_COMPRESSION_ITU_T6) ? 2 : 6;
return 0;
}
/* Monitor whether the EOLs are there in the correct amount */
if (bit == 0)
{
consecutive_zeros++;
consecutive_ones = 0;
}
else if (bit == 1)
{
if (++consecutive_ones == eol_ones)
{
if (consecutive_eols == 0 && consecutive_zeros >= eol_zeros)
consecutive_eols++;
else if (consecutive_zeros == eol_zeros)
consecutive_eols++;
else
consecutive_eols = 0;
consecutive_zeros = 0;
consecutive_ones = 0;
}
if (max_consecutive_eols < consecutive_eols)
max_consecutive_eols = consecutive_eols;
}
else if (bit == SIG_STATUS_END_OF_DATA)
{
if (end_marks == 0)
{
if (max_consecutive_eols != expected_eols)
{
printf("Only %d EOLs (should be %d)\n", max_consecutive_eols, expected_eols);
return 2;
}
consecutive_zeros = 0;
consecutive_eols = 0;
max_consecutive_eols = 0;
}
if (!page_ended)
{
/* We might need to push a few bits to get the receiver to report the
end of page condition (at least with T.6). */
if (++end_marks > 50)
{
printf("Receiver missed the end of page mark\n");
return 2;
}
return 0;
}
return 1;
}
return 0;
}
/*- End of function --------------------------------------------------------*/
int main(int argc, char *argv[])
{
static const int compression_sequence[] =
{
T4_COMPRESSION_ITU_T4_1D,
T4_COMPRESSION_ITU_T4_2D,
T4_COMPRESSION_ITU_T6,
-1
};
int bit;
int end_of_page;
int end_marks;
int compression;
int compression_step;
int min_row_bits;
int opt;
int tests_failed;
int block_size;
int len;
int res;
uint8_t chunk_buf[1024];
tests_failed = 0;
compression = -1;
compression_step = 0;
/* Use a non-zero default minimum row length to ensure we test the consecutive EOLs part
properly. */
min_row_bits = 50;
block_size = 0;
while ((opt = getopt(argc, argv, "126b:m:")) != -1)
{
switch (opt)
{
case '1':
compression = T4_COMPRESSION_ITU_T4_1D;
compression_step = -1;
break;
case '2':
compression = T4_COMPRESSION_ITU_T4_2D;
compression_step = -1;
break;
case '6':
compression = T4_COMPRESSION_ITU_T6;
compression_step = -1;
break;
case 'b':
block_size = atoi(optarg);
if (block_size > 1024)
block_size = 1024;
break;
case 'm':
min_row_bits = atoi(optarg);
break;
default:
//usage();
exit(2);
break;
}
}
/* Create a send and a receive end */
memset(&send_state, 0, sizeof(send_state));
memset(&receive_state, 0, sizeof(receive_state));
end_of_page = FALSE;
#if 1
printf("Testing image_function->compress->decompress->image_function\n");
/* Send end gets image from a function */
if (t4_t6_encode_init(&send_state, compression, 1728, row_read_handler, NULL) == NULL)
{
printf("Failed to init T.4/T.6 encoder\n");
exit(2);
}
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);
t4_t6_encode_set_min_bits_per_row(&send_state, min_row_bits);
t4_t6_encode_set_max_2d_rows_per_1d_row(&send_state, 2);
/* Receive end puts TIFF to a function. */
if (t4_t6_decode_init(&receive_state, compression, 1728, row_write_handler, NULL) == NULL)
{
printf("Failed to init T.4/T.6 decoder\n");
exit(2);
}
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);
/* Now send and receive the test data with all compression modes. */
/* If we are stepping around the compression schemes, reset to the start of the sequence. */
if (compression_step > 0)
compression_step = 0;
for (;;)
{
end_marks = 0;
if (compression_step >= 0)
{
compression = compression_sequence[compression_step++];
if (compression < 0)
break;
}
t4_t6_encode_set_encoding(&send_state, compression);
t4_t6_decode_set_encoding(&receive_state, compression);
if (t4_t6_encode_restart(&send_state, 1728))
break;
if (t4_t6_decode_restart(&receive_state, 1728))
break;
detect_page_end(-1000000, compression);
switch (block_size)
{
case 0:
end_of_page = FALSE;
for (;;)
{
bit = t4_t6_encode_get_bit(&send_state);
if ((res = detect_page_end(bit, end_of_page)))
{
if (res != 1)
{
printf("Test failed\n");
exit(2);
}
break;
}
if (!end_of_page)
end_of_page = t4_t6_decode_put_bit(&receive_state, bit & 1);
}
break;
case 1:
do
{
bit = t4_t6_encode_get_byte(&send_state);
if ((bit & 0x100))
{
if (++end_marks > 50)
{
printf("Receiver missed the end of page mark\n");
tests_failed++;
break;
}
}
end_of_page = t4_t6_decode_put_byte(&receive_state, bit & 0xFF);
}
while (!end_of_page);
break;
default:
do
{
len = t4_t6_encode_get_chunk(&send_state, chunk_buf, block_size);
if (len == 0)
{
if (++end_marks > 50)
{
printf("Receiver missed the end of page mark\n");
tests_failed++;
break;
}
chunk_buf[0] = 0xFF;
len = 1;
}
end_of_page = t4_t6_decode_put_chunk(&receive_state, chunk_buf, len);
}
while (!end_of_page);
break;
}
if (compression_step < 0)
break;
}
t4_t6_encode_release(&send_state);
t4_t6_decode_release(&receive_state);
#endif
printf("Tests passed\n");
return 0;
}
/*- End of function --------------------------------------------------------*/
/*- End of file ------------------------------------------------------------*/
+22 -21
View File
@@ -52,8 +52,8 @@ in ITU specifications T.4 and T.6.
#define XSIZE 1728
t4_state_t send_state;
t4_state_t receive_state;
t4_tx_state_t send_state;
t4_rx_state_t receive_state;
/* The following are some test cases from T.4 */
#define FILL_70 " "
@@ -100,27 +100,31 @@ static const char t4_t6_test_patterns[][1728 + 1] =
int rows_written = 0;
int rows_read = 0;
static void dump_image_as_xxx(t4_state_t *state)
static void dump_image_as_xxx(t4_rx_state_t *state)
{
#if 0
uint8_t *s;
int i;
int j;
int k;
/* Dump the entire image as text 'X's and spaces */
printf("Image (%d x %d):\n", receive_state.image_width, receive_state.image_length);
for (i = 0; i < state->image_length; i++)
printf("Image (%d x %d):\n", state->t4_t6.image_width, state->t4_t6.image_length);
s = state->image_buffer;
for (i = 0; i < state->t4_t6.image_length; i++)
{
for (j = 0; j < state->bytes_per_row; j++)
for (j = 0; j < state->t4_t6.bytes_per_row; j++)
{
for (k = 0; k < 8; k++)
printf((state->image_buffer[i*state->bytes_per_row + j] & (0x80 >> k)) ? "X" : " ");
printf((state->image_buffer[i*state->t4_t6.bytes_per_row + j] & (0x80 >> k)) ? "X" : " ");
}
printf("\n");
}
#endif
}
/*- End of function --------------------------------------------------------*/
static void display_page_stats(t4_state_t *s)
static void display_page_stats(t4_rx_state_t *s)
{
t4_stats_t stats;
@@ -132,7 +136,7 @@ static void display_page_stats(t4_state_t *s)
printf("Image resolution = %d pels/m x %d pels/m\n", stats.x_resolution, stats.y_resolution);
printf("Bad rows = %d\n", stats.bad_rows);
printf("Longest bad row run = %d\n", stats.longest_bad_row_run);
printf("Bits per row - min %d, max %d\n", s->min_row_bits, s->max_row_bits);
printf("Bits per row - min %d, max %d\n", s->decoder.t4_t6.min_row_bits, s->decoder.t4_t6.max_row_bits);
}
/*- End of function --------------------------------------------------------*/
@@ -288,10 +292,8 @@ int main(int argc, char *argv[])
#if defined(SPANDSP_SUPPORT_T43x)
T4_COMPRESSION_ITU_T43,
#endif
#if defined(SPANDSP_SUPPORT_T85)
T4_COMPRESSION_ITU_T85,
T4_COMPRESSION_ITU_T85_L0,
#endif
//T4_COMPRESSION_ITU_T45,
-1
};
@@ -303,7 +305,7 @@ int main(int argc, char *argv[])
int compression;
int compression_step;
int add_page_headers;
//int overlay_page_headers;
int overlay_page_headers;
int min_row_bits;
int restart_pages;
int block_size;
@@ -327,7 +329,7 @@ int main(int argc, char *argv[])
compression = -1;
compression_step = 0;
add_page_headers = FALSE;
//overlay_page_headers = FALSE;
overlay_page_headers = FALSE;
restart_pages = FALSE;
in_file_name = IN_FILE_NAME;
decode_file_name = NULL;
@@ -377,13 +379,11 @@ int main(int argc, char *argv[])
compression_step = -1;
}
#endif
#if defined(SPANDSP_SUPPORT_T85)
else if (strcmp(optarg, "T85") == 0)
{
compression = T4_COMPRESSION_ITU_T85;
compression_step = -1;
}
#endif
break;
case 'd':
decode_file_name = optarg;
@@ -393,11 +393,11 @@ int main(int argc, char *argv[])
break;
case 'h':
add_page_headers = TRUE;
//overlay_page_headers = FALSE;
overlay_page_headers = FALSE;
break;
case 'H':
add_page_headers = TRUE;
//overlay_page_headers = TRUE;
overlay_page_headers = TRUE;
break;
case 'r':
restart_pages = TRUE;
@@ -542,18 +542,19 @@ int main(int argc, char *argv[])
#if 1
printf("Testing image_function->compress->decompress->image_function\n");
/* Send end gets image from a function */
if (t4_tx_init(&send_state, in_file_name, -1, -1) == NULL)
if (t4_tx_init(&send_state, FALSE, -1, -1) == NULL)
{
printf("Failed to init T.4 tx\n");
exit(2);
}
span_log_set_level(&send_state.logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_FLOW);
t4_tx_set_row_read_handler(&send_state, row_read_handler, NULL);
t4_tx_set_image_width(&send_state, 1728);
t4_tx_set_min_bits_per_row(&send_state, min_row_bits);
t4_tx_set_local_ident(&send_state, "111 2222 3333");
t4_tx_set_max_2d_rows_per_1d_row(&send_state, 2);
/* Receive end puts TIFF to a function. */
if (t4_rx_init(&receive_state, OUT_FILE_NAME, T4_COMPRESSION_ITU_T4_2D) == NULL)
if (t4_rx_init(&receive_state, NULL, T4_COMPRESSION_ITU_T4_2D) == NULL)
{
printf("Failed to init T.4 rx\n");
exit(2);
@@ -701,7 +702,7 @@ int main(int argc, char *argv[])
if (tz_init(&tz, page_header_tz))
t4_tx_set_header_tz(&send_state, &tz);
}
//t4_tx_set_header_overlays_image(&send_state, overlay_page_headers);
t4_tx_set_header_overlays_image(&send_state, overlay_page_headers);
if (restart_pages && (sends & 1))
{
/* Use restart, to send the page a second time */
+1 -1
View File
@@ -630,7 +630,7 @@ static int next_step(faxtester_state_t *s)
int compression_type;
int timer;
int len;
t4_state_t t4_tx_state;
t4_tx_state_t t4_tx_state;
t30_state_t *t30;
if (s->cur == NULL)
+2 -8
View File
@@ -104,18 +104,12 @@ do
run_tsb85_test
done
#OTEN02 fails because ?????
#for TEST in OTEN01 OTEN02 OTEN03 OTEN04 OTEN05 OTEN06
for TEST in OTEN01 OTEN03 OTEN04 OTEN05 OTEN06
for TEST in OTEN01 OTEN02 OTEN03 OTEN04 OTEN05 OTEN06
do
run_tsb85_test
done
#MTGX02 fails because ?????
#for TEST in MTGX01 MTGX02 MTGX03 MTGX04 MTGX05 MTGX06 MTGX07 MTGX08
for TEST in MTGX01 MTGX03 MTGX04 MTGX05 MTGX06 MTGX07 MTGX08
for TEST in MTGX01 MTGX02 MTGX03 MTGX04 MTGX05 MTGX06 MTGX07 MTGX08
do
run_tsb85_test
done