* 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_)
#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.
*/
t45_decode_state_t t45;
#endif
} decoder;
+
+ t4_image_put_handler_t image_put_handler;
+
int current_decoder;
uint8_t *pre_encoded_buf;
#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.
*/
/*! \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;
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;
#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. */
} 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];
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);
||
((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))
{
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
{
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
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))
/* 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;
}
/*- 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. */
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)
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];
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];
/* 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 */
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)
{
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;
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;
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;
}
}
{
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;
}
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;
//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;
{
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;
uint8_t buffer[256];
-#define PATTERN 0x11111111
+#define PATTERN 0x1111111
#define SEQUENCE_LENGTH 17
uint8_t left[] =
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);
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;
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;
| 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],
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();
break;
}
+ outsize = 0;
if (process_raw)
{
uint8_t *jpeg_table;
int read_decompressed_image(meta_t *meta, uint8_t **buf)
{
int bytes_per_row;
- tsize_t off;
int x;
int y;
int xx;
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;
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);
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)
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;
}
/*- 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;
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;
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,
#if defined(SPANDSP_SUPPORT_T43x)
T4_COMPRESSION_T43,
#endif
- //T4_COMPRESSION_T45,
+#if defined(SPANDSP_SUPPORT_T45x)
+ T4_COMPRESSION_T45,
+#endif
-1
};
int sends;
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)
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)
{
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;
}
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 */
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);
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);
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)
{
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);
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);
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]);