mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-03-13 12:40:17 +00:00
Improvements to dithering down colour and gray scale images to bi-level
images, for images with different illuminants.
This commit is contained in:
parent
48857cc7a7
commit
3ae2bdf4aa
@ -77,9 +77,7 @@
|
||||
#include "spandsp/image_translate.h"
|
||||
#include "spandsp/t81_t82_arith_coding.h"
|
||||
#include "spandsp/t85.h"
|
||||
#if defined(SPANDSP_SUPPORT_T42)
|
||||
#include "spandsp/t42.h"
|
||||
#endif
|
||||
#if defined(SPANDSP_SUPPORT_T43)
|
||||
#include "spandsp/t43.h"
|
||||
#endif
|
||||
@ -111,9 +109,7 @@
|
||||
#include "spandsp/private/timezone.h"
|
||||
#include "spandsp/private/t81_t82_arith_coding.h"
|
||||
#include "spandsp/private/t85.h"
|
||||
#if defined(SPANDSP_SUPPORT_T42)
|
||||
#include "spandsp/private/t42.h"
|
||||
#endif
|
||||
#if defined(SPANDSP_SUPPORT_T43)
|
||||
#include "spandsp/private/t43.h"
|
||||
#endif
|
||||
|
@ -59,9 +59,7 @@
|
||||
#include "spandsp/t4_tx.h"
|
||||
#include "spandsp/t81_t82_arith_coding.h"
|
||||
#include "spandsp/t85.h"
|
||||
#if defined(SPANDSP_SUPPORT_T42)
|
||||
#include "spandsp/t42.h"
|
||||
#endif
|
||||
#if defined(SPANDSP_SUPPORT_T43)
|
||||
#include "spandsp/t43.h"
|
||||
#endif
|
||||
@ -72,9 +70,7 @@
|
||||
#include "spandsp/private/logging.h"
|
||||
#include "spandsp/private/t81_t82_arith_coding.h"
|
||||
#include "spandsp/private/t85.h"
|
||||
#if defined(SPANDSP_SUPPORT_T42)
|
||||
#include "spandsp/private/t42.h"
|
||||
#endif
|
||||
#if defined(SPANDSP_SUPPORT_T43)
|
||||
#include "spandsp/private/t43.h"
|
||||
#endif
|
||||
@ -132,13 +128,13 @@ static int get_and_scrunch_row(image_translate_state_t *s, uint8_t buf[], size_t
|
||||
/* Scrunch colour down to gray, and scrunch 16 bit pixels down to 8 bit pixels */
|
||||
switch (s->input_format)
|
||||
{
|
||||
case IMAGE_TRANSLATE_FROM_GRAY_16:
|
||||
case T4_IMAGE_TYPE_GRAY_12BIT:
|
||||
image_gray16_to_gray8_row(buf, (uint16_t *) buf, s->input_width);
|
||||
break;
|
||||
case IMAGE_TRANSLATE_FROM_COLOUR_16:
|
||||
case T4_IMAGE_TYPE_COLOUR_12BIT:
|
||||
image_colour16_to_gray8_row(buf, (uint16_t *) buf, s->input_width);
|
||||
break;
|
||||
case IMAGE_TRANSLATE_FROM_COLOUR_8:
|
||||
case T4_IMAGE_TYPE_COLOUR_8BIT:
|
||||
image_colour8_to_gray8_row(buf, buf, s->input_width);
|
||||
break;
|
||||
}
|
||||
@ -235,47 +231,17 @@ static __inline__ uint8_t find_closest_palette_color(int in)
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
SPAN_DECLARE(int) image_translate_row(image_translate_state_t *s, uint8_t buf[], size_t len)
|
||||
static int floyd_steinberg_dither_row(image_translate_state_t *s, uint8_t buf[], int y)
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
int i;
|
||||
int j;
|
||||
int limit;
|
||||
int old_pixel;
|
||||
int new_pixel;
|
||||
int quant_error;
|
||||
uint8_t *p;
|
||||
uint8_t xx;
|
||||
|
||||
if (s->output_row < 0)
|
||||
return 0;
|
||||
y = s->output_row++;
|
||||
/* This algorithm works over two rows, and outputs the earlier of the two. To
|
||||
make this work:
|
||||
- At row 0 we grab and scrunch two rows.
|
||||
- From row 1 up to the last row we grab one new additional row each time.
|
||||
- At the last row we dither and output, without getting an extra row in. */
|
||||
for (i = (y == 0) ? 0 : 1; i < 2; i++)
|
||||
{
|
||||
p = s->pixel_row[0];
|
||||
s->pixel_row[0] = s->pixel_row[1];
|
||||
s->pixel_row[1] = p;
|
||||
|
||||
/* If this is the end of the image just ignore that there is now rubbish in pixel_row[1].
|
||||
Mark that the end has occurred. This row will be properly output, and the next one
|
||||
will fail, with the end of image condition (i.e. returning zero length) */
|
||||
if (s->resize)
|
||||
{
|
||||
if (image_resize_row(s, s->pixel_row[1], s->output_width*s->bytes_per_pixel) != s->output_width*s->bytes_per_pixel)
|
||||
s->output_row = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (get_and_scrunch_row(s, s->pixel_row[1], s->output_width*s->bytes_per_pixel) != s->output_width*s->bytes_per_pixel)
|
||||
s->output_row = -1;
|
||||
}
|
||||
}
|
||||
/* Apply Floyd-Steinberg dithering to the 8 bit pixels, using a bustrophodontic
|
||||
scan, to reduce the grayscale image to pure black and white */
|
||||
/* The first and last pixels in each row need special treatment, so we do not
|
||||
@ -353,6 +319,46 @@ SPAN_DECLARE(int) image_translate_row(image_translate_state_t *s, uint8_t buf[],
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
SPAN_DECLARE(int) image_translate_row(image_translate_state_t *s, uint8_t buf[], size_t len)
|
||||
{
|
||||
int y;
|
||||
int i;
|
||||
uint8_t *p;
|
||||
|
||||
if (s->output_row < 0)
|
||||
return 0;
|
||||
y = s->output_row++;
|
||||
/* This algorithm works over two rows, and outputs the earlier of the two. To
|
||||
make this work:
|
||||
- At row 0 we grab and scrunch two rows.
|
||||
- From row 1 up to the last row we grab one new additional row each time.
|
||||
- At the last row we dither and output, without getting an extra row in. */
|
||||
for (i = (y == 0) ? 0 : 1; i < 2; i++)
|
||||
{
|
||||
p = s->pixel_row[0];
|
||||
s->pixel_row[0] = s->pixel_row[1];
|
||||
s->pixel_row[1] = p;
|
||||
|
||||
/* If this is the end of the image just ignore that there is now rubbish in pixel_row[1].
|
||||
Mark that the end has occurred. This row will be properly output, and the next one
|
||||
will fail, with the end of image condition (i.e. returning zero length) */
|
||||
if (s->resize)
|
||||
{
|
||||
if (image_resize_row(s, s->pixel_row[1], s->output_width*s->bytes_per_pixel) != s->output_width*s->bytes_per_pixel)
|
||||
s->output_row = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (get_and_scrunch_row(s, s->pixel_row[1], s->output_width*s->bytes_per_pixel) != s->output_width*s->bytes_per_pixel)
|
||||
s->output_row = -1;
|
||||
}
|
||||
}
|
||||
if (s->output_format == T4_IMAGE_TYPE_BILEVEL)
|
||||
i = floyd_steinberg_dither_row(s, buf, y);
|
||||
return i;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
SPAN_DECLARE(int) image_translate_get_output_width(image_translate_state_t *s)
|
||||
{
|
||||
return s->output_width;
|
||||
@ -369,6 +375,7 @@ SPAN_DECLARE(image_translate_state_t *) image_translate_init(image_translate_sta
|
||||
int input_format,
|
||||
int input_width,
|
||||
int input_length,
|
||||
int output_format,
|
||||
int output_width,
|
||||
int output_length,
|
||||
t4_row_read_handler_t row_read_handler,
|
||||
@ -384,10 +391,11 @@ SPAN_DECLARE(image_translate_state_t *) image_translate_init(image_translate_sta
|
||||
memset(s, 0, sizeof(*s));
|
||||
|
||||
s->input_format = input_format;
|
||||
|
||||
s->input_width = input_width;
|
||||
s->input_length = input_length;
|
||||
|
||||
s->output_format = output_format;
|
||||
|
||||
if ((s->resize = (output_width > 0)))
|
||||
{
|
||||
s->output_width = output_width;
|
||||
@ -404,16 +412,16 @@ SPAN_DECLARE(image_translate_state_t *) image_translate_init(image_translate_sta
|
||||
|
||||
switch (s->input_format)
|
||||
{
|
||||
case IMAGE_TRANSLATE_FROM_GRAY_8:
|
||||
case T4_IMAGE_TYPE_GRAY_8BIT:
|
||||
s->bytes_per_pixel = 1;
|
||||
break;
|
||||
case IMAGE_TRANSLATE_FROM_GRAY_16:
|
||||
case T4_IMAGE_TYPE_GRAY_12BIT:
|
||||
s->bytes_per_pixel = 2;
|
||||
break;
|
||||
case IMAGE_TRANSLATE_FROM_COLOUR_8:
|
||||
case T4_IMAGE_TYPE_COLOUR_8BIT:
|
||||
s->bytes_per_pixel = 3;
|
||||
break;
|
||||
case IMAGE_TRANSLATE_FROM_COLOUR_16:
|
||||
case T4_IMAGE_TYPE_COLOUR_12BIT:
|
||||
s->bytes_per_pixel = 6;
|
||||
break;
|
||||
default:
|
||||
|
@ -40,15 +40,6 @@
|
||||
|
||||
typedef struct image_translate_state_s image_translate_state_t;
|
||||
|
||||
enum
|
||||
{
|
||||
IMAGE_TRANSLATE_FROM_MONO = 1,
|
||||
IMAGE_TRANSLATE_FROM_GRAY_8 = 2,
|
||||
IMAGE_TRANSLATE_FROM_GRAY_16 = 3,
|
||||
IMAGE_TRANSLATE_FROM_COLOUR_8 = 4,
|
||||
IMAGE_TRANSLATE_FROM_COLOUR_16 = 5
|
||||
};
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
{
|
||||
@ -75,6 +66,7 @@ SPAN_DECLARE(int) image_translate_get_output_length(image_translate_state_t *s);
|
||||
\param input_format x
|
||||
\param input_width The width of the source image, in pixels.
|
||||
\param input_length The length of the source image, in pixels.
|
||||
\param output_format x
|
||||
\param output_width The width of the output image, in pixels. If this is set <= 0 the image
|
||||
will not be resized.
|
||||
\param output_length The length of the output image, in pixels. If this is set to <= 0 the
|
||||
@ -88,6 +80,7 @@ SPAN_DECLARE(image_translate_state_t *) image_translate_init(image_translate_sta
|
||||
int input_format,
|
||||
int input_width,
|
||||
int input_length,
|
||||
int output_format,
|
||||
int output_width,
|
||||
int output_length,
|
||||
t4_row_read_handler_t row_read_handler,
|
||||
|
@ -33,6 +33,7 @@ struct image_translate_state_s
|
||||
int input_format;
|
||||
int input_width;
|
||||
int input_length;
|
||||
int output_format;
|
||||
int output_width;
|
||||
int output_length;
|
||||
int resize;
|
||||
|
@ -90,6 +90,10 @@ struct t4_tx_state_s
|
||||
/*! \brief The type of compression used between the FAX machines. */
|
||||
int line_encoding;
|
||||
|
||||
int line_encoding_bilevel;
|
||||
int line_encoding_gray;
|
||||
int line_encoding_colour;
|
||||
|
||||
/*! \brief The width of the current page, in pixels. */
|
||||
uint32_t image_width;
|
||||
/*! \brief The length of the current page, in pixels. */
|
||||
@ -140,6 +144,9 @@ struct t4_tx_state_s
|
||||
|
||||
image_translate_state_t translator;
|
||||
|
||||
int apply_lab;
|
||||
lab_params_t lab_params;
|
||||
|
||||
/* Supporting information, like resolutions, which the backend may want. */
|
||||
t4_tx_metadata_t metadata;
|
||||
|
||||
|
@ -373,7 +373,11 @@ enum
|
||||
/*! T.81 + T.30 Annex K colour sYCC-JPEG compression */
|
||||
T30_SUPPORT_SYCC_T81_COMPRESSION = 0x200,
|
||||
/*! T.88 monochrome JBIG2 compression */
|
||||
T30_SUPPORT_T88_COMPRESSION = 0x400
|
||||
T30_SUPPORT_T88_COMPRESSION = 0x400,
|
||||
/*! Dither a gray scale image down a simple bilevel image, with rescaling to fit a FAX page */
|
||||
T30_SUPPORT_GRAY_TO_BILEVEL = 0x40000000,
|
||||
/*! Dither a colour image down a simple bilevel image, with rescaling to fit a FAX page */
|
||||
T30_SUPPORT_COLOUR_TO_BILEVEL = 0x80000000
|
||||
};
|
||||
|
||||
enum
|
||||
|
@ -114,6 +114,7 @@ enum
|
||||
|
||||
/*! Information frame types used for error correction mode, in T.4 */
|
||||
T4_FCD = 0x06, /*! [0110 0000] Facsimile coded data */
|
||||
T4_CCD = 0x46, /*! [0110 0010] Character coded data */
|
||||
T4_RCP = 0x86 /*! [0110 0001] Return to control for partial page */
|
||||
};
|
||||
|
||||
|
@ -64,9 +64,7 @@
|
||||
#include "spandsp/image_translate.h"
|
||||
#include "spandsp/t81_t82_arith_coding.h"
|
||||
#include "spandsp/t85.h"
|
||||
#if defined(SPANDSP_SUPPORT_T42)
|
||||
#include "spandsp/t42.h"
|
||||
#endif
|
||||
#if defined(SPANDSP_SUPPORT_T43)
|
||||
#include "spandsp/t43.h"
|
||||
#endif
|
||||
@ -82,9 +80,7 @@
|
||||
#include "spandsp/private/timezone.h"
|
||||
#include "spandsp/private/t81_t82_arith_coding.h"
|
||||
#include "spandsp/private/t85.h"
|
||||
#if defined(SPANDSP_SUPPORT_T42)
|
||||
#include "spandsp/private/t42.h"
|
||||
#endif
|
||||
#if defined(SPANDSP_SUPPORT_T43)
|
||||
#include "spandsp/private/t43.h"
|
||||
#endif
|
||||
@ -2072,7 +2068,7 @@ static int process_rx_dis_dtc(t30_state_t *s, const uint8_t *msg, int len)
|
||||
s->error_correcting_mode = (s->ecm_allowed && (s->far_dis_dtc_frame[6] & DISBIT3) != 0);
|
||||
/* 256 octets per ECM frame */
|
||||
s->octets_per_ecm_frame = 256;
|
||||
/* Select the compression to use. */
|
||||
/* Now we know if we are going to use ECM, select the compression to use. */
|
||||
if (!s->error_correcting_mode)
|
||||
{
|
||||
/* Without error correction our choices are very limited */
|
||||
@ -2091,7 +2087,7 @@ static int process_rx_dis_dtc(t30_state_t *s, const uint8_t *msg, int len)
|
||||
{
|
||||
#if defined(SPANDSP_SUPPORT_T42x) || defined(SPANDSP_SUPPORT_T43)
|
||||
/* With error correction colour may be possible/required */
|
||||
if (0)
|
||||
if ((0 & (T30_SUPPORT_T43_COMPRESSION | T30_SUPPORT_T45_COMPRESSION | T30_SUPPORT_T81_COMPRESSION | T30_SUPPORT_SYCC_T81_COMPRESSION)))
|
||||
{
|
||||
s->line_encoding = T4_COMPRESSION_ITU_T85_L0;
|
||||
}
|
||||
@ -2382,7 +2378,7 @@ static int process_rx_dcs(t30_state_t *s, const uint8_t *msg, int len)
|
||||
s->image_width = widths[i][dcs_frame[5] & (DISBIT2 | DISBIT1)];
|
||||
|
||||
/* Check which compression the far end has decided to use. */
|
||||
#if defined(SPANDSP_SUPPORT_T42x)
|
||||
#if defined(SPANDSP_SUPPORT_T42)
|
||||
if (test_ctrl_bit(dcs_frame, T30_DCS_BIT_FULL_COLOUR_MODE))
|
||||
{
|
||||
s->line_encoding = T4_COMPRESSION_ITU_T42;
|
||||
|
@ -64,9 +64,7 @@
|
||||
#include "spandsp/image_translate.h"
|
||||
#include "spandsp/t81_t82_arith_coding.h"
|
||||
#include "spandsp/t85.h"
|
||||
#if defined(SPANDSP_SUPPORT_T42)
|
||||
#include "spandsp/t42.h"
|
||||
#endif
|
||||
#if defined(SPANDSP_SUPPORT_T43)
|
||||
#include "spandsp/t43.h"
|
||||
#endif
|
||||
@ -82,9 +80,7 @@
|
||||
#include "spandsp/private/timezone.h"
|
||||
#include "spandsp/private/t81_t82_arith_coding.h"
|
||||
#include "spandsp/private/t85.h"
|
||||
#if defined(SPANDSP_SUPPORT_T42)
|
||||
#include "spandsp/private/t42.h"
|
||||
#endif
|
||||
#if defined(SPANDSP_SUPPORT_T43)
|
||||
#include "spandsp/private/t43.h"
|
||||
#endif
|
||||
|
@ -64,9 +64,7 @@
|
||||
#include "spandsp/image_translate.h"
|
||||
#include "spandsp/t81_t82_arith_coding.h"
|
||||
#include "spandsp/t85.h"
|
||||
#if defined(SPANDSP_SUPPORT_T42)
|
||||
#include "spandsp/t42.h"
|
||||
#endif
|
||||
#if defined(SPANDSP_SUPPORT_T43)
|
||||
#include "spandsp/t43.h"
|
||||
#endif
|
||||
@ -81,9 +79,7 @@
|
||||
#include "spandsp/private/timezone.h"
|
||||
#include "spandsp/private/t81_t82_arith_coding.h"
|
||||
#include "spandsp/private/t85.h"
|
||||
#if defined(SPANDSP_SUPPORT_T42)
|
||||
#include "spandsp/private/t42.h"
|
||||
#endif
|
||||
#if defined(SPANDSP_SUPPORT_T43)
|
||||
#include "spandsp/private/t43.h"
|
||||
#endif
|
||||
@ -410,6 +406,8 @@ SPAN_DECLARE(const char *) t30_frametype(uint8_t x)
|
||||
return "NULL";
|
||||
case T4_FCD:
|
||||
return "FCD";
|
||||
case T4_CCD:
|
||||
return "CCD";
|
||||
case T4_RCP:
|
||||
return "RCP";
|
||||
}
|
||||
|
@ -77,9 +77,7 @@
|
||||
#include "spandsp/image_translate.h"
|
||||
#include "spandsp/t81_t82_arith_coding.h"
|
||||
#include "spandsp/t85.h"
|
||||
#if defined(SPANDSP_SUPPORT_T42)
|
||||
#include "spandsp/t42.h"
|
||||
#endif
|
||||
#if defined(SPANDSP_SUPPORT_T43)
|
||||
#include "spandsp/t43.h"
|
||||
#endif
|
||||
@ -109,9 +107,7 @@
|
||||
#include "spandsp/private/timezone.h"
|
||||
#include "spandsp/private/t81_t82_arith_coding.h"
|
||||
#include "spandsp/private/t85.h"
|
||||
#if defined(SPANDSP_SUPPORT_T42)
|
||||
#include "spandsp/private/t42.h"
|
||||
#endif
|
||||
#if defined(SPANDSP_SUPPORT_T43)
|
||||
#include "spandsp/private/t43.h"
|
||||
#endif
|
||||
|
@ -67,9 +67,7 @@
|
||||
#include "spandsp/image_translate.h"
|
||||
#include "spandsp/t81_t82_arith_coding.h"
|
||||
#include "spandsp/t85.h"
|
||||
#if defined(SPANDSP_SUPPORT_T42)
|
||||
#include "spandsp/t42.h"
|
||||
#endif
|
||||
#if defined(SPANDSP_SUPPORT_T43)
|
||||
#include "spandsp/t43.h"
|
||||
#endif
|
||||
@ -87,9 +85,7 @@
|
||||
#include "spandsp/private/timezone.h"
|
||||
#include "spandsp/private/t81_t82_arith_coding.h"
|
||||
#include "spandsp/private/t85.h"
|
||||
#if defined(SPANDSP_SUPPORT_T42)
|
||||
#include "spandsp/private/t42.h"
|
||||
#endif
|
||||
#if defined(SPANDSP_SUPPORT_T43)
|
||||
#include "spandsp/private/t43.h"
|
||||
#endif
|
||||
|
@ -57,9 +57,7 @@
|
||||
#include "spandsp/image_translate.h"
|
||||
#include "spandsp/t81_t82_arith_coding.h"
|
||||
#include "spandsp/t85.h"
|
||||
#if defined(SPANDSP_SUPPORT_T42)
|
||||
#include "spandsp/t42.h"
|
||||
#endif
|
||||
#if defined(SPANDSP_SUPPORT_T43)
|
||||
#include "spandsp/t43.h"
|
||||
#endif
|
||||
@ -70,9 +68,7 @@
|
||||
#include "spandsp/private/logging.h"
|
||||
#include "spandsp/private/t81_t82_arith_coding.h"
|
||||
#include "spandsp/private/t85.h"
|
||||
#if defined(SPANDSP_SUPPORT_T42)
|
||||
#include "spandsp/private/t42.h"
|
||||
#endif
|
||||
#if defined(SPANDSP_SUPPORT_T43)
|
||||
#include "spandsp/private/t43.h"
|
||||
#endif
|
||||
|
@ -88,9 +88,7 @@
|
||||
#include "spandsp/image_translate.h"
|
||||
#include "spandsp/t81_t82_arith_coding.h"
|
||||
#include "spandsp/t85.h"
|
||||
#if defined(SPANDSP_SUPPORT_T42)
|
||||
#include "spandsp/t42.h"
|
||||
#endif
|
||||
#if defined(SPANDSP_SUPPORT_T43)
|
||||
#include "spandsp/t43.h"
|
||||
#endif
|
||||
@ -100,9 +98,7 @@
|
||||
#include "spandsp/private/logging.h"
|
||||
#include "spandsp/private/t81_t82_arith_coding.h"
|
||||
#include "spandsp/private/t85.h"
|
||||
#if defined(SPANDSP_SUPPORT_T42)
|
||||
#include "spandsp/private/t42.h"
|
||||
#endif
|
||||
#if defined(SPANDSP_SUPPORT_T43)
|
||||
#include "spandsp/private/t43.h"
|
||||
#endif
|
||||
|
@ -85,9 +85,7 @@
|
||||
#include "spandsp/image_translate.h"
|
||||
#include "spandsp/t81_t82_arith_coding.h"
|
||||
#include "spandsp/t85.h"
|
||||
#if defined(SPANDSP_SUPPORT_T42)
|
||||
#include "spandsp/t42.h"
|
||||
#endif
|
||||
#if defined(SPANDSP_SUPPORT_T43)
|
||||
#include "spandsp/t43.h"
|
||||
#endif
|
||||
@ -97,9 +95,7 @@
|
||||
#include "spandsp/private/logging.h"
|
||||
#include "spandsp/private/t81_t82_arith_coding.h"
|
||||
#include "spandsp/private/t85.h"
|
||||
#if defined(SPANDSP_SUPPORT_T42)
|
||||
#include "spandsp/private/t42.h"
|
||||
#endif
|
||||
#if defined(SPANDSP_SUPPORT_T43)
|
||||
#include "spandsp/private/t43.h"
|
||||
#endif
|
||||
|
@ -57,9 +57,7 @@
|
||||
#include "spandsp/image_translate.h"
|
||||
#include "spandsp/t81_t82_arith_coding.h"
|
||||
#include "spandsp/t85.h"
|
||||
#if defined(SPANDSP_SUPPORT_T42)
|
||||
#include "spandsp/t42.h"
|
||||
#endif
|
||||
#if defined(SPANDSP_SUPPORT_T43)
|
||||
#include "spandsp/t43.h"
|
||||
#endif
|
||||
@ -69,9 +67,7 @@
|
||||
#include "spandsp/private/logging.h"
|
||||
#include "spandsp/private/t81_t82_arith_coding.h"
|
||||
#include "spandsp/private/t85.h"
|
||||
#if defined(SPANDSP_SUPPORT_T42)
|
||||
#include "spandsp/private/t42.h"
|
||||
#endif
|
||||
#if defined(SPANDSP_SUPPORT_T43)
|
||||
#include "spandsp/private/t43.h"
|
||||
#endif
|
||||
@ -104,6 +100,8 @@ static const TIFFFieldInfo tiff_fx_tiff_field_info[] =
|
||||
{TIFFTAG_IMAGELAYER, 2, 2, TIFF_LONG, FIELD_CUSTOM, FALSE, FALSE, (char *) "ImageLayer"},
|
||||
};
|
||||
|
||||
static void t4_tx_set_image_length(t4_tx_state_t *s, int image_length);
|
||||
|
||||
static TIFFExtendProc _ParentExtender = NULL;
|
||||
|
||||
static void TIFFFXDefaultDirectory(TIFF *tif)
|
||||
@ -251,31 +249,14 @@ static int get_tiff_directory_info(t4_tx_state_t *s)
|
||||
}
|
||||
}
|
||||
t4_tx_set_image_width(s, s->image_width);
|
||||
t4_tx_set_image_length(s, s->image_length);
|
||||
switch (s->line_encoding)
|
||||
{
|
||||
case T4_COMPRESSION_ITU_T4_1D:
|
||||
case T4_COMPRESSION_ITU_T4_2D:
|
||||
case T4_COMPRESSION_ITU_T6:
|
||||
t4_t6_encode_set_image_width(&s->encoder.t4_t6, s->image_width);
|
||||
t4_t6_encode_set_max_2d_rows_per_1d_row(&s->encoder.t4_t6, -s->metadata.y_resolution);
|
||||
break;
|
||||
#if defined(SPANDSP_SUPPORT_T42)
|
||||
case T4_COMPRESSION_ITU_T42:
|
||||
t42_encode_set_image_width(&s->encoder.t42, s->image_width);
|
||||
t42_encode_set_image_length(&s->encoder.t42, s->image_length);
|
||||
break;
|
||||
#endif
|
||||
#if defined(SPANDSP_SUPPORT_T43)
|
||||
case T4_COMPRESSION_ITU_T43:
|
||||
t43_encode_set_image_width(&s->encoder.t43, s->image_width);
|
||||
t43_encode_set_image_length(&s->encoder.t43, s->image_length);
|
||||
break;
|
||||
#endif
|
||||
case T4_COMPRESSION_ITU_T85:
|
||||
case T4_COMPRESSION_ITU_T85_L0:
|
||||
t85_encode_set_image_width(&s->encoder.t85, s->image_width);
|
||||
t85_encode_set_image_length(&s->encoder.t85, s->image_length);
|
||||
break;
|
||||
}
|
||||
#if defined(SPANDSP_SUPPORT_TIFF_FX)
|
||||
if (TIFFGetField(t->tiff_file, TIFFTAG_PROFILETYPE, &parm32))
|
||||
@ -426,6 +407,8 @@ static int row_read(void *user_data, uint8_t buf[], size_t len)
|
||||
return 0;
|
||||
if (TIFFReadScanline(s->tiff.tiff_file, buf, s->tiff.raw_row, 0) < 0)
|
||||
return 0;
|
||||
if (s->apply_lab)
|
||||
lab_to_srgb(&s->lab_params, buf, buf, len/3);
|
||||
s->tiff.raw_row++;
|
||||
return len;
|
||||
}
|
||||
@ -438,23 +421,12 @@ static int read_tiff_image(t4_tx_state_t *s)
|
||||
int i;
|
||||
uint8_t *t;
|
||||
image_translate_state_t *translator;
|
||||
int mode;
|
||||
|
||||
if (s->tiff.image_type != T4_IMAGE_TYPE_BILEVEL)
|
||||
{
|
||||
/* We need to dither this image down to pure black and white, possibly resizing it
|
||||
along the way. */
|
||||
if (s->tiff.image_type == T4_IMAGE_TYPE_GRAY_8BIT)
|
||||
mode = IMAGE_TRANSLATE_FROM_GRAY_8;
|
||||
else if (s->tiff.image_type == T4_IMAGE_TYPE_GRAY_12BIT)
|
||||
mode = IMAGE_TRANSLATE_FROM_GRAY_16;
|
||||
else if (s->tiff.image_type == T4_IMAGE_TYPE_COLOUR_8BIT)
|
||||
mode = IMAGE_TRANSLATE_FROM_COLOUR_8;
|
||||
else if (s->tiff.image_type == T4_IMAGE_TYPE_COLOUR_12BIT)
|
||||
mode = IMAGE_TRANSLATE_FROM_COLOUR_16;
|
||||
else
|
||||
return -1;
|
||||
if ((translator = image_translate_init(NULL, mode, s->image_width, s->image_length, 1728, -1, row_read, s)) == NULL)
|
||||
if ((translator = image_translate_init(NULL, s->tiff.image_type, s->image_width, s->image_length, T4_IMAGE_TYPE_BILEVEL, 1728, -1, row_read, s)) == NULL)
|
||||
return -1;
|
||||
s->image_width = image_translate_get_output_width(translator);
|
||||
s->image_length = image_translate_get_output_length(translator);
|
||||
@ -469,6 +441,23 @@ static int read_tiff_image(t4_tx_state_t *s)
|
||||
s->tiff.image_buffer = t;
|
||||
}
|
||||
s->tiff.raw_row = 0;
|
||||
switch (s->tiff.photo_metric)
|
||||
{
|
||||
case PHOTOMETRIC_CIELAB:
|
||||
/* The default luminant is D50 */
|
||||
set_lab_illuminant(&s->lab_params, 0.96422f, 1.0f, 0.82521f);
|
||||
set_lab_gamut(&s->lab_params, 0, 100, -128, 127, -128, 127, TRUE);
|
||||
s->apply_lab = TRUE;
|
||||
break;
|
||||
case PHOTOMETRIC_ITULAB:
|
||||
set_lab_illuminant(&s->lab_params, 0.9638f, 1.0f, 0.8245f);
|
||||
set_lab_gamut(&s->lab_params, 0, 100, -85, 85, -75, 125, FALSE);
|
||||
s->apply_lab = TRUE;
|
||||
break;
|
||||
default:
|
||||
s->apply_lab = FALSE;
|
||||
break;
|
||||
}
|
||||
total_len = 0;
|
||||
for (i = 0; i < s->image_length; i++)
|
||||
total_len += image_translate_row(translator, &s->tiff.image_buffer[total_len], s->image_width/8);
|
||||
@ -782,6 +771,29 @@ SPAN_DECLARE(void) t4_tx_set_image_width(t4_tx_state_t *s, int image_width)
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static void t4_tx_set_image_length(t4_tx_state_t *s, int image_length)
|
||||
{
|
||||
s->image_length = image_length;
|
||||
switch (s->line_encoding)
|
||||
{
|
||||
#if defined(SPANDSP_SUPPORT_T42)
|
||||
case T4_COMPRESSION_ITU_T42:
|
||||
t42_encode_set_image_length(&s->encoder.t42, image_length);
|
||||
break;
|
||||
#endif
|
||||
#if defined(SPANDSP_SUPPORT_T43)
|
||||
case T4_COMPRESSION_ITU_T43:
|
||||
t43_encode_set_image_length(&s->encoder.t43, image_length);
|
||||
break;
|
||||
#endif
|
||||
case T4_COMPRESSION_ITU_T85:
|
||||
case T4_COMPRESSION_ITU_T85_L0:
|
||||
t85_encode_set_image_length(&s->encoder.t85, image_length);
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
SPAN_DECLARE(void) t4_tx_set_max_2d_rows_per_1d_row(t4_tx_state_t *s, int max)
|
||||
{
|
||||
switch (s->line_encoding)
|
||||
|
@ -213,7 +213,7 @@ static void dither_tests_gray16(void)
|
||||
image[i*im.width + j] = j*1200;
|
||||
}
|
||||
|
||||
s = image_translate_init(s, IMAGE_TRANSLATE_FROM_GRAY_16, im.width, im.length, -1, -1, row_read, &im);
|
||||
s = image_translate_init(s, T4_IMAGE_TYPE_GRAY_12BIT, im.width, im.length, T4_IMAGE_TYPE_BILEVEL, -1, -1, row_read, &im);
|
||||
get_flattened_image(s, TRUE);
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
@ -239,7 +239,7 @@ static void dither_tests_gray8(void)
|
||||
for (j = 0; j < im.width; j++)
|
||||
image[i*im.width + j] = j*1200/256;
|
||||
}
|
||||
s = image_translate_init(s, IMAGE_TRANSLATE_FROM_GRAY_8, im.width, im.length, -1, -1, row_read, &im);
|
||||
s = image_translate_init(s, T4_IMAGE_TYPE_GRAY_8BIT, im.width, im.length, T4_IMAGE_TYPE_BILEVEL, -1, -1, row_read, &im);
|
||||
get_flattened_image(s, TRUE);
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
@ -269,7 +269,7 @@ static void dither_tests_colour16(void)
|
||||
image[i*3*im.width + 3*j + 2] = j*1200;
|
||||
}
|
||||
}
|
||||
s = image_translate_init(s, IMAGE_TRANSLATE_FROM_COLOUR_16, im.width, im.length, -1, -1, row_read, &im);
|
||||
s = image_translate_init(s, T4_IMAGE_TYPE_COLOUR_12BIT, im.width, im.length, T4_IMAGE_TYPE_BILEVEL, -1, -1, row_read, &im);
|
||||
get_flattened_image(s, TRUE);
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
@ -300,7 +300,7 @@ static void dither_tests_colour8(void)
|
||||
}
|
||||
}
|
||||
|
||||
s = image_translate_init(s, IMAGE_TRANSLATE_FROM_COLOUR_8, im.width, im.length, -1, -1, row_read, &im);
|
||||
s = image_translate_init(s, T4_IMAGE_TYPE_COLOUR_8BIT, im.width, im.length, T4_IMAGE_TYPE_BILEVEL, -1, -1, row_read, &im);
|
||||
get_flattened_image(s, TRUE);
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
@ -331,7 +331,7 @@ static void grow_tests_colour8(void)
|
||||
}
|
||||
}
|
||||
|
||||
s1 = image_translate_init(s1, IMAGE_TRANSLATE_FROM_COLOUR_8, im.width, im.length, 200, -1, row_read, &im);
|
||||
s1 = image_translate_init(s1, T4_IMAGE_TYPE_COLOUR_8BIT, im.width, im.length, T4_IMAGE_TYPE_BILEVEL, 200, -1, row_read, &im);
|
||||
|
||||
get_flattened_image(s1, FALSE);
|
||||
}
|
||||
@ -409,7 +409,7 @@ static void lenna_tests(int output_width, int output_length_scaling, const char
|
||||
im.current_row = 0;
|
||||
im.bytes_per_pixel = samples_per_pixel;
|
||||
|
||||
s = image_translate_init(s, IMAGE_TRANSLATE_FROM_COLOUR_8, image_width, image_length, output_width, output_length, row_read, &im);
|
||||
s = image_translate_init(s, T4_IMAGE_TYPE_COLOUR_8BIT, image_width, image_length, T4_IMAGE_TYPE_BILEVEL, output_width, output_length, row_read, &im);
|
||||
output_width = image_translate_get_output_width(s);
|
||||
output_length = image_translate_get_output_length(s);
|
||||
|
||||
|
@ -476,8 +476,8 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
TIFFSetField(tif, TIFFTAG_SUBFILETYPE, FILETYPE_PAGE);
|
||||
TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, w);
|
||||
// libtiff requires IMAGELENGTH to be set before SAMPLESPERPIXEL,
|
||||
// or StripOffsets and StripByteCounts will have SAMPLESPERPIXEL values
|
||||
/* libtiff requires IMAGELENGTH to be set before SAMPLESPERPIXEL,
|
||||
or StripOffsets and StripByteCounts will have SAMPLESPERPIXEL values */
|
||||
TIFFSetField(tif, TIFFTAG_IMAGELENGTH, h);
|
||||
TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_JPEG);
|
||||
TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8);
|
||||
|
Loading…
x
Reference in New Issue
Block a user