A cleanup of FAX image size/resolution matching accuracy. Squashing of bi-level

images should now be correct. This is now close to supporting grey scale and
colour.
This commit is contained in:
Steve Underwood
2013-08-06 02:38:06 +08:00
parent 13e8532398
commit df669f700a
12 changed files with 1860 additions and 766 deletions
+1 -1
View File
@@ -78,7 +78,7 @@ EXTRA_DIST = floating_fudge.h \
spandsp/private/README \
spandsp/version.h.in
INCLUDES = -I$(top_builddir)
AM_CPPFLAGS = -I$(top_builddir)
lib_LTLIBRARIES = libspandsp.la
-17
View File
@@ -323,12 +323,6 @@ SPAN_DECLARE(int) t4_tx_set_tx_image_format(t4_tx_state_t *s,
int supported_bilevel_resolutions,
int supported_colour_resolutions);
/*! \brief Set the compression for the encoded data.
\param s The T.4 context.
\param encoding The encoding.
\return 0 for success, otherwise -1. */
SPAN_DECLARE(int) t4_tx_set_tx_encoding(t4_tx_state_t *s, int encoding);
/*! \brief Set the minimum number of encoded bits per row. This allows the
makes the encoding process to be set to comply with the minimum row
time specified by a remote receiving machine.
@@ -336,11 +330,6 @@ SPAN_DECLARE(int) t4_tx_set_tx_encoding(t4_tx_state_t *s, int encoding);
\param bits The minimum number of bits per row. */
SPAN_DECLARE(void) t4_tx_set_min_bits_per_row(t4_tx_state_t *s, int bits);
/*! \brief Set the width of the image.
\param s The T.4 context.
\param image_width The image width, in pixels. */
SPAN_DECLARE(void) t4_tx_set_image_width(t4_tx_state_t *s, int image_width);
/*! \brief Set the maximum number of 2D encoded rows between 1D encoded rows. This
is only valid for T.4 2D encoding.
\param s The T.4 context.
@@ -381,12 +370,6 @@ SPAN_DECLARE(void) t4_tx_set_header_overlays_image(t4_tx_state_t *s, int header_
\return 0 for success, otherwise -1. */
SPAN_DECLARE(int) t4_tx_set_row_read_handler(t4_tx_state_t *s, t4_row_read_handler_t handler, void *user_data);
/*! \brief Set the row squashing ratio, for adjusting row-to-row (y) resolution of bi-level
images for a T.4 transmit context.
\param s The T.4 transmit context.
\param row_squashing_ratio Vertical squashing ratio. */
SPAN_DECLARE(void) t4_tx_set_row_squashing_ratio(t4_tx_state_t *s, int row_squashing_ratio);
/*! \brief Get the number of pages in the file.
\param s The T.4 context.
\return The number of pages, or -1 if there is an error. */
+146 -268
View File
@@ -1224,7 +1224,7 @@ int t30_build_dis_or_dtc(t30_state_t *s)
// set_ctrl_bit(s->local_dis_dtc_frame, T30_DIS_BIT_T88_CAPABILITY_3);
//}
//if ((s->supported_compressions & (T4_COMPRESSION_COLOUR | T4_COMPRESSION_GRAYSCALE)))
if ((s->supported_compressions & (T4_COMPRESSION_COLOUR | T4_COMPRESSION_GRAYSCALE)))
{
if ((s->supported_compressions & T4_COMPRESSION_COLOUR))
set_ctrl_bit(s->local_dis_dtc_frame, T30_DIS_BIT_FULL_COLOUR_CAPABLE);
@@ -1249,8 +1249,8 @@ int t30_build_dis_or_dtc(t30_state_t *s)
if ((s->supported_compressions & T4_COMPRESSION_12BIT))
set_ctrl_bit(s->local_dis_dtc_frame, T30_DIS_BIT_12BIT_CAPABLE);
//if ((s->supported_compressions & T4_COMPRESSION_NO_SUBSAMPLING))
// set_ctrl_bit(s->local_dis_dtc_frame, T30_DIS_BIT_NO_SUBSAMPLING);
if ((s->supported_compressions & T4_COMPRESSION_NO_SUBSAMPLING))
set_ctrl_bit(s->local_dis_dtc_frame, T30_DIS_BIT_NO_SUBSAMPLING);
/* No custom illuminant */
/* No custom gamut range */
@@ -1423,8 +1423,6 @@ static int prune_dis_dtc(t30_state_t *s)
static int build_dcs(t30_state_t *s)
{
int i;
int bad;
int row_squashing_ratio;
int use_bilevel;
int image_type;
@@ -1523,229 +1521,21 @@ static int build_dcs(t30_state_t *s)
break;
}
/* Set the Y resolution bits */
row_squashing_ratio = 1;
bad = T30_ERR_NORESSUPPORT;
if ((use_bilevel && (s->current_page_resolution & s->mutual_bilevel_resolutions))
||
(!use_bilevel && (s->current_page_resolution & s->mutual_colour_resolutions)))
{
/* The resolution is supported by both parties */
switch (s->current_page_resolution)
{
case T4_RESOLUTION_1200_1200:
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_1200_1200);
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_INCH_RESOLUTION);
if (!use_bilevel)
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_COLOUR_GRAY_1200_1200);
break;
case T4_RESOLUTION_600_1200:
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_600_1200);
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_INCH_RESOLUTION);
break;
case T4_RESOLUTION_600_600:
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_600_600);
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_INCH_RESOLUTION);
if (!use_bilevel)
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_COLOUR_GRAY_600_600);
break;
case T4_RESOLUTION_400_800:
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_400_800);
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_INCH_RESOLUTION);
break;
case T4_RESOLUTION_400_400:
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_400_400);
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_INCH_RESOLUTION);
if (!use_bilevel)
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_COLOUR_GRAY_300_300_400_400);
break;
case T4_RESOLUTION_300_600:
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_300_600);
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_INCH_RESOLUTION);
break;
case T4_RESOLUTION_300_300:
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_300_300);
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_INCH_RESOLUTION);
if (!use_bilevel)
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_COLOUR_GRAY_300_300_400_400);
break;
case T4_RESOLUTION_200_400:
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_200_400);
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_INCH_RESOLUTION);
break;
case T4_RESOLUTION_200_200:
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_200_200);
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_INCH_RESOLUTION);
if (!use_bilevel)
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_FULL_COLOUR_MODE);
break;
case T4_RESOLUTION_200_100:
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_INCH_RESOLUTION);
break;
case T4_RESOLUTION_100_100:
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_INCH_RESOLUTION);
if (!use_bilevel)
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_COLOUR_GRAY_100_100);
break;
case T4_RESOLUTION_R16_SUPERFINE:
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_400_400);
break;
case T4_RESOLUTION_R8_SUPERFINE:
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_200_400);
break;
case T4_RESOLUTION_R8_FINE:
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_200_200);
break;
case T4_RESOLUTION_R8_STANDARD:
/* Nothing special to set */
break;
}
bad = T30_ERR_OK;
}
else
{
#if 0
/* Deal with resolution fudging */
if ((s->current_page_resolution & (T4_RESOLUTION_R16_SUPERFINE | T4_RESOLUTION_R8_SUPERFINE | T4_RESOLUTION_R8_FINE | T4_RESOLUTION_R8_STANDARD)))
{
if ((s->mutual_bilevel_resolutions & (T4_RESOLUTION_400_400 | T4_RESOLUTION_200_400 | T4_RESOLUTION_200_200 | T4_RESOLUTION_200_100)))
{
/* Fudge between imperial and metric */
}
}
else if ((s->current_page_resolution & (T4_RESOLUTION_400_400 | T4_RESOLUTION_200_400 | T4_RESOLUTION_200_200 | T4_RESOLUTION_200_100))
{
if ((s->mutual_bilevel_resolutions & (T4_RESOLUTION_R16_SUPERFINE | T4_RESOLUTION_R8_SUPERFINE | T4_RESOLUTION_R8_FINE | T4_RESOLUTION_R8_STANDARD)))
{
/* Fudge between imperial and metric */
}
}
#endif
/* Deal with squashing options */
if ((s->current_page_resolution & T4_RESOLUTION_R8_SUPERFINE))
{
if ((s->mutual_bilevel_resolutions & T4_RESOLUTION_R8_FINE))
{
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_200_200);
row_squashing_ratio = 2;
bad = T30_ERR_OK;
}
else if ((s->mutual_bilevel_resolutions & T4_RESOLUTION_R8_STANDARD))
{
row_squashing_ratio = 4;
bad = T30_ERR_OK;
}
}
else if ((s->current_page_resolution & T4_RESOLUTION_R8_FINE) && (s->mutual_bilevel_resolutions & T4_RESOLUTION_R8_STANDARD))
{
row_squashing_ratio = 2;
bad = T30_ERR_OK;
}
else if ((s->current_page_resolution & T4_RESOLUTION_200_400))
{
if ((s->mutual_bilevel_resolutions & T4_RESOLUTION_200_200))
{
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_200_200);
row_squashing_ratio = 2;
bad = T30_ERR_OK;
}
else if ((s->mutual_bilevel_resolutions & T4_RESOLUTION_200_100))
{
row_squashing_ratio = 4;
bad = T30_ERR_OK;
}
}
else if ((s->current_page_resolution & T4_RESOLUTION_200_200) && (s->mutual_bilevel_resolutions & T4_RESOLUTION_200_100))
{
row_squashing_ratio = 2;
bad = T30_ERR_OK;
}
}
t4_tx_set_row_squashing_ratio(&s->t4.tx, row_squashing_ratio);
if (bad != T30_ERR_OK)
{
t30_set_status(s, bad);
span_log(&s->logging, SPAN_LOG_FLOW, "Image resolution (%d x %d) not acceptable\n", s->x_resolution, s->y_resolution);
return -1;
}
/* Deal with the image width. */
/* Low (R4) res widths are not supported in recent versions of T.30 */
bad = T30_ERR_OK;
/* The following treats a width field of 11 like 10, which does what note 6 of Table 2/T.30
says we should do with the invalid value 11. */
if (((s->image_width == T4_WIDTH_200_A4) && (s->x_resolution == T4_X_RESOLUTION_200 || s->x_resolution == T4_X_RESOLUTION_R8))
||
((s->image_width == T4_WIDTH_300_A4) && (s->x_resolution == T4_X_RESOLUTION_300))
||
((s->image_width == T4_WIDTH_400_A4) && (s->x_resolution == T4_X_RESOLUTION_400 || s->x_resolution == T4_X_RESOLUTION_R16))
||
((s->image_width == T4_WIDTH_600_A4) && (s->x_resolution == T4_X_RESOLUTION_600))
||
((s->image_width == T4_WIDTH_1200_A4) && (s->x_resolution == T4_X_RESOLUTION_1200)))
/* Set the image width */
switch (s->line_width_code)
{
case T4_SUPPORT_WIDTH_215MM:
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))
||
((s->image_width == T4_WIDTH_300_B4) && (s->x_resolution == T4_X_RESOLUTION_300))
||
((s->image_width == T4_WIDTH_400_B4) && (s->x_resolution == T4_X_RESOLUTION_400 || s->x_resolution == T4_X_RESOLUTION_R16))
||
((s->image_width == T4_WIDTH_600_B4) && (s->x_resolution == T4_X_RESOLUTION_600))
||
((s->image_width == T4_WIDTH_1200_B4) && (s->x_resolution == T4_X_RESOLUTION_1200)))
{
if ((s->mutual_image_sizes & T4_SUPPORT_WIDTH_255MM))
{
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
{
/* We do not support this width and resolution combination */
bad = T30_ERR_NOSIZESUPPORT;
}
}
else if (((s->image_width == T4_WIDTH_200_A3) && (s->x_resolution == T4_X_RESOLUTION_200 || s->x_resolution == T4_X_RESOLUTION_R8))
||
((s->image_width == T4_WIDTH_300_A3) && (s->x_resolution == T4_X_RESOLUTION_300))
||
((s->image_width == T4_WIDTH_400_A3) && (s->x_resolution == T4_X_RESOLUTION_400 || s->x_resolution == T4_X_RESOLUTION_R16))
||
((s->image_width == T4_WIDTH_600_A3) && (s->x_resolution == T4_X_RESOLUTION_600))
||
((s->image_width == T4_WIDTH_1200_A3) && (s->x_resolution == T4_X_RESOLUTION_1200)))
{
if ((s->mutual_image_sizes & T4_SUPPORT_WIDTH_303MM))
{
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
{
/* We do not support this width and resolution combination */
bad = T30_ERR_NOSIZESUPPORT;
}
}
else
{
/* We do not support this width and resolution combination */
bad = T30_ERR_NOSIZESUPPORT;
}
if (bad != T30_ERR_OK)
{
t30_set_status(s, bad);
span_log(&s->logging,
SPAN_LOG_FLOW,
"Image width (%d pixels) and resolution (%d x %d) is not an acceptable\n",
s->image_width,
s->x_resolution,
s->y_resolution);
return -1;
break;
case T4_SUPPORT_WIDTH_255MM:
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_255MM_WIDTH);
span_log(&s->logging, SPAN_LOG_FLOW, "Image width is B4 at %ddpm x %ddpm\n", s->x_resolution, s->y_resolution);
break;
case T4_SUPPORT_WIDTH_303MM:
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_303MM_WIDTH);
span_log(&s->logging, SPAN_LOG_FLOW, "Image width is A3 at %ddpm x %ddpm\n", s->x_resolution, s->y_resolution);
break;
}
/* Set the image length */
@@ -1760,6 +1550,77 @@ static int build_dcs(t30_state_t *s)
else if ((s->mutual_image_sizes & T4_SUPPORT_LENGTH_US_LEGAL))
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_NORTH_AMERICAN_LEGAL);
/* Set the Y resolution bits */
switch (s->current_page_resolution)
{
case T4_RESOLUTION_1200_1200:
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_1200_1200);
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_INCH_RESOLUTION);
if (!use_bilevel)
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_COLOUR_GRAY_1200_1200);
break;
case T4_RESOLUTION_600_1200:
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_600_1200);
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_INCH_RESOLUTION);
break;
case T4_RESOLUTION_600_600:
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_600_600);
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_INCH_RESOLUTION);
if (!use_bilevel)
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_COLOUR_GRAY_600_600);
break;
case T4_RESOLUTION_400_800:
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_400_800);
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_INCH_RESOLUTION);
break;
case T4_RESOLUTION_400_400:
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_400_400);
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_INCH_RESOLUTION);
if (!use_bilevel)
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_COLOUR_GRAY_300_300_400_400);
break;
case T4_RESOLUTION_300_600:
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_300_600);
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_INCH_RESOLUTION);
break;
case T4_RESOLUTION_300_300:
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_300_300);
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_INCH_RESOLUTION);
if (!use_bilevel)
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_COLOUR_GRAY_300_300_400_400);
break;
case T4_RESOLUTION_200_400:
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_200_400);
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_INCH_RESOLUTION);
break;
case T4_RESOLUTION_200_200:
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_200_200);
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_INCH_RESOLUTION);
if (!use_bilevel)
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_FULL_COLOUR_MODE);
break;
case T4_RESOLUTION_200_100:
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_INCH_RESOLUTION);
break;
case T4_RESOLUTION_100_100:
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_INCH_RESOLUTION);
if (!use_bilevel)
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_COLOUR_GRAY_100_100);
break;
case T4_RESOLUTION_R16_SUPERFINE:
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_400_400);
break;
case T4_RESOLUTION_R8_SUPERFINE:
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_200_400);
break;
case T4_RESOLUTION_R8_FINE:
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_200_200);
break;
case T4_RESOLUTION_R8_STANDARD:
/* Nothing special to set */
break;
}
if (s->error_correcting_mode)
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_ECM_MODE);
@@ -1832,7 +1693,7 @@ static int analyze_rx_dis_dtc(t30_state_t *s, const uint8_t *msg, int len)
if (!s->error_correcting_mode)
{
/* Remove any compression schemes which need error correction to work. */
s->mutual_compressions &= (0xF0000000 | T4_COMPRESSION_NONE | T4_COMPRESSION_T4_1D | T4_COMPRESSION_T4_2D);
s->mutual_compressions &= (0xFF800000 | T4_COMPRESSION_NONE | T4_COMPRESSION_T4_1D | T4_COMPRESSION_T4_2D);
if (!test_ctrl_bit(s->far_dis_dtc_frame, T30_DIS_BIT_2D_CAPABLE))
s->mutual_compressions &= ~T4_COMPRESSION_T4_2D;
}
@@ -1866,8 +1727,8 @@ static int analyze_rx_dis_dtc(t30_state_t *s, const uint8_t *msg, int len)
if (!test_ctrl_bit(s->far_dis_dtc_frame, T30_DIS_BIT_12BIT_CAPABLE))
s->mutual_compressions &= ~T4_COMPRESSION_12BIT;
//if (!test_ctrl_bit(s->far_dis_dtc_frame, T30_DIS_BIT_NO_SUBSAMPLING))
// ???? = T4_COMPRESSION_T42_T81_SUBSAMPLING;
if (!test_ctrl_bit(s->far_dis_dtc_frame, T30_DIS_BIT_NO_SUBSAMPLING))
s->mutual_compressions &= ~T4_COMPRESSION_NO_SUBSAMPLING;
/* bit74 custom illuminant */
/* bit75 custom gamut range */
@@ -2087,7 +1948,7 @@ static int analyze_rx_dcs(t30_state_t *s, const uint8_t *msg, int len)
if (test_ctrl_bit(dcs_frame, T30_DCS_BIT_NO_SUBSAMPLING))
{
//???? = T4_COMPRESSION_T42_T81_SUBSAMPLING;
//???? = T4_COMPRESSION_NO_SUBSAMPLING;
}
if (!test_ctrl_bit(dcs_frame, T30_DCS_BIT_PREFERRED_HUFFMAN_TABLES))
@@ -2529,7 +2390,6 @@ static int send_dcs_sequence(t30_state_t *s, int start)
/* Schedule training after the messages */
if (start)
{
prune_dcs(s);
set_state(s, T30_STATE_D);
s->step = 0;
}
@@ -2654,22 +2514,12 @@ static void set_min_scan_time(t30_state_t *s)
{
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];
break;
}
span_log(&s->logging, SPAN_LOG_FLOW, "Remote FAX does not support super-fine resolution. Squashing image.\n");
/* Fall through */
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];
break;
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];
break;
}
span_log(&s->logging, SPAN_LOG_FLOW, "Remote FAX does not support fine resolution. Squashing image.\n");
/* Fall through */
s->min_scan_time_code = translate_min_scan_time[1][min_bits_field];
break;
case T4_Y_RESOLUTION_STANDARD:
case T4_Y_RESOLUTION_100:
s->min_scan_time_code = translate_min_scan_time[0][min_bits_field];
@@ -2689,6 +2539,8 @@ static void set_min_scan_time(t30_state_t *s)
static int start_sending_document(t30_state_t *s)
{
int res;
if (s->tx_file[0] == '\0')
{
/* There is nothing to send */
@@ -2703,27 +2555,68 @@ static int start_sending_document(t30_state_t *s)
return -1;
}
s->operation_in_progress = OPERATION_IN_PROGRESS_T4_TX;
t4_tx_get_pages_in_file(&s->t4.tx);
t4_tx_set_tx_encoding(&s->t4.tx, s->line_compression);
t4_tx_set_local_ident(&s->t4.tx, s->tx_info.ident);
t4_tx_set_header_info(&s->t4.tx, s->header_info);
if (s->use_own_tz)
t4_tx_set_header_tz(&s->t4.tx, &s->tz);
if (tx_start_page(s))
t4_tx_get_pages_in_file(&s->t4.tx);
if ((res = t4_tx_set_tx_image_format(&s->t4.tx,
s->mutual_compressions,
s->mutual_image_sizes,
s->mutual_bilevel_resolutions,
s->mutual_colour_resolutions)) < 0)
{
span_log(&s->logging, SPAN_LOG_WARNING, "Something seems to be wrong in the file\n");
t30_set_status(s, T30_ERR_FILEERROR);
switch (res)
{
case T4_IMAGE_FORMAT_INCOMPATIBLE:
span_log(&s->logging, SPAN_LOG_WARNING, "Cannot negotiate an image format\n");
t30_set_status(s, T30_ERR_BADTIFFHDR);
break;
case T4_IMAGE_FORMAT_NOSIZESUPPORT:
span_log(&s->logging, SPAN_LOG_WARNING, "Cannot negotiate an image size\n");
t30_set_status(s, T30_ERR_NOSIZESUPPORT);
break;
case T4_IMAGE_FORMAT_NORESSUPPORT:
span_log(&s->logging, SPAN_LOG_WARNING, "Cannot negotiate an image resolution\n");
t30_set_status(s, T30_ERR_NORESSUPPORT);
break;
default:
span_log(&s->logging, SPAN_LOG_WARNING, "Cannot negotiate an image format\n");
t30_set_status(s, T30_ERR_BADTIFF);
break;
}
return -1;
}
s->line_image_type = t4_tx_get_tx_image_type(&s->t4.tx);
s->line_compression = t4_tx_get_tx_compression(&s->t4.tx);
s->image_width = t4_tx_get_tx_image_width(&s->t4.tx);
s->line_width_code = t4_tx_get_tx_image_width_code(&s->t4.tx);
s->x_resolution = t4_tx_get_tx_x_resolution(&s->t4.tx);
s->y_resolution = t4_tx_get_tx_y_resolution(&s->t4.tx);
s->image_width = t4_tx_get_tx_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. */
s->current_page_resolution = t4_tx_get_tx_resolution(&s->t4.tx);
span_log(&s->logging,
SPAN_LOG_FLOW,
"Choose image type %s (%d), compression %s (%d)\n",
t4_image_type_to_str(s->line_image_type),
s->line_image_type,
t4_compression_to_str(s->line_compression),
s->line_compression);
/* The minimum scan time to be used can't be evaluated until we know the Y resolution. */
set_min_scan_time(s);
if (tx_start_page(s))
{
span_log(&s->logging, SPAN_LOG_WARNING, "Something seems to be wrong in the file\n");
t30_set_status(s, T30_ERR_BADTIFFHDR);
return -1;
}
if (s->error_correcting_mode)
{
if (get_partial_ecm_page(s) == 0)
@@ -2795,21 +2688,6 @@ static int process_rx_dis_dtc(t30_state_t *s, const uint8_t *msg, int len)
send_dcn(s);
return -1;
}
/* Choose a compression scheme from amongst those mutually available */
if ((s->mutual_compressions & T4_COMPRESSION_T85_L0))
s->line_compression = T4_COMPRESSION_T85_L0;
else if ((s->mutual_compressions & T4_COMPRESSION_T85))
s->line_compression = T4_COMPRESSION_T85;
else if ((s->mutual_compressions & T4_COMPRESSION_T6))
s->line_compression = T4_COMPRESSION_T6;
else if ((s->mutual_compressions & T4_COMPRESSION_T4_2D))
s->line_compression = T4_COMPRESSION_T4_2D;
else
s->line_compression = T4_COMPRESSION_T4_1D;
span_log(&s->logging, SPAN_LOG_FLOW, "Choose compression %s (%d)\n", t4_compression_to_str(s->line_compression), s->line_compression);
if (s->phase_b_handler)
{
new_status = s->phase_b_handler(s, s->phase_b_user_data, msg[2]);
@@ -6825,7 +6703,7 @@ SPAN_DECLARE(t30_state_t *) t30_init(t30_state_t *s,
| T4_SUPPORT_LENGTH_UNLIMITED;
/* Set the output encoding to something safe. Most things get 1D and 2D
encoding right. Quite a lot get other things wrong. */
s->supported_output_compressions = T4_COMPRESSION_T4_2D;
s->supported_output_compressions = T4_COMPRESSION_T4_2D | T4_COMPRESSION_T42_T81;
s->local_min_scan_time_code = T30_MIN_SCAN_0MS;
span_log_init(&s->logging, SPAN_LOG_NONE, NULL);
span_log_set_protocol(&s->logging, "T.30");
+160 -94
View File
@@ -234,11 +234,24 @@ static int set_tiff_directory_info(t4_rx_state_t *s)
#endif
#if defined(SPANDSP_SUPPORT_T42)
case T4_COMPRESSION_T42_T81:
output_compression = COMPRESSION_JPEG;
bits_per_sample = 8;
if (t->image_type == T4_IMAGE_TYPE_COLOUR_8BIT)
{
samples_per_pixel = 3;
photometric = PHOTOMETRIC_YCBCR; //PHOTOMETRIC_ITULAB;
}
else
{
samples_per_pixel = 1;
photometric = PHOTOMETRIC_MINISBLACK;
}
break;
case T4_COMPRESSION_SYCC_T81:
output_compression = COMPRESSION_JPEG;
bits_per_sample = 8;
samples_per_pixel = 3;
photometric = PHOTOMETRIC_ITULAB;
photometric = PHOTOMETRIC_YCBCR;
break;
#endif
#if defined(SPANDSP_SUPPORT_T43)
@@ -288,6 +301,13 @@ static int set_tiff_directory_info(t4_rx_state_t *s)
TIFFSetField(t->tiff_file, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
TIFFSetField(t->tiff_file, TIFFTAG_PHOTOMETRIC, photometric);
TIFFSetField(t->tiff_file, TIFFTAG_FILLORDER, FILLORDER_LSB2MSB);
if (t->compression == T4_COMPRESSION_T42_T81)
{
TIFFSetField(t->tiff_file, TIFFTAG_YCBCRSUBSAMPLING, 2, 2);
//TIFFSetField(t->tiff_file, TIFFTAG_YCBCRSUBSAMPLING, 1, 1);
TIFFSetField(t->tiff_file, TIFFTAG_JPEGQUALITY, 75);
TIFFSetField(t->tiff_file, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB);
}
/* TIFFTAG_STRIPBYTECOUNTS and TIFFTAG_STRIPOFFSETS are added automatically */
x_resolution = s->metadata.x_resolution/100.0f;
@@ -344,30 +364,32 @@ static int set_tiff_directory_info(t4_rx_state_t *s)
is always one greater than the highest page number in the file. */
s->tiff.pages_in_file = s->current_page + 1;
s->metadata.image_length = 0;
switch (s->metadata.compression)
switch (s->current_decoder)
{
case T4_COMPRESSION_T4_1D:
case T4_COMPRESSION_T4_2D:
/* We only get bad row info from pages received in non-ECM mode. */
if (output_compression == COMPRESSION_CCITT_T4)
case 0:
s->metadata.image_length = 1024;
break;
case T4_COMPRESSION_T4_1D | T4_COMPRESSION_T4_2D | T4_COMPRESSION_T6:
if ((s->metadata.compression & (T4_COMPRESSION_T4_1D | T4_COMPRESSION_T4_2D)))
{
if (s->decoder.t4_t6.bad_rows)
/* We only get bad row info from pages received in non-ECM mode. */
if (output_compression == COMPRESSION_CCITT_T4)
{
TIFFSetField(t->tiff_file, TIFFTAG_BADFAXLINES, s->decoder.t4_t6.bad_rows);
TIFFSetField(t->tiff_file, TIFFTAG_CONSECUTIVEBADFAXLINES, s->decoder.t4_t6.longest_bad_row_run);
TIFFSetField(t->tiff_file, TIFFTAG_CLEANFAXDATA, CLEANFAXDATA_REGENERATED);
}
else
{
TIFFSetField(t->tiff_file, TIFFTAG_CLEANFAXDATA, CLEANFAXDATA_CLEAN);
if (s->decoder.t4_t6.bad_rows)
{
TIFFSetField(t->tiff_file, TIFFTAG_BADFAXLINES, s->decoder.t4_t6.bad_rows);
TIFFSetField(t->tiff_file, TIFFTAG_CONSECUTIVEBADFAXLINES, s->decoder.t4_t6.longest_bad_row_run);
TIFFSetField(t->tiff_file, TIFFTAG_CLEANFAXDATA, CLEANFAXDATA_REGENERATED);
}
else
{
TIFFSetField(t->tiff_file, TIFFTAG_CLEANFAXDATA, CLEANFAXDATA_CLEAN);
}
}
}
/* Fall through */
case T4_COMPRESSION_T6:
s->metadata.image_length = t4_t6_decode_get_image_length(&s->decoder.t4_t6);
break;
case T4_COMPRESSION_T85:
case T4_COMPRESSION_T85_L0:
case T4_COMPRESSION_T85 | T4_COMPRESSION_T85_L0:
s->metadata.image_length = t85_decode_get_image_length(&s->decoder.t85);
break;
#if defined(SPANDSP_SUPPORT_T88)
@@ -401,6 +423,34 @@ static int set_tiff_directory_info(t4_rx_state_t *s)
/* Create a placeholder for the global parameters IFD, to be filled in later */
TIFFSetField(t->tiff_file, TIFFTAG_GLOBALPARAMETERSIFD, 0);
}
#if 0
/* Paletised image? */
TIFFSetField(t->tiff_file, TIFFTAG_INDEXED, 1);
/* T.44 mode */
TIFFSetField(t->tiff_file, TIFFTAG_MODENUMBER, 0);
span_log(&s->logging, SPAN_LOG_FLOW, "TIFF/FX stuff 2\n");
{
float xxx[] = {20.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0, 90.0};
TIFFSetField(t->tiff_file, TIFFTAG_DECODE, (uint16) 2*samples_per_pixel, xxx);
}
span_log(&s->logging, SPAN_LOG_FLOW, "TIFF/FX stuff 3\n");
{
uint16_t xxx[] = {12, 34, 45, 67};
TIFFSetField(t->tiff_file, TIFFTAG_IMAGEBASECOLOR, (uint16_t) samples_per_pixel, xxx);
}
span_log(&s->logging, SPAN_LOG_FLOW, "TIFF/FX stuff 4\n");
TIFFSetField(t->tiff_file, TIFFTAG_T82OPTIONS, 0);
{
uint32_t xxx[] = {34, 56, 78, 90};
TIFFSetField(t->tiff_file, TIFFTAG_STRIPROWCOUNTS, (uint16_t) 5, xxx);
}
span_log(&s->logging, SPAN_LOG_FLOW, "TIFF/FX stuff 5\n");
{
uint32_t xxx[] = {2, 3};
TIFFSetField(t->tiff_file, TIFFTAG_IMAGELAYER, xxx);
}
#endif
#endif
return 0;
}
@@ -450,10 +500,10 @@ static int write_tiff_t85_image(t4_rx_state_t *s)
if (buf_len < image_len + 65536)
{
buf_len += 65536;
if ((buf2 = realloc(buf, buf_len)) == NULL)
if ((buf2 = span_realloc(buf, buf_len)) == NULL)
{
if (buf)
free(buf);
span_free(buf);
return -1;
}
buf = buf2;
@@ -468,7 +518,7 @@ static int write_tiff_t85_image(t4_rx_state_t *s)
return -1;
}
t85_encode_release(&t85);
free(buf);
span_free(buf);
return 0;
}
/*- End of function --------------------------------------------------------*/
@@ -496,10 +546,10 @@ static int write_tiff_t43_image(t4_rx_state_t *s)
if (buf_len < image_len + 65536)
{
buf_len += 65536;
if ((buf2 = realloc(buf, buf_len)) == NULL)
if ((buf2 = span_realloc(buf, buf_len)) == NULL)
{
if (buf)
free(buf);
span_free(buf);
return -1;
}
buf = buf2;
@@ -511,7 +561,7 @@ static int write_tiff_t43_image(t4_rx_state_t *s)
if (TIFFWriteRawStrip(s->tiff.tiff_file, 0, buf, image_len) < 0)
span_log(&s->logging, SPAN_LOG_WARNING, "%s: Error writing TIFF strip.\n", s->tiff.file);
t43_encode_release(&t43);
free(buf);
span_free(buf);
return 0;
}
/*- End of function --------------------------------------------------------*/
@@ -525,49 +575,57 @@ static int write_tiff_image(t4_rx_state_t *s)
#endif
t = &s->tiff;
if (t->image_buffer == NULL || t->image_size <= 0)
if (s->pre_encoded_ptr <= 0 && (t->image_buffer == NULL || t->image_size <= 0))
return -1;
/* Set up the TIFF directory info... */
set_tiff_directory_info(s);
/* ...Put the directory in the file before the image data, to get them in the order specified
for TIFF/F files... */
if (!TIFFCheckpointDirectory(t->tiff_file))
span_log(&s->logging, SPAN_LOG_WARNING, "%s: Failed to checkpoint directory for page %d.\n", t->file, s->current_page);
//if (!TIFFCheckpointDirectory(t->tiff_file))
// span_log(&s->logging, SPAN_LOG_WARNING, "%s: Failed to checkpoint directory for page %d.\n", t->file, s->current_page);
/* ...and write out the image... */
switch (t->compression)
if (s->pre_encoded_ptr > 0)
{
case T4_COMPRESSION_T85:
case T4_COMPRESSION_T85_L0:
/* We need to perform this compression here, as libtiff does not understand it. */
if (write_tiff_t85_image(s) < 0)
return -1;
break;
if (TIFFWriteRawStrip(s->tiff.tiff_file, 0, s->pre_encoded_buf, s->pre_encoded_ptr) < 0)
span_log(&s->logging, SPAN_LOG_WARNING, "%s: Error writing TIFF strip.\n", s->tiff.file);
}
else
{
switch (t->compression)
{
case T4_COMPRESSION_T85:
case T4_COMPRESSION_T85_L0:
/* We need to perform this compression here, as libtiff does not understand it. */
if (write_tiff_t85_image(s) < 0)
return -1;
break;
#if defined(SPANDSP_SUPPORT_T88)
case T4_COMPRESSION_T88:
/* We need to perform this compression here, as libtiff does not understand it. */
if (write_tiff_t88_image(s) < 0)
return -1;
break;
case T4_COMPRESSION_T88:
/* We need to perform this compression here, as libtiff does not understand it. */
if (write_tiff_t88_image(s) < 0)
return -1;
break;
#endif
#if defined(SPANDSP_SUPPORT_T43)
case T4_COMPRESSION_T43:
/* We need to perform this compression here, as libtiff does not understand it. */
if (write_tiff_t43_image(s) < 0)
return -1;
break;
case T4_COMPRESSION_T43:
/* We need to perform this compression here, as libtiff does not understand it. */
if (write_tiff_t43_image(s) < 0)
return -1;
break;
#endif
#if defined(SPANDSP_SUPPORT_T45)
case T4_COMPRESSION_T45:
/* We need to perform this compression here, as libtiff does not understand it. */
if (write_tiff_t45_image(s) < 0)
return -1;
break;
case T4_COMPRESSION_T45:
/* We need to perform this compression here, as libtiff does not understand it. */
if (write_tiff_t45_image(s) < 0)
return -1;
break;
#endif
default:
/* Let libtiff do the compression */
if (TIFFWriteEncodedStrip(t->tiff_file, 0, t->image_buffer, t->image_size) < 0)
span_log(&s->logging, SPAN_LOG_WARNING, "%s: Error writing TIFF strip.\n", t->file);
break;
default:
/* Let libtiff do the compression */
if (TIFFWriteEncodedStrip(t->tiff_file, 0, t->image_buffer, t->image_size) < 0)
span_log(&s->logging, SPAN_LOG_WARNING, "%s: Error writing TIFF strip.\n", t->file);
break;
}
}
/* ...then finalise the directory entry, and libtiff is happy. */
if (!TIFFWriteDirectory(t->tiff_file))
@@ -633,7 +691,7 @@ static int close_tiff_output_file(t4_rx_state_t *s)
put in it. */
if (s->current_page == 0)
remove(s->tiff.file);
free((char *) s->tiff.file);
span_free((char *) s->tiff.file);
}
s->tiff.file = NULL;
return 0;
@@ -646,7 +704,7 @@ static void tiff_rx_release(t4_rx_state_t *s)
close_tiff_output_file(s);
if (s->tiff.image_buffer)
{
free(s->tiff.image_buffer);
span_free(s->tiff.image_buffer);
s->tiff.image_buffer = NULL;
s->tiff.image_size = 0;
s->tiff.image_buffer_size = 0;
@@ -673,10 +731,10 @@ SPAN_DECLARE(int) t4_rx_put(t4_rx_state_t *s, const uint8_t buf[], size_t len)
if (s->pre_encoded_len < s->pre_encoded_ptr + 65536)
{
s->pre_encoded_len += 65536;
if ((buf2 = realloc(s->pre_encoded_buf, s->pre_encoded_len)) == NULL)
if ((buf2 = span_realloc(s->pre_encoded_buf, s->pre_encoded_len)) == NULL)
{
if (s->pre_encoded_buf)
free(s->pre_encoded_buf);
span_free(s->pre_encoded_buf);
return -1;
}
s->pre_encoded_buf = buf2;
@@ -757,11 +815,19 @@ static void select_tiff_compression(t4_rx_state_t *s, int output_image_type)
else if ((s->supported_tiff_compressions & T4_COMPRESSION_T43))
s->tiff.compression = T4_COMPRESSION_T43;
}
s->tiff.image_type = output_image_type;
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(int) t4_rx_set_rx_encoding(t4_rx_state_t *s, int compression)
{
#if 0
output_image_type = T4_IMAGE_TYPE_BILEVEL;
s->metadata.compression = compression;
select_tiff_compression(s, T4_IMAGE_TYPE_BILEVEL);
s->current_decoder = 0;
return 0;
#else
switch (compression)
{
case T4_COMPRESSION_T4_1D:
@@ -775,6 +841,7 @@ SPAN_DECLARE(int) t4_rx_set_rx_encoding(t4_rx_state_t *s, int compression)
break;
default:
t4_t6_decode_init(&s->decoder.t4_t6, compression, s->metadata.image_width, s->row_handler, s->row_handler_user_data);
s->current_decoder = T4_COMPRESSION_T4_1D | T4_COMPRESSION_T4_2D | T4_COMPRESSION_T6;
break;
}
s->metadata.compression = compression;
@@ -789,14 +856,15 @@ SPAN_DECLARE(int) t4_rx_set_rx_encoding(t4_rx_state_t *s, int compression)
break;
default:
t85_decode_init(&s->decoder.t85, s->row_handler, s->row_handler_user_data);
s->current_decoder = T4_COMPRESSION_T85 | T4_COMPRESSION_T85_L0;
/* Constrain received images to the maximum width of any FAX. This will
avoid one potential cause of trouble, where a bad received image has
a gigantic dimension that sucks our memory dry. */
t85_decode_set_image_size_constraints(&s->decoder.t85, T4_WIDTH_1200_A3, 0);
break;
}
select_tiff_compression(s, T4_IMAGE_TYPE_BILEVEL);
s->metadata.compression = compression;
select_tiff_compression(s, T4_IMAGE_TYPE_BILEVEL);
return 0;
#if defined(SPANDSP_SUPPORT_T88)
case T4_COMPRESSION_T88:
@@ -805,10 +873,12 @@ SPAN_DECLARE(int) t4_rx_set_rx_encoding(t4_rx_state_t *s, int compression)
case T4_COMPRESSION_T88:
break;
default:
t88_decode_init(&s->decoder.t88, s->row_handler, s->row_handler_user_data);
s->current_decoder = T4_COMPRESSION_T88;
break;
}
select_tiff_compression(s, T4_IMAGE_TYPE_BILEVEL);
s->metadata.compression = compression;
select_tiff_compression(s, T4_IMAGE_TYPE_BILEVEL);
return 0;
#endif
case T4_COMPRESSION_T42_T81:
@@ -820,6 +890,7 @@ SPAN_DECLARE(int) t4_rx_set_rx_encoding(t4_rx_state_t *s, int compression)
break;
default:
t42_decode_init(&s->decoder.t42, s->row_handler, s->row_handler_user_data);
s->current_decoder = T4_COMPRESSION_T42_T81;
/* Constrain received images to the maximum width of any FAX. This will
avoid one potential cause of trouble, where a bad received image has
a gigantic dimension that sucks our memory dry. */
@@ -837,6 +908,7 @@ SPAN_DECLARE(int) t4_rx_set_rx_encoding(t4_rx_state_t *s, int compression)
break;
default:
t43_decode_init(&s->decoder.t43, s->row_handler, s->row_handler_user_data);
s->current_decoder = T4_COMPRESSION_T43;
/* Constrain received images to the maximum width of any FAX. This will
avoid one potential cause of trouble, where a bad received image has
a gigantic dimension that sucks our memory dry. */
@@ -854,6 +926,8 @@ SPAN_DECLARE(int) t4_rx_set_rx_encoding(t4_rx_state_t *s, int compression)
case T4_COMPRESSION_T45:
break;
default:
t45_decode_init(&s->decoder.t45, s->row_handler, s->row_handler_user_data);
s->current_decoder = T4_COMPRESSION_T45;
break;
}
s->metadata.compression = compression;
@@ -863,6 +937,7 @@ SPAN_DECLARE(int) t4_rx_set_rx_encoding(t4_rx_state_t *s, int compression)
}
return -1;
#endif
}
/*- End of function --------------------------------------------------------*/
@@ -876,14 +951,11 @@ SPAN_DECLARE(int) t4_rx_set_row_write_handler(t4_rx_state_t *s, t4_row_write_han
{
s->row_handler = handler;
s->row_handler_user_data = user_data;
switch (s->metadata.compression)
switch (s->current_decoder)
{
case T4_COMPRESSION_T4_1D:
case T4_COMPRESSION_T4_2D:
case T4_COMPRESSION_T6:
case T4_COMPRESSION_T4_1D | T4_COMPRESSION_T4_2D | T4_COMPRESSION_T6:
return t4_t6_decode_set_row_write_handler(&s->decoder.t4_t6, handler, user_data);
case T4_COMPRESSION_T85:
case T4_COMPRESSION_T85_L0:
case T4_COMPRESSION_T85 | T4_COMPRESSION_T85_L0:
return t85_decode_set_row_write_handler(&s->decoder.t85, handler, user_data);
#if defined(SPANDSP_SUPPORT_T88)
case T4_COMPRESSION_T88:
@@ -914,12 +986,11 @@ SPAN_DECLARE(void) t4_rx_get_transfer_statistics(t4_rx_state_t *s, t4_stats_t *t
t->image_y_resolution = s->metadata.y_resolution;
t->x_resolution = s->metadata.x_resolution;
t->y_resolution = s->metadata.y_resolution;
t->compression = s->metadata.compression;
switch (s->metadata.compression)
switch (s->current_decoder)
{
case T4_COMPRESSION_T4_1D:
case T4_COMPRESSION_T4_2D:
case T4_COMPRESSION_T6:
case T4_COMPRESSION_T4_1D | T4_COMPRESSION_T4_2D | T4_COMPRESSION_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);
@@ -930,8 +1001,7 @@ SPAN_DECLARE(void) t4_rx_get_transfer_statistics(t4_rx_state_t *s, t4_stats_t *t
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_T85:
case T4_COMPRESSION_T85_L0:
case T4_COMPRESSION_T85 | T4_COMPRESSION_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);
@@ -945,7 +1015,7 @@ SPAN_DECLARE(void) t4_rx_get_transfer_statistics(t4_rx_state_t *s, t4_stats_t *t
break;
#endif
case T4_COMPRESSION_T42_T81:
t->type = T4_IMAGE_TYPE_COLOUR_8BIT; //T4_IMAGE_TYPE_GRAY_8BIT;
t->type = T4_IMAGE_TYPE_GRAY_8BIT; //T4_IMAGE_TYPE_COLOUR_8BIT;
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;
@@ -976,21 +1046,18 @@ SPAN_DECLARE(int) t4_rx_start_page(t4_rx_state_t *s)
{
span_log(&s->logging, SPAN_LOG_FLOW, "Start rx page %d - compression %s\n", s->current_page, t4_compression_to_str(s->metadata.compression));
switch (s->metadata.compression)
switch (s->current_decoder)
{
case 0:
s->pre_encoded_ptr = 0;
s->pre_encoded_len = 0;
s->image_put_handler = NULL;
break;
case T4_COMPRESSION_T4_1D:
case T4_COMPRESSION_T4_2D:
case T4_COMPRESSION_T6:
case T4_COMPRESSION_T4_1D | T4_COMPRESSION_T4_2D | T4_COMPRESSION_T6:
t4_t6_decode_restart(&s->decoder.t4_t6, s->metadata.image_width);
s->image_put_handler = (t4_image_put_handler_t) t4_t6_decode_put;
break;
case T4_COMPRESSION_T85:
case T4_COMPRESSION_T85_L0:
case T4_COMPRESSION_T85 | T4_COMPRESSION_T85_L0:
t85_decode_restart(&s->decoder.t85);
s->image_put_handler = (t4_image_put_handler_t) t85_decode_put;
break;
@@ -1036,7 +1103,7 @@ static int tiff_row_write_handler(void *user_data, const uint8_t buf[], size_t l
{
if (s->tiff.image_size + len >= s->tiff.image_buffer_size)
{
if ((t = realloc(s->tiff.image_buffer, s->tiff.image_buffer_size + 100*len)) == NULL)
if ((t = span_realloc(s->tiff.image_buffer, s->tiff.image_buffer_size + 100*len)) == NULL)
return -1;
s->tiff.image_buffer_size += 100*len;
s->tiff.image_buffer = t;
@@ -1057,15 +1124,15 @@ SPAN_DECLARE(int) t4_rx_end_page(t4_rx_state_t *s)
if (s->image_put_handler)
s->image_put_handler((void *) &s->decoder, NULL, 0);
switch (s->metadata.compression)
switch (s->current_decoder)
{
case T4_COMPRESSION_T4_1D:
case T4_COMPRESSION_T4_2D:
case T4_COMPRESSION_T6:
case 0:
length = s->pre_encoded_ptr;
break;
case T4_COMPRESSION_T4_1D | T4_COMPRESSION_T4_2D | T4_COMPRESSION_T6:
length = t4_t6_decode_get_image_length(&s->decoder.t4_t6);
break;
case T4_COMPRESSION_T85:
case T4_COMPRESSION_T85_L0:
case T4_COMPRESSION_T85 | T4_COMPRESSION_T85_L0:
length = t85_decode_get_image_length(&s->decoder.t85);
break;
#if defined(SPANDSP_SUPPORT_T88)
@@ -1100,6 +1167,7 @@ SPAN_DECLARE(int) t4_rx_end_page(t4_rx_state_t *s)
if (write_tiff_image(s) == 0)
s->current_page++;
s->tiff.image_size = 0;
s->pre_encoded_ptr = 0;
}
else
{
@@ -1142,6 +1210,7 @@ SPAN_DECLARE(t4_rx_state_t *) t4_rx_init(t4_rx_state_t *s, const char *file, int
s->metadata.y_resolution = T4_Y_RESOLUTION_FINE;
s->current_page = 0;
s->current_decoder = 0;
/* Default handler */
s->row_handler = tiff_row_write_handler;
@@ -1153,7 +1222,7 @@ SPAN_DECLARE(t4_rx_state_t *) t4_rx_init(t4_rx_state_t *s, const char *file, int
if (open_tiff_output_file(s, file) < 0)
{
if (allocated)
free(s);
span_free(s);
return NULL;
}
/* Save the file name for logging reports. */
@@ -1167,14 +1236,11 @@ SPAN_DECLARE(int) t4_rx_release(t4_rx_state_t *s)
{
if (s->tiff.file)
tiff_rx_release(s);
switch (s->metadata.compression)
switch (s->current_decoder)
{
case T4_COMPRESSION_T4_1D:
case T4_COMPRESSION_T4_2D:
case T4_COMPRESSION_T6:
case T4_COMPRESSION_T4_1D | T4_COMPRESSION_T4_2D | T4_COMPRESSION_T6:
return t4_t6_decode_release(&s->decoder.t4_t6);
case T4_COMPRESSION_T85:
case T4_COMPRESSION_T85_L0:
case T4_COMPRESSION_T85 | T4_COMPRESSION_T85_L0:
return t85_decode_release(&s->decoder.t85);
#if defined(SPANDSP_SUPPORT_T88)
case T4_COMPRESSION_T88:
@@ -1200,7 +1266,7 @@ SPAN_DECLARE(int) t4_rx_free(t4_rx_state_t *s)
int ret;
ret = t4_rx_release(s);
free(s);
span_free(s);
return ret;
}
/*- End of function --------------------------------------------------------*/
+1221 -236
View File
File diff suppressed because it is too large Load Diff