/*! \brief TRUE if a local T.30 interrupt is pending. */
int local_interrupt_pending;
+ /*! \brief The image coding to be used on the line for non-bilevel images. */
+ int multilevel_line_encoding;
/*! \brief The image coding being used on the line. */
int line_encoding;
/*! \brief The image coding being used for output files. */
/*! \brief Row counter for playing out the rows of the image. */
int row;
- /*! \brief Image length of the image in the file. This is used when the
- image is resized or dithered flat. */
+ /*! \brief Width of the image in the file. */
+ int image_width;
+ /*! \brief Length of the image in the file. */
int 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 Row counter used when the image is resized or dithered flat. */
int raw_row;
} t4_tx_tiff_state_t;
*/
typedef struct
{
- /*! \brief Column-to-column (X) resolution in pixels per metre. */
+ /*! \brief Column-to-column (X) resolution in pixels per metre on the wire. */
int x_resolution;
- /*! \brief Row-to-row (Y) resolution in pixels per metre. */
+ /*! \brief Row-to-row (Y) resolution in pixels per metre on the wire. */
int y_resolution;
} t4_tx_metadata_t;
if (product == 0x40000000)
return INT16_MAX;
/*endif*/
- return (int16_t)(product >> 15);
+ return (int16_t) (product >> 15);
}
/*- End of function --------------------------------------------------------*/
int pages_rx;
/*! \brief The number of pages in the file (<0 if not known). */
int pages_in_file;
- /*! \brief The horizontal column-to-column resolution of the most recent page, in pixels per metre */
+ /*! \brief The type of image of the most recent file page */
+ int image_type;
+ /*! \brief The horizontal column-to-column resolution of the most recent file page, in pixels per metre */
+ int image_x_resolution;
+ /*! \brief The vertical row-to-row resolution of the most recent file page, in pixels per metre */
+ int image_y_resolution;
+ /*! \brief The number of horizontal pixels in the most recent file page. */
+ int image_width;
+ /*! \brief The number of vertical pixels in the most recent file page. */
+ int image_length;
+ /*! \brief The type of image of the most recent exchanged page */
+ int type;
+ /*! \brief The horizontal column-to-column resolution of the most recent exchanged page, in pixels per metre */
int x_resolution;
- /*! \brief The vertical row-to-row resolution of the most recent page, in pixels per metre */
+ /*! \brief The vertical row-to-row resolution of the most recent exchanged page, in pixels per metre */
int y_resolution;
- /*! \brief The number of horizontal pixels in the most recent page. */
+ /*! \brief The number of horizontal pixels in the most recent exchanged page. */
int width;
- /*! \brief The number of vertical pixels in the most recent page. */
+ /*! \brief The number of vertical pixels in the most recent exchanged page. */
int length;
/*! \brief The size of the image, in bytes */
int image_size;
int pages_transferred;
/*! \brief The number of pages in the file (<0 if unknown). */
int pages_in_file;
- /*! \brief The number of horizontal pixels in the most recent page. */
- int width;
- /*! \brief The number of vertical pixels in the most recent page. */
- int length;
/*! \brief The number of bad pixel rows in the most recent page. */
int bad_rows;
/*! \brief The largest number of bad pixel rows in a block in the most recent page. */
int longest_bad_row_run;
- /*! \brief The horizontal resolution of the page in pixels per metre */
+ /*! \brief The type of image in the file page */
+ int image_type;
+ /*! \brief The horizontal resolution of the file page in pixels per metre */
+ int image_x_resolution;
+ /*! \brief The vertical resolution of the file page in pixels per metre */
+ int image_y_resolution;
+ /*! \brief The number of horizontal pixels in the file page. */
+ int image_width;
+ /*! \brief The number of vertical pixels in the file page. */
+ int image_length;
+ /*! \brief The type of image in the exchanged page */
+ int type;
+ /*! \brief The horizontal resolution of the exchanged page in pixels per metre */
int x_resolution;
- /*! \brief The vertical resolution of the page in pixels per metre */
+ /*! \brief The vertical resolution of the exchanged page in pixels per metre */
int y_resolution;
+ /*! \brief The number of horizontal pixels in the exchanged page. */
+ int width;
+ /*! \brief The number of vertical pixels in the exchanged page. */
+ int length;
/*! \brief The type of compression used between the FAX machines */
int encoding;
/*! \brief The size of the image on the line, in bytes */
\return A pointer to the string. */
SPAN_DECLARE(const char *) t4_encoding_to_str(int encoding);
+/*! Get the short text name of an image format.
+ \brief Get the short text name of an image format.
+ \param encoding The image format.
+ \return A pointer to the string. */
+SPAN_DECLARE(const char *) t4_image_type_to_str(int type);
+
#if defined(__cplusplus)
}
#endif
t->pages_tx = s->tx_page_number;
t->pages_rx = s->rx_page_number;
t->pages_in_file = stats.pages_in_file;
- t->width = stats.width;
- t->length = stats.length;
t->bad_rows = stats.bad_rows;
t->longest_bad_row_run = stats.longest_bad_row_run;
+
+ t->image_type = stats.image_type;
+ t->image_x_resolution = stats.image_x_resolution;
+ t->image_y_resolution = stats.image_y_resolution;
+ t->image_width = stats.image_width;
+ t->image_length = stats.image_length;
+
+ t->type = stats.type;
t->x_resolution = stats.x_resolution;
t->y_resolution = stats.y_resolution;
+ t->width = stats.width;
+ t->length = stats.length;
+
t->encoding = stats.encoding;
t->image_size = stats.line_image_size;
t->current_status = s->current_status;
}
/*- End of function --------------------------------------------------------*/
+SPAN_DECLARE(const char *) t4_image_type_to_str(int type)
+{
+ switch (type)
+ {
+ case T4_IMAGE_TYPE_BILEVEL:
+ return "bi-level";
+ case T4_IMAGE_TYPE_COLOUR_BILEVEL:
+ return "bi-level colour";
+ case T4_IMAGE_TYPE_GRAY_8BIT:
+ return "8-bit gray scale";
+ case T4_IMAGE_TYPE_GRAY_12BIT:
+ return "12-bit gray scale";
+ case T4_IMAGE_TYPE_COLOUR_8BIT:
+ return "8-bit colour";
+ case T4_IMAGE_TYPE_COLOUR_12BIT:
+ return "12-bit colour";
+ }
+ return "???";
+}
+/*- End of function --------------------------------------------------------*/
+
static int set_tiff_directory_info(t4_rx_state_t *s)
{
time_t now;
memset(t, 0, sizeof(*t));
t->pages_transferred = s->current_page;
t->pages_in_file = s->tiff.pages_in_file;
+ t->image_x_resolution = s->metadata.x_resolution;
+ t->image_y_resolution = s->metadata.y_resolution;
t->x_resolution = s->metadata.x_resolution;
t->y_resolution = s->metadata.y_resolution;
t->encoding = s->line_encoding;
case T4_COMPRESSION_ITU_T4_1D:
case T4_COMPRESSION_ITU_T4_2D:
case T4_COMPRESSION_ITU_T6:
+ t->type = T4_IMAGE_TYPE_BILEVEL;
t->width = t4_t6_decode_get_image_width(&s->decoder.t4_t6);
t->length = t4_t6_decode_get_image_length(&s->decoder.t4_t6);
+ t->image_type = t->type;
+ t->image_width = t->width;
+ t->image_length = t->length;
t->line_image_size = t4_t6_decode_get_compressed_image_size(&s->decoder.t4_t6)/8;
t->bad_rows = s->decoder.t4_t6.bad_rows;
t->longest_bad_row_run = s->decoder.t4_t6.longest_bad_row_run;
break;
case T4_COMPRESSION_ITU_T42:
+ t->type = 0;
t->width = t42_decode_get_image_width(&s->decoder.t42);
t->length = t42_decode_get_image_length(&s->decoder.t42);
+ t->image_type = t->type;
+ t->image_width = t->width;
+ t->image_length = t->length;
t->line_image_size = t42_decode_get_compressed_image_size(&s->decoder.t42)/8;
break;
#if defined(SPANDSP_SUPPORT_T43)
case T4_COMPRESSION_ITU_T43:
+ t->type = 0;
t->width = t43_decode_get_image_width(&s->decoder.t43);
t->length = t43_decode_get_image_length(&s->decoder.t43);
+ t->image_type = t->type;
+ t->image_width = t->width;
+ t->image_length = t->length;
t->line_image_size = t43_decode_get_compressed_image_size(&s->decoder.t43)/8;
break;
#endif
case T4_COMPRESSION_ITU_T85:
case T4_COMPRESSION_ITU_T85_L0:
+ t->type = T4_IMAGE_TYPE_BILEVEL;
t->width = t85_decode_get_image_width(&s->decoder.t85);
t->length = t85_decode_get_image_length(&s->decoder.t85);
+ t->image_type = t->type;
+ t->image_width = t->width;
+ t->image_length = t->length;
t->line_image_size = t85_decode_get_compressed_image_size(&s->decoder.t85)/8;
break;
}
#endif
parm32 = 0;
TIFFGetField(t->tiff_file, TIFFTAG_IMAGEWIDTH, &parm32);
+ t->image_width =
s->image_width = parm32;
parm32 = 0;
TIFFGetField(t->tiff_file, TIFFTAG_IMAGELENGTH, &parm32);
- s->tiff.image_length =
+ t->image_length =
s->image_length = parm32;
x_resolution = 0.0f;
TIFFGetField(t->tiff_file, TIFFTAG_XRESOLUTION, &x_resolution);
break;
}
}
+ if (res_unit == RESUNIT_INCH)
+ t->image_x_resolution = x_resolution*100.0f/CM_PER_INCH;
+ else
+ t->image_x_resolution = x_resolution*100.0f;
s->metadata.y_resolution = T4_Y_RESOLUTION_STANDARD;
for (i = 0; y_res_table[i].code > 0; i++)
break;
}
}
+ if (res_unit == RESUNIT_INCH)
+ t->image_y_resolution = y_resolution*100.0f/CM_PER_INCH;
+ else
+ t->image_y_resolution = y_resolution*100.0f;
+
t4_tx_set_image_width(s, s->image_width);
t4_tx_set_image_length(s, s->image_length);
t4_tx_set_max_2d_rows_per_1d_row(s, -s->metadata.y_resolution);
if (t->image_type != T4_IMAGE_TYPE_BILEVEL)
return -1;
#endif
- if (s->tiff.image_type != image_type)
+ if (t->image_type != image_type)
return 1;
parm32 = 0;
memset(t, 0, sizeof(*t));
t->pages_transferred = s->current_page - s->start_page;
t->pages_in_file = s->tiff.pages_in_file;
+
+ 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->x_resolution = s->metadata.x_resolution;
t->y_resolution = s->metadata.y_resolution/s->row_squashing_ratio;
t->encoding = s->line_encoding;
case T4_COMPRESSION_ITU_T4_1D:
case T4_COMPRESSION_ITU_T4_2D:
case T4_COMPRESSION_ITU_T6:
+ t->type = T4_IMAGE_TYPE_BILEVEL;
t->width = t4_t6_encode_get_image_width(&s->encoder.t4_t6);
- t->length = t4_t6_encode_get_image_length(&s->encoder.t4_t6);
+ t->length = t4_t6_encode_get_image_length(&s->encoder.t4_t6)/s->row_squashing_ratio;
t->line_image_size = t4_t6_encode_get_compressed_image_size(&s->encoder.t4_t6)/8;
break;
case T4_COMPRESSION_ITU_T42:
+ t->type = 0;
t->width = t42_encode_get_image_width(&s->encoder.t42);
- t->length = t42_encode_get_image_length(&s->encoder.t42);
+ t->length = t42_encode_get_image_length(&s->encoder.t42)/s->row_squashing_ratio;
t->line_image_size = t42_encode_get_compressed_image_size(&s->encoder.t42)/8;
break;
#if defined(SPANDSP_SUPPORT_T43)
case T4_COMPRESSION_ITU_T43:
+ t->type = 0;
t->width = t43_encode_get_image_width(&s->encoder.t43);
- t->length = t43_encode_get_image_length(&s->encoder.t43);
+ t->length = t43_encode_get_image_length(&s->encoder.t43)/s->row_squashing_ratio;
t->line_image_size = t43_encode_get_compressed_image_size(&s->encoder.t43)/8;
break;
#endif
case T4_COMPRESSION_ITU_T85:
case T4_COMPRESSION_ITU_T85_L0:
+ t->type = T4_IMAGE_TYPE_BILEVEL;
t->width = t85_encode_get_image_width(&s->encoder.t85);
- t->length = t85_encode_get_image_length(&s->encoder.t85);
+ t->length = t85_encode_get_image_length(&s->encoder.t85)/s->row_squashing_ratio;
t->line_image_size = t85_encode_get_compressed_image_size(&s->encoder.t85)/8;
break;
}
exit(2);
}
- gen = dtmf_tx_init(NULL);
+ gen = dtmf_tx_init(NULL, NULL, NULL);
len = dtmf_tx(gen, amp, 16384);
printf("Generated %d samples\n", len);
sf_writef_short(outhandle, amp, len);
}
while (len > 0);
- dtmf_tx_init(gen);
+ dtmf_tx_init(gen, NULL, NULL);
len = dtmf_tx(gen, amp, 16384);
printf("Generated %d samples\n", len);
sf_writef_short(outhandle, amp, len);
int image_len;
int image_ptr;
int image_bit_ptr;
-
+
int ecm_frame_size;
int corrupt_crc;
-
+
int final_delayed;
fax_modems_state_t modems;
-
+
+ /*! \brief CED or CNG detector */
+ modem_connect_tones_rx_state_t connect_rx;
+
/*! If TRUE, transmission is in progress */
int transmit;
decode_file_name = NULL;
code_to_look_up = -1;
t38_transport = T38_TRANSPORT_UDPTL;
- while ((opt = getopt(argc, argv, "c:d:D:efFgH:i:Ilm:M:n:p:s:tT:u:v:z:")) != -1)
+ while ((opt = getopt(argc, argv, "c:d:D:efFgH:i:Ilm:M:n:p:s:S:tT:u:v:z:")) != -1)
{
switch (opt)
{
T30_SUPPORT_T4_1D_COMPRESSION
| T30_SUPPORT_T4_2D_COMPRESSION
| T30_SUPPORT_T6_COMPRESSION
- | T30_SUPPORT_T81_COMPRESSION
+ //| T30_SUPPORT_T81_COMPRESSION
| T30_SUPPORT_T85_COMPRESSION
| T30_SUPPORT_T85_L0_COMPRESSION);
}
printf("%s: Bad ECM frames %d\n", tag, t.error_correcting_mode_retries);
printf("%s: Compression type %s (%d)\n", tag, t4_encoding_to_str(t.encoding), t.encoding);
printf("%s: Compressed image size %d bytes\n", tag, t.image_size);
- printf("%s: Image size %d pels x %d pels\n", tag, t.width, t.length);
- printf("%s: Image resolution %d pels/m x %d pels/m\n", tag, t.x_resolution, t.y_resolution);
+ printf("%s: Image type %s (%s in the file)\n", tag, t4_image_type_to_str(t.type), t4_image_type_to_str(t.image_type));
+ printf("%s: Image size %d pels x %d pels (%d pels x %d pels in the file)\n", tag, t.width, t.length, t.image_width, t.image_length);
+ printf("%s: Image resolution %d pels/m x %d pels/m (%d pels/m x %d pels/m in the file)\n", tag, t.x_resolution, t.y_resolution, t.image_x_resolution, t.image_y_resolution);
#if defined(SPANDSP_EXPOSE_INTERNAL_STRUCTURES)
printf("%s: Bits per row - min %d, max %d\n", tag, s->t4.tx.encoder.t4_t6.min_row_bits, s->t4.tx.encoder.t4_t6.max_row_bits);
#endif
printf("Pages = %d\n", stats.pages_transferred);
printf("Compression = %s\n", t4_encoding_to_str(stats.encoding));
printf("Compressed size = %d\n", stats.line_image_size);
+ printf("Raw image size = %d pels x %d pels\n", stats.image_width, stats.image_length);
printf("Image size = %d pels x %d pels\n", stats.width, stats.length);
+ printf("Raw image resolution = %d pels/m x %d pels/m\n", stats.image_x_resolution, stats.image_y_resolution);
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);
static int phase_d_handler(t30_state_t *s, void *user_data, int msg)
{
t30_stats_t t30_stats;
- char *fax_image_resolution = NULL;
+ char *fax_file_image_resolution = NULL;
+ char *fax_line_image_resolution = NULL;
+ char *fax_file_image_pixel_size = NULL;
+ char *fax_line_image_pixel_size = NULL;
char *fax_image_size = NULL;
- char *fax_image_pixel_size = NULL;
char *fax_bad_rows = NULL;
char *fax_encoding = NULL;
char *fax_longest_bad_row_run = NULL;
/* Set Channel Variable */
- fax_image_resolution = switch_core_session_sprintf(session, "%ix%i", t30_stats.x_resolution, t30_stats.y_resolution);
- if (fax_image_resolution) {
- switch_channel_set_variable(channel, "fax_image_resolution", fax_image_resolution);
+ fax_line_image_resolution = switch_core_session_sprintf(session, "%ix%i", t30_stats.x_resolution, t30_stats.y_resolution);
+ if (fax_line_image_resolution) {
+ switch_channel_set_variable(channel, "fax_image_resolution", fax_line_image_resolution);
+ }
+
+ fax_file_image_resolution = switch_core_session_sprintf(session, "%ix%i", t30_stats.image_x_resolution, t30_stats.image_y_resolution);
+ if (fax_file_image_resolution) {
+ switch_channel_set_variable(channel, "fax_file_image_resolution", fax_file_image_resolution);
+ }
+
+ fax_line_image_pixel_size = switch_core_session_sprintf(session, "%ix%i", t30_stats.width, t30_stats.length);
+ if (fax_line_image_pixel_size) {
+ switch_channel_set_variable(channel, "fax_image_pixel_size", fax_line_image_pixel_size);;
}
- fax_image_pixel_size = switch_core_session_sprintf(session, "%ix%i", t30_stats.width, t30_stats.length);
- if (fax_image_pixel_size) {
- switch_channel_set_variable(channel, "fax_image_pixel_size", fax_image_pixel_size);;
+ fax_file_image_pixel_size = switch_core_session_sprintf(session, "%ix%i", t30_stats.image_width, t30_stats.image_length);
+ if (fax_file_image_pixel_size) {
+ switch_channel_set_variable(channel, "fax_file_image_pixel_size", fax_file_image_pixel_size);;
}
fax_image_size = switch_core_session_sprintf(session, "%d", t30_stats.image_size);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "==== Page %s===========================================================\n", pvt->app_mode == FUNCTION_TX ? "Sent ====": "Received ");
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Page no = %d\n", (pvt->app_mode == FUNCTION_TX) ? t30_stats.pages_tx : t30_stats.pages_rx);
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Image size = %d x %d pixels\n", t30_stats.width, t30_stats.length);
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Image resolution = %d/m x %d/m\n", t30_stats.x_resolution, t30_stats.y_resolution);
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Image type = %s (%s in the file)\n", t4_image_type_to_str(t30_stats.type), t4_image_type_to_str(t30_stats.image_type));
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Image size = %d x %d pixels (%d x %d pixels in the file)\n", t30_stats.width, t30_stats.length, t30_stats.image_width, t30_stats.image_length);
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Image resolution = %d/m x %d/m (%d/m x %d/m in the file)\n", t30_stats.x_resolution, t30_stats.y_resolution, t30_stats.image_x_resolution, t30_stats.image_y_resolution);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Compression = %s (%d)\n", t4_encoding_to_str(t30_stats.encoding), t30_stats.encoding);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Compressed image size = %d bytes\n", t30_stats.image_size);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Bad rows = %d\n", t30_stats.bad_rows);
if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, pvt->app_mode == FUNCTION_TX ? SPANDSP_EVENT_TXFAXPAGERESULT : SPANDSP_EVENT_RXFAXPAGERESULT) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "uuid", switch_core_session_get_uuid(session));
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-document-transferred-pages", fax_document_transferred_pages);
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-image-resolution", fax_image_resolution);
+ switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-image-resolution", fax_line_image_resolution);
+ switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-file-image-resolution", fax_file_image_resolution);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-image-size", fax_image_size);
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-image-pixel-size", fax_image_pixel_size);
+ switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-image-pixel-size", fax_line_image_pixel_size);
+ switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-file-image-pixel-size", fax_file_image_pixel_size);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-bad-rows", fax_bad_rows);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-longest-bad-row-run", fax_longest_bad_row_run);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-encoding", fax_encoding);