Various tweaks to spandsp

This commit is contained in:
Steve Underwood 2013-07-19 15:40:22 +08:00
parent 2490868830
commit 6716623d1a
13 changed files with 238 additions and 369 deletions

View File

@ -21,15 +21,8 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* Based on a single channel G.722 codec which is:
*
***** Copyright (c) CMU 1993 *****
* Computer Science, Speech Group
* Chengxiang Lu and Alex Hauptmann
*/
/*! \file */
#if !defined(_SPANDSP_PRIVATE_G722_H_)

View File

@ -26,6 +26,8 @@
#if !defined(_SPANDSP_PRIVATE_T4_RX_H_)
#define _SPANDSP_PRIVATE_T4_RX_H_
typedef int (*t4_image_put_handler_t)(void *user_data, const uint8_t buf[], size_t len);
/*!
TIFF specific state information to go with T.4 compression or decompression handling.
*/
@ -125,6 +127,9 @@ struct t4_rx_state_s
t45_decode_state_t t45;
#endif
} decoder;
t4_image_put_handler_t image_put_handler;
int current_decoder;
uint8_t *pre_encoded_buf;

View File

@ -26,6 +26,8 @@
#if !defined(_SPANDSP_PRIVATE_T4_TX_H_)
#define _SPANDSP_PRIVATE_T4_TX_H_
typedef int (*t4_image_get_handler_t)(void *user_data, uint8_t buf[], size_t len);
/*!
TIFF specific state information to go with T.4 compression or decompression handling.
*/
@ -45,6 +47,17 @@ typedef struct
/*! \brief The TIFF fill order setting for the current page. */
uint16_t fill_order;
/*! \brief Width of the image in the file. */
uint32_t image_width;
/*! \brief Length of the image in the file. */
uint32_t image_length;
/*! \brief Column-to-column (X) resolution in pixels per metre of the image in the file. */
int x_resolution;
/*! \brief Row-to-row (Y) resolution in pixels per metre of the image in the file. */
int y_resolution;
/*! \brief Code for the combined X and Y resolution of the image in the file. */
int resolution_code;
/*! \brief The number of pages in the current image file. */
int pages_in_file;
@ -56,18 +69,6 @@ typedef struct
int image_buffer_size;
/*! \brief Row counter for playing out the rows of the image. */
int row;
/*! \brief Width of the image in the file. */
uint32_t image_width;
/*! \brief Length of the image in the file. */
uint32_t image_length;
/*! \brief Column-to-column (X) resolution in pixels per metre of the image in the file. */
int image_x_resolution;
/*! \brief Row-to-row (Y) resolution in pixels per metre of the image in the file. */
int image_y_resolution;
/*! \brief Code for the combined X and Y resolution of the image in the file. */
int resolution_code;
/*! \brief Row counter used when the image is resized or dithered flat. */
int raw_row;
} t4_tx_tiff_state_t;
@ -162,23 +163,25 @@ struct t4_tx_state_s
#endif
} encoder;
image_translate_state_t translator;
uint8_t *pack_buf;
int pack_ptr;
int pack_row;
int pack_bit_mask;
t4_image_get_handler_t image_get_handler;
int apply_lab;
lab_params_t lab_params;
uint8_t *colour_map;
int colour_map_entries;
image_translate_state_t translator;
uint8_t *pack_buf;
int pack_ptr;
int pack_row;
int pack_bit_mask;
uint8_t *pre_encoded_buf;
int pre_encoded_len;
int pre_encoded_ptr;
int pre_encoded_bit;
/* Supporting information, like resolutions, which the backend may want. */
/*! \brief Supporting information, like resolutions, which the backend may want. */
t4_tx_metadata_t metadata;
/*! \brief All TIFF file specific state information for the T.4 context. */

View File

@ -43,15 +43,15 @@ struct v18_state_s
} queue;
tone_gen_descriptor_t alert_tone_desc;
tone_gen_state_t alert_tone_gen;
fsk_tx_state_t fsktx;
dtmf_tx_state_t dtmftx;
async_tx_state_t asynctx;
fsk_tx_state_t fsk_tx;
dtmf_tx_state_t dtmf_tx;
async_tx_state_t async_tx;
int baudot_tx_shift;
int tx_signal_on;
uint8_t next_byte;
fsk_rx_state_t fskrx;
dtmf_rx_state_t dtmfrx;
fsk_rx_state_t fsk_rx;
dtmf_rx_state_t dtmf_rx;
int baudot_rx_shift;
int consecutive_ones;
uint8_t rx_msg[256 + 1];

View File

