提交 e69a5a30 authored 作者: Steve Underwood's avatar Steve Underwood

Various little tweaks

A bug in end of image handling fixed, which could mean some T.85 images would
screw up.
上级 61839229
差异被折叠。
...@@ -163,9 +163,9 @@ static int image_gray16_to_colour16_row(uint16_t colour16[], uint16_t gray16[], ...@@ -163,9 +163,9 @@ static int image_gray16_to_colour16_row(uint16_t colour16[], uint16_t gray16[],
for (i = pixels - 1; i >= 0; i--) for (i = pixels - 1; i >= 0; i--)
{ {
colour16[3*i] = saturateu16((gray16[i]*36532) >> 15); colour16[3*i] = saturateu16((gray16[i]*36532U) >> 15);
colour16[3*i + 1] = saturateu16((gray16[i]*37216) >> 16); colour16[3*i + 1] = saturateu16((gray16[i]*37216U) >> 16);
colour16[3*i + 2] = saturateu16((gray16[i]*47900) >> 14); colour16[3*i + 2] = saturateu16((gray16[i]*47900U) >> 14);
} }
return pixels; return pixels;
} }
...@@ -177,9 +177,9 @@ static int image_gray16_to_colour8_row(uint8_t colour8[], uint16_t gray16[], int ...@@ -177,9 +177,9 @@ static int image_gray16_to_colour8_row(uint8_t colour8[], uint16_t gray16[], int
for (i = pixels - 1; i >= 0; i--) for (i = pixels - 1; i >= 0; i--)
{ {
colour8[3*i] = saturateu8((gray16[i]*36532) >> 23); colour8[3*i] = saturateu8((gray16[i]*36532U) >> 23);
colour8[3*i + 1] = saturateu8((gray16[i]*37216) >> 24); colour8[3*i + 1] = saturateu8((gray16[i]*37216U) >> 24);
colour8[3*i + 2] = saturateu8((gray16[i]*47900) >> 22); colour8[3*i + 2] = saturateu8((gray16[i]*47900U) >> 22);
} }
return pixels; return pixels;
} }
...@@ -557,6 +557,8 @@ SPAN_DECLARE(image_translate_state_t *) image_translate_init(image_translate_sta ...@@ -557,6 +557,8 @@ SPAN_DECLARE(image_translate_state_t *) image_translate_init(image_translate_sta
void *row_read_user_data) void *row_read_user_data)
{ {
int i; int i;
int raw_row_size;
int row_size;
if (s == NULL) if (s == NULL)
{ {
...@@ -624,25 +626,29 @@ SPAN_DECLARE(image_translate_state_t *) image_translate_init(image_translate_sta ...@@ -624,25 +626,29 @@ SPAN_DECLARE(image_translate_state_t *) image_translate_init(image_translate_sta
} }
/* Allocate the two row buffers we need, using the space requirements we now have */ /* Allocate the two row buffers we need, using the space requirements we now have */
raw_row_size = s->input_width*s->input_bytes_per_pixel;
row_size = s->output_width*s->output_bytes_per_pixel;
if (raw_row_size < row_size)
raw_row_size = row_size;
if (s->resize) if (s->resize)
{ {
for (i = 0; i < 2; i++) for (i = 0; i < 2; i++)
{ {
if ((s->raw_pixel_row[i] = (uint8_t *) malloc(s->input_width*s->input_bytes_per_pixel)) == NULL) if ((s->raw_pixel_row[i] = (uint8_t *) malloc(raw_row_size)) == NULL)
return NULL; return NULL;
memset(s->raw_pixel_row[i], 0, s->input_width*s->input_bytes_per_pixel); memset(s->raw_pixel_row[i], 0, raw_row_size);
if ((s->pixel_row[i] = (uint8_t *) malloc(s->output_width*sizeof(uint8_t))) == NULL) if ((s->pixel_row[i] = (uint8_t *) malloc(row_size)) == NULL)
return NULL; return NULL;
memset(s->pixel_row[i], 0, s->output_width*sizeof(uint8_t)); memset(s->pixel_row[i], 0, row_size);
} }
} }
else else
{ {
for (i = 0; i < 2; i++) for (i = 0; i < 2; i++)
{ {
if ((s->pixel_row[i] = (uint8_t *) malloc(s->output_width*s->input_bytes_per_pixel)) == NULL) if ((s->pixel_row[i] = (uint8_t *) malloc(raw_row_size)) == NULL)
return NULL; return NULL;
memset(s->pixel_row[i], 0, s->output_width*s->input_bytes_per_pixel); memset(s->pixel_row[i], 0, raw_row_size);
} }
} }
......
...@@ -81,6 +81,11 @@ SPAN_DECLARE(void) t42_encode_abort(t42_encode_state_t *s); ...@@ -81,6 +81,11 @@ SPAN_DECLARE(void) t42_encode_abort(t42_encode_state_t *s);
SPAN_DECLARE(void) t42_encode_comment(t42_encode_state_t *s, const uint8_t comment[], size_t len); SPAN_DECLARE(void) t42_encode_comment(t42_encode_state_t *s, const uint8_t comment[], size_t len);
/*! \brief Check if we are at the end of the current document page.
\param s The T.42 context.
\return 0 for more data to come. SIG_STATUS_END_OF_DATA for no more data. */
SPAN_DECLARE(int) t42_encode_check_if_complete(t42_encode_state_t *s);
SPAN_DECLARE(int) t42_encode_get_byte(t42_encode_state_t *s); SPAN_DECLARE(int) t42_encode_get_byte(t42_encode_state_t *s);
SPAN_DECLARE(int) t42_encode_get_chunk(t42_encode_state_t *s, uint8_t buf[], int max_len); SPAN_DECLARE(int) t42_encode_get_chunk(t42_encode_state_t *s, uint8_t buf[], int max_len);
......
...@@ -38,15 +38,13 @@ extern "C" { ...@@ -38,15 +38,13 @@ extern "C" {
moving forward in the buffer. The document will be padded for the moving forward in the buffer. The document will be padded for the
current minimum scan line time. current minimum scan line time.
\param s The T.4/T.6 context. \param s The T.4/T.6 context.
\return The next bit (i.e. 0 or 1). For the last bit of data, bit 1 is \return The next bit (i.e. 0 or 1). SIG_STATUS_END_OF_DATA for no more data. */
set (i.e. the returned value is 2 or 3). */
SPAN_DECLARE(int) t4_t6_encode_check_bit(t4_t6_encode_state_t *s); SPAN_DECLARE(int) t4_t6_encode_check_bit(t4_t6_encode_state_t *s);
/*! \brief Get the next bit of the current image. The image will /*! \brief Get the next bit of the current image. The image will
be padded for the current minimum scan line time. be padded for the current minimum scan line time.
\param s The T.4/T.6 context. \param s The T.4/T.6 context.
\return The next bit (i.e. 0 or 1). For the last bit of data, bit 1 is \return The next bit (i.e. 0 or 1). SIG_STATUS_END_OF_DATA for no more data. */
set (i.e. the returned value is 2 or 3). */
SPAN_DECLARE(int) t4_t6_encode_get_bit(t4_t6_encode_state_t *s); SPAN_DECLARE(int) t4_t6_encode_get_bit(t4_t6_encode_state_t *s);
/*! \brief Get the next byte of the current document page. The document will /*! \brief Get the next byte of the current document page. The document will
......
...@@ -253,15 +253,13 @@ SPAN_DECLARE(int) t4_tx_end_page(t4_tx_state_t *s); ...@@ -253,15 +253,13 @@ SPAN_DECLARE(int) t4_tx_end_page(t4_tx_state_t *s);
moving forward in the buffer. The document will be padded for the moving forward in the buffer. The document will be padded for the
current minimum scan line time. current minimum scan line time.
\param s The T.4 context. \param s The T.4 context.
\return The next bit (i.e. 0 or 1). For the last bit of data, bit 1 is \return The next bit (i.e. 0 or 1). SIG_STATUS_END_OF_DATA for no more data. */
set (i.e. the returned value is 2 or 3). */ SPAN_DECLARE(int) t4_tx_check_if_complete(t4_tx_state_t *s);
SPAN_DECLARE(int) t4_tx_check_bit(t4_tx_state_t *s);
/*! \brief Get the next bit of the current document page. The document will /*! \brief Get the next bit of the current document page. The document will
be padded for the current minimum scan line time. be padded for the current minimum scan line time.
\param s The T.4 context. \param s The T.4 context.
\return The next bit (i.e. 0 or 1). For the last bit of data, bit 1 is \return The next bit (i.e. 0 or 1). SIG_STATUS_END_OF_DATA for no more data. */
set (i.e. the returned value is 2 or 3). */
SPAN_DECLARE(int) t4_tx_get_bit(t4_tx_state_t *s); SPAN_DECLARE(int) t4_tx_get_bit(t4_tx_state_t *s);
/*! \brief Get the next byte of the current document page. The document will /*! \brief Get the next byte of the current document page. The document will
......
...@@ -64,8 +64,12 @@ extern "C" ...@@ -64,8 +64,12 @@ extern "C"
{ {
#endif #endif
/*! \brief Get the next byte of the current document page. The document will /*! \brief Check if we are at the end of the current document page.
be padded for the current minimum scan line time. \param s The T.85 context.
\return 0 for more data to come. SIG_STATUS_END_OF_DATA for no more data. */
SPAN_DECLARE(int) t85_encode_check_if_complete(t85_encode_state_t *s);
/*! \brief Get the next byte of the current document page.
\param s The T.85 context. \param s The T.85 context.
\return The next byte. For the last byte of data, bit 8 is \return The next byte. For the last byte of data, bit 8 is
set. In this case, one or more bits of the byte may be padded with set. In this case, one or more bits of the byte may be padded with
......
...@@ -748,7 +748,7 @@ static int get_partial_ecm_page(t30_state_t *s) ...@@ -748,7 +748,7 @@ static int get_partial_ecm_page(t30_state_t *s)
/* We filled the entire buffer */ /* We filled the entire buffer */
s->ecm_frames = 256; s->ecm_frames = 256;
span_log(&s->logging, SPAN_LOG_FLOW, "Partial page buffer full (%d per frame)\n", s->octets_per_ecm_frame); span_log(&s->logging, SPAN_LOG_FLOW, "Partial page buffer full (%d per frame)\n", s->octets_per_ecm_frame);
s->ecm_at_page_end = ((t4_tx_check_bit(&s->t4.tx) & 2) != 0); s->ecm_at_page_end = (t4_tx_check_if_complete(&s->t4.tx) == SIG_STATUS_END_OF_DATA);
return 256; return 256;
} }
/*- End of function --------------------------------------------------------*/ /*- End of function --------------------------------------------------------*/
...@@ -1332,12 +1332,10 @@ static int build_dcs(t30_state_t *s) ...@@ -1332,12 +1332,10 @@ static int build_dcs(t30_state_t *s)
/* Select the compression to use. */ /* Select the compression to use. */
switch (s->line_encoding) switch (s->line_encoding)
{ {
#if defined(SPANDSP_SUPPORT_T42)
case T4_COMPRESSION_ITU_T42: case T4_COMPRESSION_ITU_T42:
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_FULL_COLOUR_MODE); set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_FULL_COLOUR_MODE);
set_ctrl_bits(s->dcs_frame, T30_MIN_SCAN_0MS, 21); set_ctrl_bits(s->dcs_frame, T30_MIN_SCAN_0MS, 21);
break; break;
#endif
#if defined(SPANDSP_SUPPORT_T43) #if defined(SPANDSP_SUPPORT_T43)
case T4_COMPRESSION_ITU_T43: case T4_COMPRESSION_ITU_T43:
set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_T43_MODE); set_ctrl_bit(s->dcs_frame, T30_DCS_BIT_T43_MODE);
......
...@@ -697,9 +697,7 @@ SPAN_DECLARE(int) t30_set_supported_compressions(t30_state_t *s, int supported_c ...@@ -697,9 +697,7 @@ SPAN_DECLARE(int) t30_set_supported_compressions(t30_state_t *s, int supported_c
mask = T30_SUPPORT_T4_1D_COMPRESSION mask = T30_SUPPORT_T4_1D_COMPRESSION
| T30_SUPPORT_T4_2D_COMPRESSION | T30_SUPPORT_T4_2D_COMPRESSION
| T30_SUPPORT_T6_COMPRESSION | T30_SUPPORT_T6_COMPRESSION
#if defined(SPANDSP_SUPPORT_T42) //| T30_SUPPORT_T81_COMPRESSION
//| T30_SUPPORT_T42_COMPRESSION
#endif
#if defined(SPANDSP_SUPPORT_T43) #if defined(SPANDSP_SUPPORT_T43)
| T30_SUPPORT_T43_COMPRESSION | T30_SUPPORT_T43_COMPRESSION
#endif #endif
......
...@@ -29,23 +29,31 @@ ...@@ -29,23 +29,31 @@
#include "config.h" #include "config.h"
#endif #endif
#include <inttypes.h>
#include <stdlib.h> #include <stdlib.h>
#include <inttypes.h>
#include <limits.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <time.h>
#include <memory.h>
#include <string.h> #include <string.h>
#include <tiffio.h>
#if defined(HAVE_TGMATH_H) #if defined(HAVE_TGMATH_H)
#include <tgmath.h> #include <tgmath.h>
#endif #endif
#if defined(HAVE_MATH_H) #if defined(HAVE_MATH_H)
#include <math.h> #include <math.h>
#endif #endif
#include <time.h>
#include "floating_fudge.h" #include "floating_fudge.h"
#include <tiffio.h>
#include <assert.h>
#include <jpeglib.h> #include <jpeglib.h>
#include <setjmp.h> #include <setjmp.h>
#include "spandsp/telephony.h" #include "spandsp/telephony.h"
#include "spandsp/fast_convert.h"
#include "spandsp/logging.h" #include "spandsp/logging.h"
#include "spandsp/saturated.h"
#include "spandsp/async.h" #include "spandsp/async.h"
#include "spandsp/timezone.h" #include "spandsp/timezone.h"
#include "spandsp/t4_rx.h" #include "spandsp/t4_rx.h"
...@@ -362,15 +370,10 @@ static __inline__ void itu_to_lab(lab_params_t *s, cielab_t *lab, const uint8_t ...@@ -362,15 +370,10 @@ static __inline__ void itu_to_lab(lab_params_t *s, cielab_t *lab, const uint8_t
static __inline__ void lab_to_itu(lab_params_t *s, uint8_t out[3], const cielab_t *lab) static __inline__ void lab_to_itu(lab_params_t *s, uint8_t out[3], const cielab_t *lab)
{ {
float val;
/* T.4 E.6.4 */ /* T.4 E.6.4 */
val = floorf(lab->L/s->range_L + s->offset_L); out[0] = saturateu8(floorf(lab->L/s->range_L + s->offset_L));
out[0] = (uint8_t) (val < 0.0) ? 0 : (val < 256.0) ? val : 255; out[1] = saturateu8(floorf(lab->a/s->range_a + s->offset_a));
val = floorf(lab->a/s->range_a + s->offset_a); out[2] = saturateu8(floorf(lab->b/s->range_b + s->offset_b));
out[1] = (uint8_t) (val < 0.0) ? 0 : (val < 256.0) ? val : 255;
val = floorf(lab->b/s->range_b + s->offset_b);
out[2] = (uint8_t) (val < 0.0) ? 0 : (val < 256.0) ? val : 255;
if (s->ab_are_signed) if (s->ab_are_signed)
{ {
out[1] -= 128; out[1] -= 128;
...@@ -485,13 +488,9 @@ SPAN_DECLARE(void) lab_to_srgb(lab_params_t *s, uint8_t srgb[], const uint8_t la ...@@ -485,13 +488,9 @@ SPAN_DECLARE(void) lab_to_srgb(lab_params_t *s, uint8_t srgb[], const uint8_t la
g = (g > 0.0031308f) ? (1.055f*powf(g, 1.0f/2.4f) - 0.055f) : g*12.92f; g = (g > 0.0031308f) ? (1.055f*powf(g, 1.0f/2.4f) - 0.055f) : g*12.92f;
b = (b > 0.0031308f) ? (1.055f*powf(b, 1.0f/2.4f) - 0.055f) : b*12.92f; b = (b > 0.0031308f) ? (1.055f*powf(b, 1.0f/2.4f) - 0.055f) : b*12.92f;
r = floorf(r*256.0f); srgb[0] = saturateu8(floorf(r*256.0f));
g = floorf(g*256.0f); srgb[1] = saturateu8(floorf(g*256.0f));
b = floorf(b*256.0f); srgb[2] = saturateu8(floorf(b*256.0f));
srgb[0] = (r < 0) ? 0 : (r <= 255) ? r : 255;
srgb[1] = (g < 0) ? 0 : (g <= 255) ? g : 255;
srgb[2] = (b < 0) ? 0 : (b <= 255) ? b : 255;
#endif #endif
srgb += 3; srgb += 3;
lab += 3; lab += 3;
...@@ -929,7 +928,7 @@ SPAN_DECLARE(int) t42_srgb_to_itulab(logging_state_t *logging, lab_params_t *s, ...@@ -929,7 +928,7 @@ SPAN_DECLARE(int) t42_srgb_to_itulab(logging_state_t *logging, lab_params_t *s,
for (pos = 0; pos < srclen; pos += compressor.image_width*compressor.num_components) for (pos = 0; pos < srclen; pos += compressor.image_width*compressor.num_components)
{ {
scan_line_in = (JSAMPROW)src + pos; scan_line_in = (JSAMPROW) src + pos;
srgb_to_lab(s, scan_line_out, scan_line_in, compressor.image_width); srgb_to_lab(s, scan_line_out, scan_line_in, compressor.image_width);
jpeg_write_scanlines(&compressor, &scan_line_out, 1); jpeg_write_scanlines(&compressor, &scan_line_out, 1);
} }
...@@ -1033,7 +1032,7 @@ SPAN_DECLARE(int) t42_itulab_to_itulab(logging_state_t *logging, tdata_t *dst, t ...@@ -1033,7 +1032,7 @@ SPAN_DECLARE(int) t42_itulab_to_itulab(logging_state_t *logging, tdata_t *dst, t
for (pos = 0; pos < srclen; pos += compressor.image_width*compressor.num_components) for (pos = 0; pos < srclen; pos += compressor.image_width*compressor.num_components)
{ {
scan_line_in = (JSAMPROW)src + pos; scan_line_in = (JSAMPROW) src + pos;
jpeg_write_scanlines(&compressor, &scan_line_in, 1); jpeg_write_scanlines(&compressor, &scan_line_in, 1);
} }
...@@ -1150,7 +1149,7 @@ SPAN_DECLARE(int) t42_itulab_to_srgb(logging_state_t *logging, lab_params_t *s, ...@@ -1150,7 +1149,7 @@ SPAN_DECLARE(int) t42_itulab_to_srgb(logging_state_t *logging, lab_params_t *s,
for (pos = 0; decompressor.output_scanline < decompressor.output_height; pos += decompressor.output_width*decompressor.num_components) for (pos = 0; decompressor.output_scanline < decompressor.output_height; pos += decompressor.output_width*decompressor.num_components)
{ {
scan_line_out = (JSAMPROW)dst + pos; scan_line_out = (JSAMPROW) dst + pos;
jpeg_read_scanlines(&decompressor, &scan_line_in, 1); jpeg_read_scanlines(&decompressor, &scan_line_in, 1);
lab_to_srgb(s, scan_line_out, scan_line_in, decompressor.output_width); lab_to_srgb(s, scan_line_out, scan_line_in, decompressor.output_width);
} }
...@@ -1196,6 +1195,12 @@ SPAN_DECLARE(void) t42_encode_comment(t42_encode_state_t *s, const uint8_t comme ...@@ -1196,6 +1195,12 @@ SPAN_DECLARE(void) t42_encode_comment(t42_encode_state_t *s, const uint8_t comme
} }
/*- End of function --------------------------------------------------------*/ /*- End of function --------------------------------------------------------*/
SPAN_DECLARE(int) t42_encode_check_if_complete(t42_encode_state_t *s)
{
return 0;
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(int) t42_encode_get_byte(t42_encode_state_t *s) SPAN_DECLARE(int) t42_encode_get_byte(t42_encode_state_t *s)
{ {
return 0; return 0;
......
...@@ -900,9 +900,25 @@ SPAN_DECLARE(void) t4_tx_get_transfer_statistics(t4_tx_state_t *s, t4_stats_t *t ...@@ -900,9 +900,25 @@ SPAN_DECLARE(void) t4_tx_get_transfer_statistics(t4_tx_state_t *s, t4_stats_t *t
} }
/*- End of function --------------------------------------------------------*/ /*- End of function --------------------------------------------------------*/
SPAN_DECLARE(int) t4_tx_check_bit(t4_tx_state_t *s) SPAN_DECLARE(int) t4_tx_check_if_complete(t4_tx_state_t *s)
{ {
return t4_t6_encode_check_bit(&s->encoder.t4_t6); switch (s->line_encoding)
{
case T4_COMPRESSION_ITU_T4_1D:
case T4_COMPRESSION_ITU_T4_2D:
case T4_COMPRESSION_ITU_T6:
return t4_t6_encode_check_bit(&s->encoder.t4_t6);
case T4_COMPRESSION_ITU_T42:
return t42_encode_check_if_complete(&s->encoder.t42);
#if defined(SPANDSP_SUPPORT_T43)
case T4_COMPRESSION_ITU_T43:
return t43_encode_check_if_complete(&s->encoder.t43);
#endif
case T4_COMPRESSION_ITU_T85:
case T4_COMPRESSION_ITU_T85_L0:
return t85_encode_check_if_complete(&s->encoder.t85);
}
return SIG_STATUS_END_OF_DATA;
} }
/*- End of function --------------------------------------------------------*/ /*- End of function --------------------------------------------------------*/
......
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#include "spandsp/telephony.h" #include "spandsp/telephony.h"
#include "spandsp/logging.h" #include "spandsp/logging.h"
#include "spandsp/async.h"
#include "spandsp/timezone.h" #include "spandsp/timezone.h"
#include "spandsp/t4_rx.h" #include "spandsp/t4_rx.h"
#include "spandsp/t4_tx.h" #include "spandsp/t4_tx.h"
...@@ -580,6 +581,14 @@ SPAN_DECLARE(void) t85_encode_comment(t85_encode_state_t *s, const uint8_t comme ...@@ -580,6 +581,14 @@ SPAN_DECLARE(void) t85_encode_comment(t85_encode_state_t *s, const uint8_t comme
} }
/*- End of function --------------------------------------------------------*/ /*- End of function --------------------------------------------------------*/
SPAN_DECLARE(int) t85_encode_check_if_complete(t85_encode_state_t *s)
{
if (s->y >= s->yd)
return SIG_STATUS_END_OF_DATA;
return 0;
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(int) t85_encode_get_byte(t85_encode_state_t *s) SPAN_DECLARE(int) t85_encode_get_byte(t85_encode_state_t *s)
{ {
if (s->bitstream_optr >= s->bitstream_iptr) if (s->bitstream_optr >= s->bitstream_iptr)
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论