@ -434,7 +434,7 @@ static void disconnect(t30_state_t *s);
static void decode_20digit_msg(t30_state_t *s, char *msg, const uint8_t *pkt, int len);
static void decode_url_msg(t30_state_t *s, char *msg, const uint8_t *pkt, int len);
static int decode_nsf_nss_nsc(t30_state_t *s, uint8_t *msg[], const uint8_t *pkt, int len);
static int set_min_scan_time_code(t30_state_t *s);
static void set_min_scan_time(t30_state_t *s);
static int send_cfr_sequence(t30_state_t *s, int start);
static void timer_t2_start(t30_state_t *s);
static void timer_t2a_start(t30_state_t *s);
@ -1682,7 +1682,7 @@ static int build_dcs(t30_state_t *s)
||
((s->image_width == T4_WIDTH_1200_A4) && (s->x_resolution == T4_X_RESOLUTION_1200)))
{
span_log(&s->logging, SPAN_LOG_FLOW, "Image width is A4 at %ddpi x %ddpi\n", s->x_resolution, s->y_resolution);
span_log(&s->logging, SPAN_LOG_FLOW, "Image width is A4 at %ddpm x %ddpm\n", s->x_resolution, s->y_resolution);
/* No width related bits need to be set. */
}
else if (((s->image_width == T4_WIDTH_200_B4) && (s->x_resolution == T4_X_RESOLUTION_200 || s->x_resolution == T4_X_RESOLUTION_R8))
@ -1697,7 +1697,7 @@ static int build_dcs(t30_state_t *s)
{
if ((s->mutual_image_sizes & T4_SUPPORT_WIDTH_255MM))
{
span_log(&s->logging, SPAN_LOG_FLOW, "Image width is B4 at %ddpi x %ddpi\n", s->x_resolution, s->y_resolution);
span_log(&s->logging, SPAN_LOG_FLOW, "Image width is B4 at %ddpm x %ddpm\n", s->x_resolution, s->y_resolution);
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_255MM_WIDTH);
}
else
@ -1718,7 +1718,7 @@ static int build_dcs(t30_state_t *s)
{
if ((s->mutual_image_sizes & T4_SUPPORT_WIDTH_303MM))
{
span_log(&s->logging, SPAN_LOG_FLOW, "Image width is A3 at %ddpi x %ddpi\n", s->x_resolution, s->y_resolution);
span_log(&s->logging, SPAN_LOG_FLOW, "Image width is A3 at %ddpm x %ddpm\n", s->x_resolution, s->y_resolution);
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_303MM_WIDTH);
}
else
@ -2392,8 +2392,6 @@ static int analyze_rx_dcs(t30_state_t *s, const uint8_t *msg, int len)
static int step_fallback_entry(t30_state_t *s)
{
int min_row_bits;
while (fallback_sequence[++s->current_fallback].which)
{
if ((fallback_sequence[s->current_fallback].which & s->current_permitted_modems))
@ -2404,8 +2402,7 @@ static int step_fallback_entry(t30_state_t *s)
/* TODO: This only sets the minimum row time for future pages. It doesn't fix up the
current page, though it is benign - fallback will only result in an excessive
minimum. */
min_row_bits = set_min_scan_time_code(s);
t4_tx_set_min_bits_per_row(&s->t4.tx, min_row_bits);
set_min_scan_time(s);
/* We need to rebuild the DCS message we will send. */
build_dcs(s);
return s->current_fallback;
@ -2629,7 +2626,7 @@ static void disconnect(t30_state_t *s)
}
/*- End of function --------------------------------------------------------*/
static int set_min_scan_time_code(t30_state_t *s)
static void set_min_scan_time(t30_state_t *s)
{
/* Translation between the codes for the minimum scan times the other end needs,
and the codes for what we say will be used. We need 0 minimum. */
@ -2645,6 +2642,7 @@ static int set_min_scan_time_code(t30_state_t *s)
20, 5, 10, 0, 40, 0, 0, 0
};
int min_bits_field;
int min_row_bits;
/* Set the minimum scan time bits */
if (s->error_correcting_mode)
@ -2654,6 +2652,7 @@ static int set_min_scan_time_code(t30_state_t *s)
switch (s->y_resolution)
{
case T4_Y_RESOLUTION_SUPERFINE:
case T4_Y_RESOLUTION_400:
if (test_ctrl_bit(s->far_dis_dtc_frame, T30_DIS_BIT_200_400_CAPABLE))
{
s->min_scan_time_code = translate_min_scan_time[(test_ctrl_bit(s->far_dis_dtc_frame, T30_DIS_BIT_MIN_SCAN_TIME_HALVES)) ? 2 : 1][min_bits_field];
@ -2662,6 +2661,7 @@ static int set_min_scan_time_code(t30_state_t *s)
span_log(&s->logging, SPAN_LOG_FLOW, "Remote FAX does not support super-fine resolution. Squashing image.\n");
/* Fall through */
case T4_Y_RESOLUTION_FINE:
case T4_Y_RESOLUTION_200:
if (test_ctrl_bit(s->far_dis_dtc_frame, T30_DIS_BIT_200_200_CAPABLE))
{
s->min_scan_time_code = translate_min_scan_time[1][min_bits_field];
@ -2671,19 +2671,21 @@ static int set_min_scan_time_code(t30_state_t *s)
/* Fall through */
default:
case T4_Y_RESOLUTION_STANDARD:
case T4_Y_RESOLUTION_100:
s->min_scan_time_code = translate_min_scan_time[0][min_bits_field];
break;
}
if (!s->error_correcting_mode && (s->iaf & T30_IAF_MODE_NO_FILL_BITS))
return 0;
return fallback_sequence[s->current_fallback].bit_rate*min_scan_times[s->min_scan_time_code]/1000;
min_row_bits = 0;
else
min_row_bits = fallback_sequence[s->current_fallback].bit_rate*min_scan_times[s->min_scan_time_code]/1000;
span_log(&s->logging, SPAN_LOG_FLOW, "Minimum bits per row will be %d\n", min_row_bits);
t4_tx_set_min_bits_per_row(&s->t4.tx, min_row_bits);
}
/*- End of function --------------------------------------------------------*/
static int start_sending_document(t30_state_t *s)
{
int min_row_bits;
if (s->tx_file[0] == '\0')
{
/* There is nothing to send */
@ -2715,15 +2717,8 @@ static int start_sending_document(t30_state_t *s)
s->x_resolution = t4_tx_get_x_resolution(&s->t4.tx);
s->y_resolution = t4_tx_get_y_resolution(&s->t4.tx);
s->image_width = t4_tx_get_image_width(&s->t4.tx);
/* The minimum scan time to be used can't be evaluated until we know the Y resolution, and
must be evaluated before the minimum scan row bits can be evaluated. */
if ((min_row_bits = set_min_scan_time_code(s)) < 0)
{
terminate_operation_in_progress(s);
return -1;
}
span_log(&s->logging, SPAN_LOG_FLOW, "Minimum bits per row will be %d\n", min_row_bits);
t4_tx_set_min_bits_per_row(&s->t4.tx, min_row_bits);
/* The minimum scan time to be used can't be evaluated until we know the Y resolution. */
set_min_scan_time(s);
if (s->error_correcting_mode)
{

View File

@ -369,18 +369,18 @@ static int get_tiff_directory_info(t4_tx_state_t *s)
t->fill_order = FILLORDER_LSB2MSB;
if (res_unit == RESUNIT_INCH)
t->image_x_resolution = x_resolution*100.0f/CM_PER_INCH;
t->x_resolution = x_resolution*100.0f/CM_PER_INCH;
else
t->image_x_resolution = x_resolution*100.0f;
t->x_resolution = x_resolution*100.0f;
/* Treat everything we can't match as R8. Most FAXes are this resolution anyway. */
if ((best_x_entry = match_resolution(res_unit, x_resolution, x_res_table)) < 0)
best_x_entry = 3;
s->metadata.x_resolution = x_res_table[best_x_entry].code;
if (res_unit == RESUNIT_INCH)
t->image_y_resolution = y_resolution*100.0f/CM_PER_INCH;
t->y_resolution = y_resolution*100.0f/CM_PER_INCH;
else
t->image_y_resolution = y_resolution*100.0f;
t->y_resolution = y_resolution*100.0f;
if ((best_y_entry = match_resolution(res_unit, y_resolution, y_res_table)) < 0)
best_y_entry = 0;
s->metadata.y_resolution = y_res_table[best_y_entry].code;
@ -1354,8 +1354,8 @@ SPAN_DECLARE(void) t4_tx_get_transfer_statistics(t4_tx_state_t *s, t4_stats_t *t
t->image_type = s->tiff.image_type;
t->image_width = s->tiff.image_width;
t->image_length = s->tiff.image_length;
t->image_x_resolution = s->tiff.image_x_resolution;
t->image_y_resolution = s->tiff.image_y_resolution;
t->image_x_resolution = s->tiff.x_resolution;
t->image_y_resolution = s->tiff.y_resolution;
t->x_resolution = s->metadata.x_resolution;
t->y_resolution = s->metadata.y_resolution/s->row_squashing_ratio;

View File

@ -665,7 +665,7 @@ static void v18_dtmf_get(void *user_data)
if ((ch = queue_read_byte(&s->queue.queue)) >= 0)
{
v = ascii_to_dtmf[ch & 0x7F];
dtmf_tx_put(&s->dtmftx, v, strlen(v));
dtmf_tx_put(&s->dtmf_tx, v, strlen(v));
s->rx_suppression = ((300 + 100*strlen(v))*SAMPLE_RATE)/1000;
}
}
@ -809,12 +809,12 @@ SPAN_DECLARE_NONSTD(int) v18_tx(v18_state_t *s, int16_t *amp, int max_len)
{
case V18_MODE_DTMF:
if (len < max_len)
len += dtmf_tx(&s->dtmftx, amp, max_len - len);
len += dtmf_tx(&s->dtmf_tx, amp, max_len - len);
break;
default:
if (len < max_len)
{
if ((lenx = fsk_tx(&s->fsktx, amp + len, max_len - len)) <= 0)
if ((lenx = fsk_tx(&s->fsk_tx, amp + len, max_len - len)) <= 0)
s->tx_signal_on = FALSE;
len += lenx;
}
@ -841,10 +841,10 @@ SPAN_DECLARE_NONSTD(int) v18_rx(v18_state_t *s, const int16_t amp[], int len)
s->in_progress -= len;
if (s->in_progress <= 0)
s->rx_msg_len = 0;
dtmf_rx(&s->dtmfrx, amp, len);
dtmf_rx(&s->dtmf_rx, amp, len);
break;
default:
fsk_rx(&s->fskrx, amp, len);
fsk_rx(&s->fsk_rx, amp, len);
break;
}
return 0;
@ -867,10 +867,10 @@ SPAN_DECLARE_NONSTD(int) v18_rx_fillin(v18_state_t *s, int len)
//s->in_progress -= len;
//if (s->in_progress <= 0)
// s->rx_msg_len = 0;
dtmf_rx_fillin(&s->dtmfrx, len);
dtmf_rx_fillin(&s->dtmf_rx, len);
break;
default:
fsk_rx_fillin(&s->fskrx, len);
fsk_rx_fillin(&s->fsk_rx, len);
break;
}
return 0;
@ -973,56 +973,56 @@ SPAN_DECLARE(v18_state_t *) v18_init(v18_state_t *s,
{
case V18_MODE_5BIT_45:
s->repeat_shifts = mode & 0x100;
fsk_tx_init(&s->fsktx, &preset_fsk_specs[FSK_WEITBRECHT], async_tx_get_bit, &s->asynctx);
async_tx_init(&s->asynctx, 5, ASYNC_PARITY_NONE, 2, FALSE, v18_tdd_get_async_byte, s);
fsk_tx_init(&s->fsk_tx, &preset_fsk_specs[FSK_WEITBRECHT], async_tx_get_bit, &s->async_tx);
async_tx_init(&s->async_tx, 5, ASYNC_PARITY_NONE, 2, FALSE, v18_tdd_get_async_byte, s);
/* Schedule an explicit shift at the start of baudot transmission */
s->baudot_tx_shift = 2;
/* TDD uses 5 bit data, no parity and 1.5 stop bits. We scan for the first stop bit, and
ride over the fraction. */
fsk_rx_init(&s->fskrx, &preset_fsk_specs[FSK_WEITBRECHT], FSK_FRAME_MODE_5N1_FRAMES, v18_tdd_put_async_byte, s);
fsk_rx_init(&s->fsk_rx, &preset_fsk_specs[FSK_WEITBRECHT], FSK_FRAME_MODE_5N1_FRAMES, v18_tdd_put_async_byte, s);
s->baudot_rx_shift = 0;
s->next_byte = (uint8_t) 0xFF;
break;
case V18_MODE_5BIT_50:
s->repeat_shifts = mode & 0x100;
fsk_tx_init(&s->fsktx, &preset_fsk_specs[FSK_WEITBRECHT50], async_tx_get_bit, &s->asynctx);
async_tx_init(&s->asynctx, 5, ASYNC_PARITY_NONE, 2, FALSE, v18_tdd_get_async_byte, s);
fsk_tx_init(&s->fsk_tx, &preset_fsk_specs[FSK_WEITBRECHT50], async_tx_get_bit, &s->async_tx);
async_tx_init(&s->async_tx, 5, ASYNC_PARITY_NONE, 2, FALSE, v18_tdd_get_async_byte, s);
/* Schedule an explicit shift at the start of baudot transmission */
s->baudot_tx_shift = 2;
/* TDD uses 5 bit data, no parity and 1.5 stop bits. We scan for the first stop bit, and
ride over the fraction. */
fsk_rx_init(&s->fskrx, &preset_fsk_specs[FSK_WEITBRECHT50], FSK_FRAME_MODE_5N1_FRAMES, v18_tdd_put_async_byte, s);
fsk_rx_init(&s->fsk_rx, &preset_fsk_specs[FSK_WEITBRECHT50], FSK_FRAME_MODE_5N1_FRAMES, v18_tdd_put_async_byte, s);
s->baudot_rx_shift = 0;
s->next_byte = (uint8_t) 0xFF;
break;
case V18_MODE_DTMF:
dtmf_tx_init(&s->dtmftx, v18_dtmf_get, s);
dtmf_rx_init(&s->dtmfrx, v18_dtmf_put, s);
dtmf_tx_init(&s->dtmf_tx, v18_dtmf_get, s);
dtmf_rx_init(&s->dtmf_rx, v18_dtmf_put, s);
break;
case V18_MODE_EDT:
fsk_tx_init(&s->fsktx, &preset_fsk_specs[FSK_V21CH1_110], async_tx_get_bit, &s->asynctx);
async_tx_init(&s->asynctx, 7, ASYNC_PARITY_EVEN, 2, FALSE, v18_edt_get_async_byte, s);
fsk_rx_init(&s->fskrx, &preset_fsk_specs[FSK_V21CH1_110], FSK_FRAME_MODE_7E2_FRAMES, v18_edt_put_async_byte, s);
fsk_tx_init(&s->fsk_tx, &preset_fsk_specs[FSK_V21CH1_110], async_tx_get_bit, &s->async_tx);
async_tx_init(&s->async_tx, 7, ASYNC_PARITY_EVEN, 2, FALSE, v18_edt_get_async_byte, s);
fsk_rx_init(&s->fsk_rx, &preset_fsk_specs[FSK_V21CH1_110], FSK_FRAME_MODE_7E2_FRAMES, v18_edt_put_async_byte, s);
break;
case V18_MODE_BELL103:
fsk_tx_init(&s->fsktx, &preset_fsk_specs[FSK_BELL103CH1], async_tx_get_bit, &s->asynctx);
async_tx_init(&s->asynctx, 7, ASYNC_PARITY_EVEN, 1, FALSE, v18_edt_get_async_byte, s);
fsk_rx_init(&s->fskrx, &preset_fsk_specs[FSK_BELL103CH2], FSK_FRAME_MODE_7E1_FRAMES, v18_bell103_put_async_byte, s);
fsk_tx_init(&s->fsk_tx, &preset_fsk_specs[FSK_BELL103CH1], async_tx_get_bit, &s->async_tx);
async_tx_init(&s->async_tx, 7, ASYNC_PARITY_EVEN, 1, FALSE, v18_edt_get_async_byte, s);
fsk_rx_init(&s->fsk_rx, &preset_fsk_specs[FSK_BELL103CH2], FSK_FRAME_MODE_7E1_FRAMES, v18_bell103_put_async_byte, s);
break;
case V18_MODE_V23VIDEOTEX:
fsk_tx_init(&s->fsktx, &preset_fsk_specs[FSK_V23CH1], async_tx_get_bit, &s->asynctx);
async_tx_init(&s->asynctx, 7, ASYNC_PARITY_EVEN, 1, FALSE, v18_edt_get_async_byte, s);
fsk_rx_init(&s->fskrx, &preset_fsk_specs[FSK_V23CH2], FSK_FRAME_MODE_7E1_FRAMES, v18_videotex_put_async_byte, s);
fsk_tx_init(&s->fsk_tx, &preset_fsk_specs[FSK_V23CH1], async_tx_get_bit, &s->async_tx);
async_tx_init(&s->async_tx, 7, ASYNC_PARITY_EVEN, 1, FALSE, v18_edt_get_async_byte, s);
fsk_rx_init(&s->fsk_rx, &preset_fsk_specs[FSK_V23CH2], FSK_FRAME_MODE_7E1_FRAMES, v18_videotex_put_async_byte, s);
break;
case V18_MODE_V21TEXTPHONE:
fsk_tx_init(&s->fsktx, &preset_fsk_specs[FSK_V21CH1], async_tx_get_bit, &s->asynctx);
async_tx_init(&s->asynctx, 7, ASYNC_PARITY_EVEN, 1, FALSE, v18_edt_get_async_byte, s);
fsk_rx_init(&s->fskrx, &preset_fsk_specs[FSK_V21CH1], FSK_FRAME_MODE_7E1_FRAMES, v18_textphone_put_async_byte, s);
fsk_tx_init(&s->fsk_tx, &preset_fsk_specs[FSK_V21CH1], async_tx_get_bit, &s->async_tx);
async_tx_init(&s->async_tx, 7, ASYNC_PARITY_EVEN, 1, FALSE, v18_edt_get_async_byte, s);
fsk_rx_init(&s->fsk_rx, &preset_fsk_specs[FSK_V21CH1], FSK_FRAME_MODE_7E1_FRAMES, v18_textphone_put_async_byte, s);
break;
case V18_MODE_V18TEXTPHONE:
fsk_tx_init(&s->fsktx, &preset_fsk_specs[FSK_V21CH1], async_tx_get_bit, &s->asynctx);
async_tx_init(&s->asynctx, 7, ASYNC_PARITY_EVEN, 1, FALSE, v18_edt_get_async_byte, s);
fsk_rx_init(&s->fskrx, &preset_fsk_specs[FSK_V21CH1], FSK_FRAME_MODE_7E1_FRAMES, v18_textphone_put_async_byte, s);
fsk_tx_init(&s->fsk_tx, &preset_fsk_specs[FSK_V21CH1], async_tx_get_bit, &s->async_tx);
async_tx_init(&s->async_tx, 7, ASYNC_PARITY_EVEN, 1, FALSE, v18_edt_get_async_byte, s);
fsk_rx_init(&s->fsk_rx, &preset_fsk_specs[FSK_V21CH1], FSK_FRAME_MODE_7E1_FRAMES, v18_textphone_put_async_byte, s);
break;
}
s->nation = nation;

View File

@ -45,7 +45,7 @@
uint8_t buffer[256];
#define PATTERN 0x11111111
#define PATTERN 0x1111111
#define SEQUENCE_LENGTH 17
uint8_t left[] =
@ -111,7 +111,7 @@ int main(int argc, char *argv[])
total_bits = 0;
for (i = 0; i < SEQUENCE_LENGTH; i++)
{
bitstream_put(s, &w, PATTERN*i, i + 1);
bitstream_put(s, &w, i*PATTERN, i + 1);
total_bits += (i + 1);
}
bitstream_flush(s, &w);

View File

@ -490,6 +490,7 @@ int main(int argc, char *argv[])
int noise_level;
int code_to_look_up;
int scan_line_time;
int allowed_bilevel_resolutions;
int colour_enabled;
t38_stats_t t38_stats;
t30_stats_t t30_stats;
@ -529,12 +530,16 @@ int main(int argc, char *argv[])
scan_line_time = 0;
decode_file_name = NULL;
code_to_look_up = -1;
allowed_bilevel_resolutions = 0;
colour_enabled = FALSE;
t38_transport = T38_TRANSPORT_UDPTL;
while ((opt = getopt(argc, argv, "c:Cd:D:efFgH:i:Ilm:M:n:p:s:S:tT:u:v:z:")) != -1)
while ((opt = getopt(argc, argv, "b:c:Cd:D:efFgH:i:Ilm:M:n:p:s:S:tT:u:v:z:")) != -1)
{
switch (opt)
{
case 'b':
allowed_bilevel_resolutions = atoi(optarg);
break;
case 'c':
code_to_look_up = atoi(optarg);
break;
@ -850,41 +855,63 @@ int main(int argc, char *argv[])
| T4_SUPPORT_LENGTH_US_LETTER
| T4_SUPPORT_LENGTH_US_LEGAL
| T4_SUPPORT_LENGTH_UNLIMITED);
#if 1
t30_set_supported_bilevel_resolutions(t30_state[i],
T4_SUPPORT_RESOLUTION_R8_STANDARD
| T4_SUPPORT_RESOLUTION_R8_FINE
| T4_SUPPORT_RESOLUTION_R8_SUPERFINE
| T4_SUPPORT_RESOLUTION_R16_SUPERFINE
| T4_SUPPORT_RESOLUTION_200_100
| T4_SUPPORT_RESOLUTION_200_200
| T4_SUPPORT_RESOLUTION_200_400
| T4_SUPPORT_RESOLUTION_300_300
| T4_SUPPORT_RESOLUTION_300_600
| T4_SUPPORT_RESOLUTION_400_400
| T4_SUPPORT_RESOLUTION_400_800
| T4_SUPPORT_RESOLUTION_600_600
| T4_SUPPORT_RESOLUTION_600_1200
| T4_SUPPORT_RESOLUTION_1200_1200);
#elif 0
t30_set_supported_bilevel_resolutions(t30_state[i],
T4_SUPPORT_RESOLUTION_R8_STANDARD
| T4_SUPPORT_RESOLUTION_R8_FINE
| T4_SUPPORT_RESOLUTION_R8_SUPERFINE
| T4_SUPPORT_RESOLUTION_R16_SUPERFINE);
#else
t30_set_supported_bilevel_resolutions(t30_state[i],
T4_SUPPORT_RESOLUTION_200_100
| T4_SUPPORT_RESOLUTION_200_200
| T4_SUPPORT_RESOLUTION_200_400
| T4_SUPPORT_RESOLUTION_300_300
| T4_SUPPORT_RESOLUTION_300_600
| T4_SUPPORT_RESOLUTION_400_400
| T4_SUPPORT_RESOLUTION_400_800
| T4_SUPPORT_RESOLUTION_600_600
| T4_SUPPORT_RESOLUTION_600_1200
| T4_SUPPORT_RESOLUTION_1200_1200);
#endif
switch (allowed_bilevel_resolutions)
{
case 0:
/* Allow anything */
t30_set_supported_bilevel_resolutions(t30_state[i],
T4_SUPPORT_RESOLUTION_R8_STANDARD
| T4_SUPPORT_RESOLUTION_R8_FINE
| T4_SUPPORT_RESOLUTION_R8_SUPERFINE
| T4_SUPPORT_RESOLUTION_R16_SUPERFINE
| T4_SUPPORT_RESOLUTION_200_100
| T4_SUPPORT_RESOLUTION_200_200
| T4_SUPPORT_RESOLUTION_200_400
| T4_SUPPORT_RESOLUTION_300_300
| T4_SUPPORT_RESOLUTION_300_600
| T4_SUPPORT_RESOLUTION_400_400
| T4_SUPPORT_RESOLUTION_400_800
| T4_SUPPORT_RESOLUTION_600_600
| T4_SUPPORT_RESOLUTION_600_1200
| T4_SUPPORT_RESOLUTION_1200_1200);
break;
case 1:
/* Allow anything metric */
t30_set_supported_bilevel_resolutions(t30_state[i],
T4_SUPPORT_RESOLUTION_R8_STANDARD
| T4_SUPPORT_RESOLUTION_R8_FINE
| T4_SUPPORT_RESOLUTION_R8_SUPERFINE
| T4_SUPPORT_RESOLUTION_R16_SUPERFINE);
break;
case 2:
/* Allow anything inch based */
t30_set_supported_bilevel_resolutions(t30_state[i],
T4_SUPPORT_RESOLUTION_200_100
| T4_SUPPORT_RESOLUTION_200_200
| T4_SUPPORT_RESOLUTION_200_400
| T4_SUPPORT_RESOLUTION_300_300
| T4_SUPPORT_RESOLUTION_300_600
| T4_SUPPORT_RESOLUTION_400_400
| T4_SUPPORT_RESOLUTION_400_800
| T4_SUPPORT_RESOLUTION_600_600
| T4_SUPPORT_RESOLUTION_600_1200
| T4_SUPPORT_RESOLUTION_1200_1200);
break;
case 3:
/* Allow only restricted length resolution */
t30_set_supported_bilevel_resolutions(t30_state[i],
T4_SUPPORT_RESOLUTION_R8_STANDARD
| T4_SUPPORT_RESOLUTION_R8_FINE
| T4_SUPPORT_RESOLUTION_200_100
| T4_SUPPORT_RESOLUTION_200_200);
break;
case 4:
/* Allow only more restricted length resolution */
t30_set_supported_bilevel_resolutions(t30_state[i],
T4_SUPPORT_RESOLUTION_R8_STANDARD
| T4_SUPPORT_RESOLUTION_200_100);
break;
}
if (colour_enabled)
{
t30_set_supported_colour_resolutions(t30_state[i],

View File

@ -147,11 +147,15 @@ int main(int argc, char *argv[])
uint16_t *map_b;
uint16_t *map_z;
uint32_t jpeg_table_len;
#if 0
logging_state_t *logging;
#endif
printf("Demo of ITU/Lab library.\n");
#if 0
logging = span_log_init(NULL, SPAN_LOG_FLOW, "T.42");
#endif
#if defined(SPANDSP_SUPPORT_TIFF_FX)
TIFF_FX_init();
@ -265,6 +269,7 @@ int main(int argc, char *argv[])
break;
}
outsize = 0;
if (process_raw)
{
uint8_t *jpeg_table;

View File

@ -552,7 +552,6 @@ int read_compressed_image(meta_t *meta, uint8_t **buf)
int read_decompressed_image(meta_t *meta, uint8_t **buf)
{
int bytes_per_row;
tsize_t off;
int x;
int y;
int xx;
@ -561,21 +560,23 @@ int read_decompressed_image(meta_t *meta, uint8_t **buf)
int yyy;
int i;
int j;
uint32_t w;
uint32_t h;
uint16_t samples_per_pixel;
int result;
int total_raw;
int total_data;
uint8_t *raw_buf;
uint8_t *image_buf;
uint8_t *jpeg_table;
uint32_t jpeg_table_len;
t85_decode_state_t t85;
t43_decode_state_t t43;
packer_t pack;
logging_state_t *logging;
logging_state_t logging2;
#if 0
uint8_t *jpeg_table;
uint32_t jpeg_table_len;
tsize_t off;
uint32_t w;
uint32_t h;
#endif
image_buf = NULL;
total_data = 0;
@ -652,8 +653,8 @@ total_data *= 8;
if ((image_buf = malloc(total_data)) == NULL)
printf("Failed to allocated image buffer\n");
jpeg_table_len = 0;
#if 0
jpeg_table_len = 0;
if (TIFFGetField(meta->tif, TIFFTAG_JPEGTABLES, &jpeg_table_len, &jpeg_table))
{
total_image_len += (jpeg_table_len - 4);
@ -921,6 +922,7 @@ int main(int argc, char *argv[])
set_lab_illuminant(&lab_param, 96.422f, 100.000f, 82.521f);
set_lab_gamut(&lab_param, 0, 100, -85, 85, -75, 125, FALSE);
outptr = NULL;
for (page_no = 0; ; page_no++)
{
if (read_file(&in_meta, page_no) < 0)

View File

@ -53,48 +53,6 @@ in ITU specifications T.4 and T.6.
t4_tx_state_t *send_state;
t4_rx_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
static const char t4_t6_test_patterns[][1728 + 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). */
};
int rows_written = 0;
int rows_read = 0;
@ -140,63 +98,7 @@ static void display_page_stats(t4_rx_state_t *s)
}
/*- End of function --------------------------------------------------------*/
static int row_read_handler(void *user_data, uint8_t buf[], size_t len)
{
int i;
int j;
const char *s;
/* Send the test pattern. */
if (rows_read >= 16)
return 0;
s = t4_t6_test_patterns[rows_read++];
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, rows_read);
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;
uint8_t ref[8192];
/* Verify that what is received matches the test pattern. */
if (len == 0)
return 0;
s = t4_t6_test_patterns[rows_written++];
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, rows_written);
if (memcmp(buf, ref, len))
{
printf("Test failed at row %d\n", rows_written);
exit(2);
}
return 0;
}
/*- End of function --------------------------------------------------------*/
static int detect_page_end(int bit, int page_ended)
static int detect_non_ecm_page_end(int bit, int page_ended)
{
static int consecutive_eols;
static int max_consecutive_eols;
@ -207,10 +109,10 @@ static int detect_page_end(int bit, int page_ended)
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)
/* Check the EOLs are added properly to the end of a non-ECM 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 == -1)
{
/* Reset */
consecutive_eols = 0;
@ -287,6 +189,9 @@ int main(int argc, char *argv[])
T4_COMPRESSION_T6,
T4_COMPRESSION_T85,
T4_COMPRESSION_T85_L0,
#if defined(SPANDSP_SUPPORT_T88x)
T4_COMPRESSION_T88,
#endif
#if defined(SPANDSP_SUPPORT_T42x)
T4_COMPRESSION_T42_T81,
T4_COMPRESSION_SYCC_T81,
@ -294,7 +199,9 @@ int main(int argc, char *argv[])
#if defined(SPANDSP_SUPPORT_T43x)
T4_COMPRESSION_T43,
#endif
//T4_COMPRESSION_T45,
#if defined(SPANDSP_SUPPORT_T45x)
T4_COMPRESSION_T45,
#endif
-1
};
int sends;
@ -348,7 +255,10 @@ int main(int argc, char *argv[])
case 'b':
block_size = atoi(optarg);
if (block_size > 1024)
block_size = 1024;
{
printf("Block size too large. Must be 1024 or less\n");
exit(2);
}
break;
case 'c':
if (strcmp(optarg, "T41D") == 0)
@ -371,6 +281,13 @@ int main(int argc, char *argv[])
compression = T4_COMPRESSION_T85;
compression_step = -1;
}
#if defined(SPANDSP_SUPPORT_T88)
else if (strcmp(optarg, "T88") == 0)
{
compression = T4_COMPRESSION_T88;
compression_step = -1;
}
#endif
#if defined(SPANDSP_SUPPORT_T42)
else if (strcmp(optarg, "T81") == 0)
{
@ -385,6 +302,18 @@ int main(int argc, char *argv[])
compression_step = -1;
}
#endif
#if defined(SPANDSP_SUPPORT_T45)
else if (strcmp(optarg, "T45") == 0)
{
compression = T4_COMPRESSION_T45;
compression_step = -1;
}
#endif
else
{
printf("Unrecognised compression.\n");
exit(2);
}
break;
case 'd':
decode_file_name = optarg;
@ -533,130 +462,6 @@ int main(int argc, char *argv[])
}
else
{
#if 1
printf("Testing image_function->compress->decompress->image_function\n");
/* Send end gets image from a function */
if ((send_state = t4_tx_init(NULL, NULL, -1, -1)) == NULL)
{
printf("Failed to init T.4 tx\n");
exit(2);
}
span_log_set_level(t4_tx_get_logging_state(send_state), 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_max_2d_rows_per_1d_row(send_state, 2);
/* Receive end puts TIFF to a function. */
if ((receive_state = t4_rx_init(NULL, NULL, T4_COMPRESSION_T4_2D)) == NULL)
{
printf("Failed to init T.4 rx\n");
exit(2);
}
span_log_set_level(t4_rx_get_logging_state(receive_state), SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_FLOW);
t4_rx_set_row_write_handler(receive_state, row_write_handler, NULL);
t4_rx_set_image_width(receive_state, t4_tx_get_image_width(send_state));
t4_rx_set_x_resolution(receive_state, t4_tx_get_x_resolution(send_state));
t4_rx_set_y_resolution(receive_state, t4_tx_get_y_resolution(send_state));
/* 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 || (block_size == 0 && compression_step >= 3))
break;
}
t4_tx_set_tx_encoding(send_state, compression);
t4_rx_set_rx_encoding(receive_state, compression);
rows_read = 0;
rows_written = 0;
if (t4_tx_start_page(send_state))
break;
if (t4_rx_start_page(receive_state))
break;
detect_page_end(-1000000, compression);
page_ended = FALSE;
switch (block_size)
{
case 0:
while ((bit = t4_tx_get_bit(send_state)) >= 0)
{
/* Monitor whether the EOLs are there in the correct amount */
if ((res = detect_page_end(bit, page_ended)))
{
printf("Incorrect EOLs - %d\n", res);
tests_failed += (res - 1);
break;
}
if (bit >= 0)
{
if (bit_error_rate)
{
if ((rand() % bit_error_rate) == 0)
bit ^= 1;
}
end_of_page = t4_rx_put_bit(receive_state, bit);
}
}
while (end_of_page != T4_DECODE_OK)
{
end_of_page = t4_rx_put_bit(receive_state, 0);
if (++end_marks > 50)
{
printf("Receiver missed the end of page mark\n");
tests_failed++;
break;
}
}
/* Now throw junk at the receive context, to ensure stuff occuring
after the end of page condition has no bad effect. */
for (i = 0; i < 1000; i++)
t4_rx_put_bit(receive_state, (rand() >> 10) & 1);
break;
default:
/* Some decoders require a few extra bits before the recognise the end
of an image, so be prepared to offer it a few. */
do
{
len = t4_tx_get(send_state, block, block_size);
if (len > 0)
end_of_page = t4_rx_put(receive_state, block, len);
}
while (len > 0);
while (end_of_page != T4_DECODE_OK)
{
block[0] = 0;
end_of_page = t4_rx_put(receive_state, block, 1);
if (++end_marks > 5)
{
printf("Receiver missed the end of page mark\n");
tests_failed++;
break;
}
}
break;
}
display_page_stats(receive_state);
t4_tx_end_page(send_state);
t4_rx_end_page(receive_state);
if (rows_read != (15 + 1) || rows_written != (15 + 1))
{
printf("Test failed: %d rows read, %d rows written\n", rows_read, rows_written);
exit(2);
}
if (compression_step < 0)
break;
}
t4_tx_release(send_state);
t4_rx_release(receive_state);
#endif
#if 1
printf("Testing TIFF->compress->decompress->TIFF cycle\n");
/* Send end gets TIFF from a file */
@ -713,6 +518,37 @@ int main(int argc, char *argv[])
compression = compression_sequence[compression_step++];
}
}
#if 0
if (t4_tx_set_tx_image_format(send_state,
compression,
T4_SUPPORT_WIDTH_215MM
| T4_SUPPORT_LENGTH_US_LETTER
| T4_SUPPORT_LENGTH_US_LEGAL
| T4_SUPPORT_LENGTH_UNLIMITED,
T4_RESOLUTION_R8_STANDARD
| T4_RESOLUTION_R8_FINE
| T4_RESOLUTION_R8_SUPERFINE
| T4_RESOLUTION_R16_SUPERFINE
| T4_RESOLUTION_200_100
| T4_RESOLUTION_200_200
| T4_RESOLUTION_200_400
| T4_RESOLUTION_300_300
| T4_RESOLUTION_300_600
| T4_RESOLUTION_400_400
| T4_RESOLUTION_400_800
| T4_RESOLUTION_600_600
| T4_RESOLUTION_600_1200
| T4_RESOLUTION_1200_1200,
T4_RESOLUTION_100_100
| T4_RESOLUTION_200_200
| T4_RESOLUTION_300_300
| T4_RESOLUTION_400_400
| T4_RESOLUTION_600_600
| T4_RESOLUTION_1200_1200) < 0)
{
break;
}
#endif
t4_tx_set_tx_encoding(send_state, compression);
t4_rx_set_rx_encoding(receive_state, compression);
@ -723,15 +559,17 @@ int main(int argc, char *argv[])
t4_rx_set_image_width(receive_state, t4_tx_get_image_width(send_state));
}
t4_rx_start_page(receive_state);
detect_page_end(-1000000, compression);
detect_non_ecm_page_end(-1, compression);
page_ended = FALSE;
switch (block_size)
{
case 0:
/* Bit by bit operation. This is only appropriate for T.4 1D and 2D,
which are used without ECM. */
while ((bit = t4_tx_get_bit(send_state)) >= 0)
{
/* Monitor whether the EOLs are there in the correct amount */
if ((res = detect_page_end(bit, page_ended)))
if ((res = detect_non_ecm_page_end(bit, page_ended)))
{
printf("Incorrect EOLs - %d\n", res);
tests_failed += (res - 1);
@ -767,7 +605,7 @@ int main(int argc, char *argv[])
end_of_page = t4_rx_put(receive_state, block, len);
}
while (len > 0);
/* Some decoders require a few extra bits before the recognise the end
/* Some decoders require a few extra bits before they recognise the end
of an image, so be prepared to offer it a few. */
while (end_of_page != T4_DECODE_OK)
{

View File

@ -54,8 +54,8 @@ static int test_vec_copyf(void)
for (i = 0; i < 99; i++)
{
x[i] = i;
za[i] = -1.0f;
zb[i] = -1.0f;
za[i] = -0.5f;
zb[i] = -0.5f;
}
vec_copyf_dumb(za + 3, x + 1, 0);
vec_copyf(zb + 3, x + 1, 0);
@ -114,8 +114,8 @@ static int test_vec_negatef(void)
for (i = 0; i < 99; i++)
{
x[i] = i;
za[i] = -1.0f;
zb[i] = -1.0f;
za[i] = -0.5f;
zb[i] = -0.5f;
}
vec_negatef_dumb(za + 3, x + 1, 0);
vec_negatef(zb + 3, x + 1, 0);
@ -143,6 +143,7 @@ static int test_vec_negatef(void)
vec_negatef(zb + 3, x + 1, 29);
for (i = 0; i < 99; i++)
{
printf("C %d %f %f %f\n", i, x[i], za[i], zb[i]);
if (za[i] != zb[i])
{
printf("vec_negatef() - %d %f %f\n", i, za[i], zb[i]);