FAX T.6 decompression fixed for images with black in the last pixel of lines.
Colour and grey images can down be dithered down to bi-level images for transmission as faxes. More movement towards T.42 support
This commit is contained in:
parent
e35221b981
commit
e523076274
|
@ -20,6 +20,7 @@ AM_CFLAGS = $(COMP_VENDOR_CFLAGS)
|
|||
AM_LDFLAGS = $(COMP_VENDOR_LDFLAGS)
|
||||
|
||||
DISTCLEANFILES = $(srcdir)/at_interpreter_dictionary.h \
|
||||
$(srcdir)/cielab_luts.h \
|
||||
$(srcdir)/math_fixed_tables.h \
|
||||
$(srcdir)/v17_v32bis_rx_fixed_rrc.h \
|
||||
$(srcdir)/v17_v32bis_rx_floating_rrc.h \
|
||||
|
@ -58,6 +59,7 @@ EXTRA_DIST = floating_fudge.h \
|
|||
libtiff.2008.vcproj \
|
||||
filter_tools.c \
|
||||
make_at_dictionary.c \
|
||||
make_cielab_luts.c \
|
||||
make_math_fixed_tables.c \
|
||||
make_modem_filter.c \
|
||||
msvc/config.h \
|
||||
|
@ -344,6 +346,7 @@ noinst_HEADERS = cielab_luts.h \
|
|||
mmx_sse_decs.h \
|
||||
t30_local.h \
|
||||
t4_t6_decode_states.h \
|
||||
t42_t43_local.h \
|
||||
v17_v32bis_rx_constellation_maps.h \
|
||||
v17_v32bis_tx_constellation_maps.h \
|
||||
v29tx_constellation_maps.h
|
||||
|
@ -351,6 +354,9 @@ noinst_HEADERS = cielab_luts.h \
|
|||
make_at_dictionary$(EXEEXT): $(top_srcdir)/src/make_at_dictionary.c
|
||||
$(CC_FOR_BUILD) -o make_at_dictionary$(EXEEXT) $(top_srcdir)/src/make_at_dictionary.c -DHAVE_CONFIG_H -I$(top_builddir)/src
|
||||
|
||||
make_cielab_luts$(EXEEXT): $(top_srcdir)/src/make_cielab_luts.c
|
||||
$(CC_FOR_BUILD) -o make_cielab_luts$(EXEEXT) $(top_srcdir)/src/make_cielab_luts.c -DHAVE_CONFIG_H -I$(top_builddir)/src -lm
|
||||
|
||||
make_math_fixed_tables$(EXEEXT): $(top_srcdir)/src/make_math_fixed_tables.c
|
||||
$(CC_FOR_BUILD) -o make_math_fixed_tables$(EXEEXT) $(top_srcdir)/src/make_math_fixed_tables.c -DHAVE_CONFIG_H -I$(top_builddir)/src -lm
|
||||
|
||||
|
@ -378,6 +384,13 @@ t4_rx.$(OBJEXT): spandsp/version.h
|
|||
|
||||
t4_rx.lo: spandsp/version.h
|
||||
|
||||
t42.$(OBJEXT): cielab_luts.h
|
||||
|
||||
t42.lo: cielab_luts.h
|
||||
|
||||
cielab_luts.h: make_cielab_luts$(EXEEXT)
|
||||
./make_cielab_luts$(EXEEXT) >cielab_luts.h
|
||||
|
||||
V17_V32BIS_RX_INCL = v17_v32bis_rx_fixed_rrc.h \
|
||||
v17_v32bis_rx_floating_rrc.h
|
||||
|
||||
|
|
|
@ -1,32 +1,4 @@
|
|||
/*
|
||||
* SpanDSP - a series of DSP components for telephony
|
||||
*
|
||||
* cielab_luts.h
|
||||
*
|
||||
* Written by Steve Underwood <steveu@coppice.org>
|
||||
*
|
||||
* Copyright (C) 2011 Steve Underwood
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License version 2.1,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
|
||||
#if defined(T42_USE_LUTS)
|
||||
static const float sRGB_to_linear[256] =
|
||||
static const float srgb_to_linear[256] =
|
||||
{
|
||||
0.000000,
|
||||
0.000302,
|
||||
|
@ -168,7 +140,7 @@ static const float sRGB_to_linear[256] =
|
|||
0.248036,
|
||||
0.251995,
|
||||
0.255990,
|
||||
0.260021,
|
||||
0.260022,
|
||||
0.264090,
|
||||
0.268196,
|
||||
0.272338,
|
||||
|
@ -267,7 +239,7 @@ static const float sRGB_to_linear[256] =
|
|||
0.831396,
|
||||
0.839397,
|
||||
0.847443,
|
||||
0.855533,
|
||||
0.855534,
|
||||
0.863669,
|
||||
0.871850,
|
||||
0.880075,
|
||||
|
@ -285,8 +257,7 @@ static const float sRGB_to_linear[256] =
|
|||
0.982319,
|
||||
0.991137
|
||||
};
|
||||
|
||||
static const uint8_t linear_to_sRGB[4096] =
|
||||
static const uint8_t linear_to_srgb[4096] =
|
||||
{
|
||||
0,
|
||||
0,
|
||||
|
@ -4385,5 +4356,3 @@ static const uint8_t linear_to_sRGB[4096] =
|
|||
255,
|
||||
255
|
||||
};
|
||||
#endif
|
||||
/*- End of file ------------------------------------------------------------*/
|
||||
|
|
|
@ -74,6 +74,7 @@
|
|||
#include "spandsp/timezone.h"
|
||||
#include "spandsp/t4_rx.h"
|
||||
#include "spandsp/t4_tx.h"
|
||||
#include "spandsp/image_translate.h"
|
||||
#include "spandsp/t81_t82_arith_coding.h"
|
||||
#include "spandsp/t85.h"
|
||||
#if defined(SPANDSP_SUPPORT_T42)
|
||||
|
@ -118,6 +119,7 @@
|
|||
#endif
|
||||
#include "spandsp/private/t4_t6_decode.h"
|
||||
#include "spandsp/private/t4_t6_encode.h"
|
||||
#include "spandsp/private/image_translate.h"
|
||||
#include "spandsp/private/t4_rx.h"
|
||||
#include "spandsp/private/t4_tx.h"
|
||||
#include "spandsp/private/t30.h"
|
||||
|
|
|
@ -80,9 +80,9 @@
|
|||
#endif
|
||||
#include "spandsp/private/t4_t6_decode.h"
|
||||
#include "spandsp/private/t4_t6_encode.h"
|
||||
#include "spandsp/private/image_translate.h"
|
||||
#include "spandsp/private/t4_rx.h"
|
||||
#include "spandsp/private/t4_tx.h"
|
||||
#include "spandsp/private/image_translate.h"
|
||||
|
||||
static int image_colour16_to_gray8_row(uint8_t mono[], uint16_t colour[], int pixels)
|
||||
{
|
||||
|
@ -154,12 +154,14 @@ static int image_resize_row(image_translate_state_t *s, uint8_t buf[], size_t le
|
|||
int input_width;
|
||||
int input_length;
|
||||
int x;
|
||||
double c1;
|
||||
double c2;
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
int c1;
|
||||
int c2;
|
||||
int frac_row;
|
||||
int frac_col;
|
||||
#else
|
||||
double c1;
|
||||
double c2;
|
||||
double int_part;
|
||||
double frac_row;
|
||||
double frac_col;
|
||||
|
@ -200,15 +202,15 @@ static int image_resize_row(image_translate_state_t *s, uint8_t buf[], size_t le
|
|||
}
|
||||
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
frac_row = s->raw_output_row*input_length/output_length;
|
||||
frac_row = s->raw_output_row*input_length - frac_row*output_length;
|
||||
frac_row = ((s->raw_output_row*256*input_length)/output_length) & 0xFF;
|
||||
for (i = 0; i < output_width; i++)
|
||||
{
|
||||
x = i*input_width/output_width;
|
||||
frac_col = x - x*output_width;
|
||||
c1 = s->raw_pixel_row[0][x] + (s->raw_pixel_row[0][x + 1] - s->raw_pixel_row[0][x])*frac_col;
|
||||
c2 = s->raw_pixel_row[1][x] + (s->raw_pixel_row[1][x + 1] - s->raw_pixel_row[1][x])*frac_col;
|
||||
buf[i] = saturateu8(c1 + (c2 - c1)*frac_row);
|
||||
x = i*256*input_width/output_width;
|
||||
frac_col = x & 0xFF;
|
||||
x >>= 8;
|
||||
c1 = s->raw_pixel_row[0][x] + (((s->raw_pixel_row[0][x + 1] - s->raw_pixel_row[0][x])*frac_col) >> 8);
|
||||
c2 = s->raw_pixel_row[1][x] + (((s->raw_pixel_row[1][x + 1] - s->raw_pixel_row[1][x])*frac_col) >> 8);
|
||||
buf[i] = saturateu8(c1 + (((c2 - c1)*frac_row) >> 8));
|
||||
}
|
||||
#else
|
||||
frac_row = modf((double) s->raw_output_row*input_length/output_length, &int_part);
|
||||
|
@ -368,6 +370,7 @@ SPAN_DECLARE(image_translate_state_t *) image_translate_init(image_translate_sta
|
|||
int input_width,
|
||||
int input_length,
|
||||
int output_width,
|
||||
int output_length,
|
||||
t4_row_read_handler_t row_read_handler,
|
||||
void *row_read_user_data)
|
||||
{
|
||||
|
@ -385,9 +388,19 @@ SPAN_DECLARE(image_translate_state_t *) image_translate_init(image_translate_sta
|
|||
s->input_width = input_width;
|
||||
s->input_length = input_length;
|
||||
|
||||
s->resize = (output_width > 0);
|
||||
s->output_width = (s->resize) ? output_width : s->input_width;
|
||||
s->output_length = (s->resize) ? s->input_length*s->output_width/s->input_width : s->input_length;
|
||||
if ((s->resize = (output_width > 0)))
|
||||
{
|
||||
s->output_width = output_width;
|
||||
if (output_length > 0)
|
||||
s->output_length = output_length;
|
||||
else
|
||||
s->output_length = (s->input_length*s->output_width)/s->input_width;
|
||||
}
|
||||
else
|
||||
{
|
||||
s->output_width = s->input_width;
|
||||
s->output_length = s->input_length;
|
||||
}
|
||||
|
||||
switch (s->input_format)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* SpanDSP - a series of DSP components for telephony
|
||||
*
|
||||
* make_cielab_luts.c - Create the look up tables for CIELab colour management
|
||||
*
|
||||
* Written by Steve Underwood <steveu@coppice.org>
|
||||
*
|
||||
* Copyright (C) 2011 Steve Underwood
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
|
||||
#if defined(HAVE_CONFIG_H)
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <memory.h>
|
||||
#if defined(HAVE_TGMATH_H)
|
||||
#include <tgmath.h>
|
||||
#endif
|
||||
#if defined(HAVE_MATH_H)
|
||||
#include <math.h>
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float L;
|
||||
float a;
|
||||
float b;
|
||||
} cielab_t;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
float r;
|
||||
uint8_t srgb;
|
||||
int i;
|
||||
|
||||
printf("static const float srgb_to_linear[256] =\n");
|
||||
printf("{\n");
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
/* Start with "i" as the sRGB value */
|
||||
r = i/256.0f;
|
||||
|
||||
/* sRGB to Linear RGB */
|
||||
r = (r > 0.04045f) ? powf((r + 0.055f)/1.055f, 2.4f) : r/12.92f;
|
||||
|
||||
printf((i < 255) ? " %f,\n" : " %f\n", r);
|
||||
}
|
||||
printf("};\n");
|
||||
|
||||
printf("static const uint8_t linear_to_srgb[4096] =\n");
|
||||
printf("{\n");
|
||||
for (i = 0; i < 4096; i++)
|
||||
{
|
||||
/* Start with "i" as the linear RGB value */
|
||||
/* Linear RGB to sRGB */
|
||||
r = i/4096.0f;
|
||||
|
||||
r = (r > 0.0031308f) ? (1.055f*powf(r, 1.0f/2.4f) - 0.055f) : r*12.92f;
|
||||
|
||||
r = floorf(r*256.0f);
|
||||
|
||||
srgb = (r < 0) ? 0 : (r <= 255) ? r : 255;
|
||||
|
||||
printf((i < 4095) ? " %d,\n" : " %d\n", srgb);
|
||||
}
|
||||
printf("};\n");
|
||||
return 0;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
/*- End of file ------------------------------------------------------------*/
|
|
@ -75,9 +75,11 @@ 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_width The width of the output image, in pixels. The length of the output image
|
||||
will be derived automatically from this and the source image dimension, to main the
|
||||
geometry of the original image.
|
||||
\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
|
||||
output length will be derived automatically from the width, to maintain the geometry
|
||||
of the original image.
|
||||
\param row_read_handler A callback routine used to pull rows of pixels from the source image
|
||||
into the translation process.
|
||||
\param row_read_user_data An opaque point passed to read_row_handler
|
||||
|
@ -87,6 +89,7 @@ SPAN_DECLARE(image_translate_state_t *) image_translate_init(image_translate_sta
|
|||
int input_width,
|
||||
int input_length,
|
||||
int output_width,
|
||||
int output_length,
|
||||
t4_row_read_handler_t row_read_handler,
|
||||
void *row_read_user_data);
|
||||
|
||||
|
|
|
@ -53,6 +53,9 @@ struct t42_encode_state_s
|
|||
|
||||
lab_params_t lab_params;
|
||||
|
||||
/*! \brief The size of the compressed image, in bytes. */
|
||||
int compressed_image_size;
|
||||
|
||||
/*! \brief Error and flow logging control */
|
||||
logging_state_t logging;
|
||||
};
|
||||
|
@ -68,6 +71,8 @@ struct t42_decode_state_s
|
|||
t4_row_write_handler_t comment_handler;
|
||||
/*! An opaque pointer passed to comment_handler() */
|
||||
void *comment_user_data;
|
||||
/*! The maximum length of comment to be passed to the comment handler */
|
||||
uint32_t max_comment_len;
|
||||
|
||||
lab_params_t lab_params;
|
||||
|
||||
|
@ -78,6 +83,12 @@ struct t42_decode_state_s
|
|||
/*! Length of data pointed to by comment */
|
||||
size_t comment_len;
|
||||
|
||||
/*! \brief The size of the compressed image, in bytes. */
|
||||
int compressed_image_size;
|
||||
|
||||
int buf_size;
|
||||
uint8_t *compressed_buf;
|
||||
|
||||
/*! \brief Error and flow logging control */
|
||||
logging_state_t logging;
|
||||
};
|
||||
|
|
|
@ -54,6 +54,12 @@ typedef struct
|
|||
int image_buffer_size;
|
||||
/*! \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. */
|
||||
int image_length;
|
||||
/*! \brief Row counter used when the image is resized or dithered flat. */
|
||||
int raw_row;
|
||||
} t4_tx_tiff_state_t;
|
||||
|
||||
/*!
|
||||
|
@ -132,6 +138,8 @@ struct t4_tx_state_s
|
|||
t85_encode_state_t t85;
|
||||
} encoder;
|
||||
|
||||
image_translate_state_t translator;
|
||||
|
||||
/* Supporting information, like resolutions, which the backend may want. */
|
||||
t4_tx_metadata_t metadata;
|
||||
|
||||
|
|
|
@ -123,11 +123,11 @@ struct t85_decode_state_s
|
|||
t4_row_write_handler_t comment_handler;
|
||||
/*! An opaque pointer passed to comment_handler() */
|
||||
void *comment_user_data;
|
||||
/*! The maximum length of comment to be passed to the comment handler */
|
||||
uint32_t max_comment_len;
|
||||
|
||||
uint8_t min_bit_planes;
|
||||
uint8_t max_bit_planes;
|
||||
/*! The maximum length of comment to be passed to the comment handler */
|
||||
uint32_t max_comment_len;
|
||||
/*! The maximum permitted width of the full image, in pixels */
|
||||
uint32_t max_xd;
|
||||
/*! The maximum permitted height of the full image, in pixels */
|
||||
|
|
|
@ -58,19 +58,15 @@ SPAN_DECLARE(void) set_lab_gamut(lab_params_t *s, int L_min, int L_max, int a_mi
|
|||
|
||||
SPAN_DECLARE(void) set_lab_gamut2(lab_params_t *s, int L_P, int L_Q, int a_P, int a_Q, int b_P, int b_Q);
|
||||
|
||||
SPAN_DECLARE(void) set_illuminant_from_code(lab_params_t *s, const uint8_t code[4]);
|
||||
SPAN_DECLARE(int) t42_itulab_to_itulab(logging_state_t *logging, tdata_t *dst, tsize_t *dstlen, tdata_t src, tsize_t srclen, uint32_t width, uint32_t height);
|
||||
|
||||
SPAN_DECLARE(void) set_gamut_from_code(lab_params_t *s, const uint8_t code[12]);
|
||||
SPAN_DECLARE(int) t42_itulab_to_jpeg(logging_state_t *logging, lab_params_t *s, tdata_t *dst, tsize_t *dstlen, tdata_t src, tsize_t srclen);
|
||||
|
||||
SPAN_DECLARE(int) t42_itulab_to_itulab(tdata_t *dst, tsize_t *dstlen, tdata_t src, tsize_t srclen, uint32_t width, uint32_t height, char *emsg, size_t max_emsg_bytes);
|
||||
SPAN_DECLARE(int) t42_jpeg_to_itulab(logging_state_t *logging, lab_params_t *s, tdata_t *dst, tsize_t *dstlen, tdata_t src, tsize_t srclen);
|
||||
|
||||
SPAN_DECLARE(int) t42_itulab_to_jpeg(lab_params_t *s, tdata_t *dst, tsize_t *dstlen, tdata_t src, tsize_t srclen, char *emsg, size_t max_emsg_bytes);
|
||||
SPAN_DECLARE(int) t42_srgb_to_itulab(logging_state_t *logging, lab_params_t *s, tdata_t *dst, tsize_t *dstlen, tdata_t src, tsize_t srclen, uint32_t width, uint32_t height);
|
||||
|
||||
SPAN_DECLARE(int) t42_jpeg_to_itulab(lab_params_t *s, tdata_t *dst, tsize_t *dstlen, tdata_t src, tsize_t srclen, char *emsg, size_t max_emsg_bytes);
|
||||
|
||||
SPAN_DECLARE(int) t42_srgb_to_itulab(lab_params_t *s, tdata_t *dst, tsize_t *dstlen, tdata_t src, tsize_t srclen, uint32_t width, uint32_t height, char *emsg, size_t max_emsg_bytes);
|
||||
|
||||
SPAN_DECLARE(int) t42_itulab_to_srgb(lab_params_t *s, tdata_t dst, tsize_t *dstlen, tdata_t src, tsize_t srclen, uint32_t *width, uint32_t *height, char *emsg, size_t max_emsg_bytes);
|
||||
SPAN_DECLARE(int) t42_itulab_to_srgb(logging_state_t *logging, lab_params_t *s, tdata_t dst, tsize_t *dstlen, tdata_t src, tsize_t srclen, uint32_t *width, uint32_t *height);
|
||||
|
||||
SPAN_DECLARE(void) t42_encode_set_options(t42_encode_state_t *s,
|
||||
uint32_t l0,
|
||||
|
|
|
@ -199,6 +199,23 @@ typedef enum
|
|||
T4_LENGTH_1200_US_LEGAL = 0
|
||||
} t4_image_length_t;
|
||||
|
||||
/*! Return values from the T.85 decoder */
|
||||
typedef enum
|
||||
{
|
||||
/*! More image data is needed */
|
||||
T4_DECODE_MORE_DATA = 0,
|
||||
/*! Image completed successfully */
|
||||
T4_DECODE_OK = -1,
|
||||
/*! The decoder has interrupted */
|
||||
T4_DECODE_INTERRUPT = -2,
|
||||
/*! An abort was found in the image data */
|
||||
T4_DECODE_ABORTED = -3,
|
||||
/*! A memory allocation error occurred */
|
||||
T4_DECODE_NOMEM = -4,
|
||||
/*! The image data is invalid. */
|
||||
T4_DECODE_INVALID_DATA = -5
|
||||
} t4_decoder_status_t;
|
||||
|
||||
/*!
|
||||
T.4 FAX compression/decompression descriptor. This defines the working state
|
||||
for a single instance of a T.4 FAX compression or decompression channel.
|
||||
|
|
|
@ -53,24 +53,6 @@ enum
|
|||
T85_LRLTWO = 0x40
|
||||
};
|
||||
|
||||
/*! Return values from the T.85 decoder */
|
||||
enum
|
||||
{
|
||||
/*! More image data is needed */
|
||||
T85_MORE_DATA = 0,
|
||||
/*! Image completed successfully */
|
||||
T85_OK = -1,
|
||||
/*! The decoder has interrupted */
|
||||
T85_INTERRUPT = -2,
|
||||
/*! An abort was found in the image data */
|
||||
T85_ABORTED = -3,
|
||||
/*! A memory allocation error occurred */
|
||||
T85_NOMEM = -4,
|
||||
/*! The image data is invalid. This includes finding values
|
||||
in the BIH which lie outside the T.85 domain */
|
||||
T85_INVALID_DATA = -5
|
||||
};
|
||||
|
||||
/*! State of a working instance of the T.85 encoder */
|
||||
typedef struct t85_encode_state_s t85_encode_state_t;
|
||||
|
||||
|
|
|
@ -61,6 +61,7 @@
|
|||
#include "spandsp/timezone.h"
|
||||
#include "spandsp/t4_rx.h"
|
||||
#include "spandsp/t4_tx.h"
|
||||
#include "spandsp/image_translate.h"
|
||||
#include "spandsp/t81_t82_arith_coding.h"
|
||||
#include "spandsp/t85.h"
|
||||
#if defined(SPANDSP_SUPPORT_T42)
|
||||
|
@ -89,6 +90,7 @@
|
|||
#endif
|
||||
#include "spandsp/private/t4_t6_decode.h"
|
||||
#include "spandsp/private/t4_t6_encode.h"
|
||||
#include "spandsp/private/image_translate.h"
|
||||
#include "spandsp/private/t4_rx.h"
|
||||
#include "spandsp/private/t4_tx.h"
|
||||
#include "spandsp/private/t30.h"
|
||||
|
@ -1179,9 +1181,11 @@ int t30_build_dis_or_dtc(t30_state_t *s)
|
|||
set_ctrl_bit(s->local_dis_dtc_frame, T30_DIS_BIT_SYCC_T81_CAPABLE);
|
||||
if ((s->supported_compressions & T30_SUPPORT_T85_COMPRESSION))
|
||||
{
|
||||
set_ctrl_bit(s->local_dis_dtc_frame, T30_DIS_BIT_T85_CAPABLE);
|
||||
/* Bit 79 set with bit 78 clear is invalid, so only check for L0
|
||||
support here. */
|
||||
if ((s->supported_compressions & T30_SUPPORT_T85_L0_COMPRESSION))
|
||||
set_ctrl_bit(s->local_dis_dtc_frame, T30_DIS_BIT_T85_L0_CAPABLE);
|
||||
set_ctrl_bit(s->local_dis_dtc_frame, T30_DIS_BIT_T85_CAPABLE);
|
||||
}
|
||||
//if ((s->supported_compressions & T30_SUPPORT_T89_COMPRESSION))
|
||||
// set_ctrl_bit(s->local_dis_dtc_frame, T30_DIS_BIT_T89_CAPABLE);
|
||||
|
@ -1970,8 +1974,6 @@ static int start_sending_document(t30_state_t *s)
|
|||
if (s->use_own_tz)
|
||||
t4_tx_set_header_tz(&s->t4.tx, &s->tz);
|
||||
|
||||
s->x_resolution = t4_tx_get_x_resolution(&s->t4.tx);
|
||||
s->y_resolution = t4_tx_get_y_resolution(&s->t4.tx);
|
||||
/* The minimum scan time to be used can't be evaluated until we know the Y resolution, and
|
||||
must be evaluated before the minimum scan row bits can be evaluated. */
|
||||
if ((min_row_bits = set_min_scan_time_code(s)) < 0)
|
||||
|
@ -1984,6 +1986,8 @@ static int start_sending_document(t30_state_t *s)
|
|||
|
||||
if (tx_start_page(s))
|
||||
return -1;
|
||||
s->x_resolution = t4_tx_get_x_resolution(&s->t4.tx);
|
||||
s->y_resolution = t4_tx_get_y_resolution(&s->t4.tx);
|
||||
s->image_width = t4_tx_get_image_width(&s->t4.tx);
|
||||
if (s->error_correcting_mode)
|
||||
{
|
||||
|
@ -2069,41 +2073,61 @@ static int process_rx_dis_dtc(t30_state_t *s, const uint8_t *msg, int len)
|
|||
/* 256 octets per ECM frame */
|
||||
s->octets_per_ecm_frame = 256;
|
||||
/* Select the compression to use. */
|
||||
if (s->error_correcting_mode
|
||||
&&
|
||||
(s->supported_compressions & T30_SUPPORT_T85_COMPRESSION)
|
||||
&&
|
||||
test_ctrl_bit(s->far_dis_dtc_frame, T30_DIS_BIT_T85_CAPABLE))
|
||||
if (!s->error_correcting_mode)
|
||||
{
|
||||
if (s->supported_compressions & T30_SUPPORT_T85_L0_COMPRESSION
|
||||
/* Without error correction our choices are very limited */
|
||||
if ((s->supported_compressions & T30_SUPPORT_T4_2D_COMPRESSION)
|
||||
&&
|
||||
test_ctrl_bit(s->far_dis_dtc_frame, T30_DIS_BIT_T85_L0_CAPABLE))
|
||||
test_ctrl_bit(s->far_dis_dtc_frame, T30_DIS_BIT_2D_CAPABLE))
|
||||
{
|
||||
s->line_encoding = T4_COMPRESSION_ITU_T4_2D;
|
||||
}
|
||||
else
|
||||
{
|
||||
s->line_encoding = T4_COMPRESSION_ITU_T4_1D;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined(SPANDSP_SUPPORT_T42x) || defined(SPANDSP_SUPPORT_T43)
|
||||
/* With error correction colour may be possible/required */
|
||||
if (0)
|
||||
{
|
||||
s->line_encoding = T4_COMPRESSION_ITU_T85_L0;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
s->line_encoding = T4_COMPRESSION_ITU_T85;
|
||||
if ((s->supported_compressions & T30_SUPPORT_T85_L0_COMPRESSION)
|
||||
&&
|
||||
test_ctrl_bit(s->far_dis_dtc_frame, T30_DIS_BIT_T85_L0_CAPABLE))
|
||||
{
|
||||
s->line_encoding = T4_COMPRESSION_ITU_T85_L0;
|
||||
}
|
||||
else if ((s->supported_compressions & T30_SUPPORT_T85_COMPRESSION)
|
||||
&&
|
||||
test_ctrl_bit(s->far_dis_dtc_frame, T30_DIS_BIT_T85_CAPABLE))
|
||||
{
|
||||
s->line_encoding = T4_COMPRESSION_ITU_T85;
|
||||
}
|
||||
else if ((s->supported_compressions & T30_SUPPORT_T6_COMPRESSION)
|
||||
&&
|
||||
test_ctrl_bit(s->far_dis_dtc_frame, T30_DIS_BIT_T6_CAPABLE))
|
||||
{
|
||||
s->line_encoding = T4_COMPRESSION_ITU_T6;
|
||||
}
|
||||
else if ((s->supported_compressions & T30_SUPPORT_T4_2D_COMPRESSION)
|
||||
&&
|
||||
test_ctrl_bit(s->far_dis_dtc_frame, T30_DIS_BIT_2D_CAPABLE))
|
||||
{
|
||||
s->line_encoding = T4_COMPRESSION_ITU_T4_2D;
|
||||
}
|
||||
else
|
||||
{
|
||||
s->line_encoding = T4_COMPRESSION_ITU_T4_1D;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (s->error_correcting_mode
|
||||
&&
|
||||
(s->supported_compressions & T30_SUPPORT_T6_COMPRESSION)
|
||||
&&
|
||||
test_ctrl_bit(s->far_dis_dtc_frame, T30_DIS_BIT_T6_CAPABLE))
|
||||
{
|
||||
s->line_encoding = T4_COMPRESSION_ITU_T6;
|
||||
}
|
||||
else if ((s->supported_compressions & T30_SUPPORT_T4_2D_COMPRESSION)
|
||||
&&
|
||||
test_ctrl_bit(s->far_dis_dtc_frame, T30_DIS_BIT_2D_CAPABLE))
|
||||
{
|
||||
s->line_encoding = T4_COMPRESSION_ITU_T4_2D;
|
||||
}
|
||||
else
|
||||
{
|
||||
s->line_encoding = T4_COMPRESSION_ITU_T4_1D;
|
||||
}
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Selected compression %s (%d)\n", t4_encoding_to_str(s->line_encoding), s->line_encoding);
|
||||
switch (s->far_dis_dtc_frame[4] & (DISBIT6 | DISBIT5 | DISBIT4 | DISBIT3))
|
||||
{
|
||||
|
@ -2357,7 +2381,21 @@ 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 we will use. */
|
||||
/* Check which compression the far end has decided to use. */
|
||||
#if defined(SPANDSP_SUPPORT_T42x)
|
||||
if (test_ctrl_bit(dcs_frame, T30_DCS_BIT_FULL_COLOUR_MODE))
|
||||
{
|
||||
s->line_encoding = T4_COMPRESSION_ITU_T42;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#if defined(SPANDSP_SUPPORT_T43)
|
||||
if (test_ctrl_bit(dcs_frame, T30_DCS_BIT_T43_MODE))
|
||||
{
|
||||
s->line_encoding = T4_COMPRESSION_ITU_T43;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (test_ctrl_bit(dcs_frame, T30_DCS_BIT_T85_L0_MODE))
|
||||
{
|
||||
s->line_encoding = T4_COMPRESSION_ITU_T85_L0;
|
||||
|
|
|
@ -61,6 +61,7 @@
|
|||
#include "spandsp/timezone.h"
|
||||
#include "spandsp/t4_rx.h"
|
||||
#include "spandsp/t4_tx.h"
|
||||
#include "spandsp/image_translate.h"
|
||||
#include "spandsp/t81_t82_arith_coding.h"
|
||||
#include "spandsp/t85.h"
|
||||
#if defined(SPANDSP_SUPPORT_T42)
|
||||
|
@ -89,6 +90,7 @@
|
|||
#endif
|
||||
#include "spandsp/private/t4_t6_decode.h"
|
||||
#include "spandsp/private/t4_t6_encode.h"
|
||||
#include "spandsp/private/image_translate.h"
|
||||
#include "spandsp/private/t4_rx.h"
|
||||
#include "spandsp/private/t4_tx.h"
|
||||
#include "spandsp/private/t30.h"
|
||||
|
@ -700,7 +702,7 @@ SPAN_DECLARE(int) t30_set_supported_compressions(t30_state_t *s, int supported_c
|
|||
| T30_SUPPORT_T4_2D_COMPRESSION
|
||||
| T30_SUPPORT_T6_COMPRESSION
|
||||
#if defined(SPANDSP_SUPPORT_T42)
|
||||
| T30_SUPPORT_T42_COMPRESSION
|
||||
//| T30_SUPPORT_T42_COMPRESSION
|
||||
#endif
|
||||
#if defined(SPANDSP_SUPPORT_T43)
|
||||
| T30_SUPPORT_T43_COMPRESSION
|
||||
|
|
|
@ -61,6 +61,7 @@
|
|||
#include "spandsp/timezone.h"
|
||||
#include "spandsp/t4_rx.h"
|
||||
#include "spandsp/t4_tx.h"
|
||||
#include "spandsp/image_translate.h"
|
||||
#include "spandsp/t81_t82_arith_coding.h"
|
||||
#include "spandsp/t85.h"
|
||||
#if defined(SPANDSP_SUPPORT_T42)
|
||||
|
@ -88,6 +89,7 @@
|
|||
#endif
|
||||
#include "spandsp/private/t4_t6_decode.h"
|
||||
#include "spandsp/private/t4_t6_encode.h"
|
||||
#include "spandsp/private/image_translate.h"
|
||||
#include "spandsp/private/t4_rx.h"
|
||||
#include "spandsp/private/t4_tx.h"
|
||||
#include "spandsp/private/t30.h"
|
||||
|
|
|
@ -74,6 +74,7 @@
|
|||
#include "spandsp/timezone.h"
|
||||
#include "spandsp/t4_rx.h"
|
||||
#include "spandsp/t4_tx.h"
|
||||
#include "spandsp/image_translate.h"
|
||||
#include "spandsp/t81_t82_arith_coding.h"
|
||||
#include "spandsp/t85.h"
|
||||
#if defined(SPANDSP_SUPPORT_T42)
|
||||
|
@ -116,6 +117,7 @@
|
|||
#endif
|
||||
#include "spandsp/private/t4_t6_decode.h"
|
||||
#include "spandsp/private/t4_t6_encode.h"
|
||||
#include "spandsp/private/image_translate.h"
|
||||
#include "spandsp/private/t4_rx.h"
|
||||
#include "spandsp/private/t4_tx.h"
|
||||
#include "spandsp/private/t30.h"
|
||||
|
|
|
@ -64,6 +64,7 @@
|
|||
#include "spandsp/timezone.h"
|
||||
#include "spandsp/t4_rx.h"
|
||||
#include "spandsp/t4_tx.h"
|
||||
#include "spandsp/image_translate.h"
|
||||
#include "spandsp/t81_t82_arith_coding.h"
|
||||
#include "spandsp/t85.h"
|
||||
#if defined(SPANDSP_SUPPORT_T42)
|
||||
|
@ -94,6 +95,7 @@
|
|||
#endif
|
||||
#include "spandsp/private/t4_t6_decode.h"
|
||||
#include "spandsp/private/t4_t6_encode.h"
|
||||
#include "spandsp/private/image_translate.h"
|
||||
#include "spandsp/private/t4_rx.h"
|
||||
#include "spandsp/private/t4_tx.h"
|
||||
#include "spandsp/private/t30.h"
|
||||
|
|
|
@ -61,7 +61,10 @@
|
|||
|
||||
#define T42_USE_LUTS
|
||||
|
||||
#include "t42_t43_local.h"
|
||||
#if defined(T42_USE_LUTS)
|
||||
#include "cielab_luts.h"
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
@ -197,7 +200,7 @@ SPAN_DECLARE(void) set_lab_gamut2(lab_params_t *s, int L_P, int L_Q, int a_P, in
|
|||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
SPAN_DECLARE(void) set_illuminant_from_code(lab_params_t *s, const uint8_t code[4])
|
||||
void set_illuminant_from_code(logging_state_t *logging, lab_params_t *s, const uint8_t code[4])
|
||||
{
|
||||
int i;
|
||||
int colour_temp;
|
||||
|
@ -205,42 +208,44 @@ SPAN_DECLARE(void) set_illuminant_from_code(lab_params_t *s, const uint8_t code[
|
|||
if (code[0] == 'C' && code[1] == 'T')
|
||||
{
|
||||
colour_temp = pack_16(&code[2]);
|
||||
printf("Illuminant colour temp %dK\n", colour_temp);
|
||||
span_log(logging, SPAN_LOG_FLOW, "Illuminant colour temp %dK\n", colour_temp);
|
||||
return;
|
||||
}
|
||||
for (i = 0; illuminants[i].name[0]; i++)
|
||||
{
|
||||
if (memcmp(code, illuminants[i].tag, 4) == 0)
|
||||
{
|
||||
printf("Illuminant %s\n", illuminants[i].name);
|
||||
span_log(logging, SPAN_LOG_FLOW, "Illuminant %s\n", illuminants[i].name);
|
||||
set_lab_illuminant(s, illuminants[i].xn, illuminants[i].yn, illuminants[i].zn);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (illuminants[i].name[0] == '\0')
|
||||
printf("Unrecognised illuminant 0x%x 0x%x 0x%x 0x%x\n", code[0], code[1], code[2], code[3]);
|
||||
span_log(logging, SPAN_LOG_FLOW, "Unrecognised illuminant 0x%x 0x%x 0x%x 0x%x\n", code[0], code[1], code[2], code[3]);
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
SPAN_DECLARE(void) set_gamut_from_code(lab_params_t *s, const uint8_t code[12])
|
||||
void set_gamut_from_code(logging_state_t *logging, lab_params_t *s, const uint8_t code[12])
|
||||
{
|
||||
int i;
|
||||
int val[6];
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
val[i] = pack_16(&code[2*i]);
|
||||
printf("Gamut L=[%d,%d], a*=[%d,%d], b*=[%d,%d]\n",
|
||||
val[0],
|
||||
val[1],
|
||||
val[2],
|
||||
val[3],
|
||||
val[4],
|
||||
val[5]);
|
||||
span_log(logging,
|
||||
SPAN_LOG_FLOW,
|
||||
"Gamut L=[%d,%d], a*=[%d,%d], b*=[%d,%d]\n",
|
||||
val[0],
|
||||
val[1],
|
||||
val[2],
|
||||
val[3],
|
||||
val[4],
|
||||
val[5]);
|
||||
set_lab_gamut2(s, val[0], val[1], val[2], val[3], val[4], val[5]);
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static int isITUfax(lab_params_t *s, jpeg_saved_marker_ptr ptr)
|
||||
static int is_itu_fax(logging_state_t *logging, lab_params_t *s, jpeg_saved_marker_ptr ptr)
|
||||
{
|
||||
const uint8_t *data;
|
||||
int ok;
|
||||
|
@ -252,6 +257,11 @@ static int isITUfax(lab_params_t *s, jpeg_saved_marker_ptr ptr)
|
|||
{
|
||||
if (ptr->marker == (JPEG_APP0 + 1) && ptr->data_length >= 6)
|
||||
{
|
||||
/* Markers are:
|
||||
JPEG_RST0
|
||||
JPEG_EOI
|
||||
JPEG_APP0
|
||||
JPEG_COM */
|
||||
data = (const uint8_t *) ptr->data;
|
||||
if (strncmp((const char *) data, "G3FAX", 5) == 0)
|
||||
{
|
||||
|
@ -260,29 +270,57 @@ static int isITUfax(lab_params_t *s, jpeg_saved_marker_ptr ptr)
|
|||
case 0:
|
||||
for (i = 0; i < 2; i++)
|
||||
val[i] = pack_16(&data[6 + 2*i]);
|
||||
printf("Version %d, resolution %d dpi\n", val[0], val[1]);
|
||||
span_log(logging, SPAN_LOG_FLOW, "Version %d, resolution %d dpi\n", val[0], val[1]);
|
||||
ok = TRUE;
|
||||
break;
|
||||
case 1:
|
||||
printf("Set gamut\n");
|
||||
set_gamut_from_code(s, &data[6]);
|
||||
ok = TRUE;
|
||||
span_log(logging, SPAN_LOG_FLOW, "Set gamut\n");
|
||||
if (ptr->data_length >= 6 + 12)
|
||||
{
|
||||
set_gamut_from_code(logging, s, &data[6]);
|
||||
ok = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
span_log(logging, SPAN_LOG_FLOW, "Got bad G3FAX1 length - %d\n", ptr->data_length);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
printf("Set illuminant\n");
|
||||
set_illuminant_from_code(s, &data[6]);
|
||||
ok = TRUE;
|
||||
span_log(logging, SPAN_LOG_FLOW, "Set illuminant\n");
|
||||
if (ptr->data_length >= 6 + 4)
|
||||
{
|
||||
set_illuminant_from_code(logging, s, &data[6]);
|
||||
ok = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
span_log(logging, SPAN_LOG_FLOW, "Got bad G3FAX2 length - %d\n", ptr->data_length);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
/* Colour palette table */
|
||||
printf("Set colour palette\n");
|
||||
val[0] = pack_16(&data[6]);
|
||||
printf("Colour palette %d\n", val[0]);
|
||||
span_log(logging, SPAN_LOG_FLOW, "Set colour palette\n");
|
||||
if (ptr->data_length >= 6 + 2)
|
||||
{
|
||||
val[0] = pack_16(&data[6]);
|
||||
span_log(logging, SPAN_LOG_FLOW, "Colour palette %d\n", val[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
span_log(logging, SPAN_LOG_FLOW, "Got bad G3FAX3 length - %d\n", ptr->data_length);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
span_log(logging, SPAN_LOG_FLOW, "Got unexpected G3FAX%d length - %d\n", data[5], ptr->data_length);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
span_log(logging, SPAN_LOG_FLOW, "Got marker 0x%x, length %d\n", ptr->marker, ptr->data_length);
|
||||
span_log_buf(logging, SPAN_LOG_FLOW, "Got marker", (const uint8_t *) ptr->data, ptr->data_length);
|
||||
}
|
||||
ptr = ptr->next;
|
||||
}
|
||||
|
||||
|
@ -290,7 +328,7 @@ static int isITUfax(lab_params_t *s, jpeg_saved_marker_ptr ptr)
|
|||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static void SetITUFax(j_compress_ptr cinfo)
|
||||
static void set_itu_fax(j_compress_ptr cinfo)
|
||||
{
|
||||
uint8_t marker[10] =
|
||||
{
|
||||
|
@ -358,9 +396,9 @@ SPAN_DECLARE(void) srgb_to_lab(lab_params_t *s, uint8_t lab[], const uint8_t srg
|
|||
for (i = 0; i < pixels; i++)
|
||||
{
|
||||
#if defined(T42_USE_LUTS)
|
||||
r = sRGB_to_linear[srgb[0]];
|
||||
g = sRGB_to_linear[srgb[1]];
|
||||
b = sRGB_to_linear[srgb[2]];
|
||||
r = srgb_to_linear[srgb[0]];
|
||||
g = srgb_to_linear[srgb[1]];
|
||||
b = srgb_to_linear[srgb[2]];
|
||||
#else
|
||||
r = srgb[0]/256.0f;
|
||||
g = srgb[1]/256.0f;
|
||||
|
@ -436,11 +474,11 @@ SPAN_DECLARE(void) lab_to_srgb(lab_params_t *s, uint8_t srgb[], const uint8_t la
|
|||
|
||||
#if defined(T42_USE_LUTS)
|
||||
val = r*4096.0f;
|
||||
srgb[0] = linear_to_sRGB[(val < 0) ? 0 : (val < 4095) ? val : 4095];
|
||||
srgb[0] = linear_to_srgb[(val < 0) ? 0 : (val < 4095) ? val : 4095];
|
||||
val = g*4096.0f;
|
||||
srgb[1] = linear_to_sRGB[(val < 0) ? 0 : (val < 4095) ? val : 4095];
|
||||
srgb[1] = linear_to_srgb[(val < 0) ? 0 : (val < 4095) ? val : 4095];
|
||||
val = b*4096.0f;
|
||||
srgb[2] = linear_to_sRGB[(val < 0) ? 0 : (val < 4095) ? val : 4095];
|
||||
srgb[2] = linear_to_srgb[(val < 0) ? 0 : (val < 4095) ? val : 4095];
|
||||
#else
|
||||
/* Linear RGB to sRGB */
|
||||
r = (r > 0.0031308f) ? (1.055f*powf(r, 1.0f/2.4f) - 0.055f) : r*12.92f;
|
||||
|
@ -461,54 +499,77 @@ SPAN_DECLARE(void) lab_to_srgb(lab_params_t *s, uint8_t srgb[], const uint8_t la
|
|||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
SPAN_DECLARE(int) t42_itulab_to_jpeg(lab_params_t *s, tdata_t *dst, tsize_t *dstlen, tdata_t src, tsize_t srclen, char *emsg, size_t max_emsg_bytes)
|
||||
SPAN_DECLARE(int) t42_itulab_to_jpeg(logging_state_t *logging, lab_params_t *s, tdata_t *dst, tsize_t *dstlen, tdata_t src, tsize_t srclen)
|
||||
{
|
||||
struct jpeg_decompress_struct decompressor;
|
||||
struct jpeg_compress_struct compressor;
|
||||
char *outptr;
|
||||
size_t outsize;
|
||||
FILE *in;
|
||||
FILE *out;
|
||||
int m;
|
||||
JSAMPROW scan_line_in;
|
||||
JSAMPROW scan_line_out;
|
||||
escape_route_t escape;
|
||||
#if defined(HAVE_OPEN_MEMSTREAM)
|
||||
char *outptr;
|
||||
size_t outsize;
|
||||
#endif
|
||||
|
||||
escape.error_message[0] = '\0';
|
||||
emsg[0] = '\0';
|
||||
|
||||
#if defined(HAVE_OPEN_MEMSTREAM)
|
||||
in = fmemopen(src, srclen, "r");
|
||||
#else
|
||||
in = tmpfile();
|
||||
fwrite(src, 1, srclen, in);
|
||||
rewind(in);
|
||||
#endif
|
||||
if (in == NULL)
|
||||
if ((in = fmemopen(src, srclen, "r")) == NULL)
|
||||
{
|
||||
if (emsg[0] == '\0')
|
||||
strcpy(emsg, "Failed to fmemopen().");
|
||||
span_log(logging, SPAN_LOG_FLOW, "Failed to fmemopen().\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#if defined(HAVE_OPEN_MEMSTREAM)
|
||||
out = open_memstream(&outptr, &outsize);
|
||||
#else
|
||||
out = tmpfile();
|
||||
#endif
|
||||
if (out == NULL)
|
||||
outsize = 0;
|
||||
if ((out = open_memstream(&outptr, &outsize)) == NULL)
|
||||
{
|
||||
if (emsg[0] == '\0')
|
||||
strcpy(emsg, "Failed to open_memstream().");
|
||||
span_log(logging, SPAN_LOG_FLOW, "Failed to open_memstream().\n");
|
||||
fclose(in);
|
||||
return FALSE;
|
||||
}
|
||||
if (fseek(out, 0, SEEK_SET) != 0)
|
||||
{
|
||||
fclose(in);
|
||||
fclose(out);
|
||||
return FALSE;
|
||||
}
|
||||
#else
|
||||
if ((in = tmpfile()) == NULL)
|
||||
{
|
||||
span_log(logging, SPAN_LOG_FLOW, "Failed to tmpfile().\n");
|
||||
return FALSE;
|
||||
}
|
||||
if (fwrite(src, 1, srclen, in) != srclen)
|
||||
{
|
||||
fclose(in);
|
||||
return FALSE;
|
||||
}
|
||||
if (fseek(in, 0, SEEK_SET) != 0)
|
||||
{
|
||||
fclose(in);
|
||||
return FALSE;
|
||||
}
|
||||
if ((out = tmpfile()) == NULL)
|
||||
{
|
||||
span_log(logging, SPAN_LOG_FLOW, "Failed to tmpfile().\n");
|
||||
fclose(in);
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
scan_line_out = NULL;
|
||||
|
||||
if (setjmp(escape.escape))
|
||||
{
|
||||
strncpy(emsg, escape.error_message, max_emsg_bytes - 1);
|
||||
emsg[max_emsg_bytes - 1] = '\0';
|
||||
if (emsg[0] == '\0')
|
||||
strcpy(emsg, "Unspecified libjpeg error.");
|
||||
if (escape.error_message[0])
|
||||
span_log(logging, SPAN_LOG_FLOW, "%s\n", escape.error_message);
|
||||
else
|
||||
span_log(logging, SPAN_LOG_FLOW, "Unspecified libjpeg error.\n");
|
||||
if (scan_line_out)
|
||||
free(scan_line_out);
|
||||
fclose(in);
|
||||
fclose(out);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -532,14 +593,13 @@ SPAN_DECLARE(int) t42_itulab_to_jpeg(lab_params_t *s, tdata_t *dst, tsize_t *dst
|
|||
/* Take the header */
|
||||
jpeg_read_header(&decompressor, TRUE);
|
||||
|
||||
/* Now we can force the input colorspace. For ITULab, we will use YCbCr as a "don't touch" marker */
|
||||
/* Now we can force the input colour space. For ITULab, we use YCbCr as a "don't touch" marker */
|
||||
decompressor.out_color_space = JCS_YCbCr;
|
||||
|
||||
/* Sanity check and parameter check */
|
||||
if (!isITUfax(s, decompressor.marker_list))
|
||||
if (!is_itu_fax(logging, s, decompressor.marker_list))
|
||||
{
|
||||
if (emsg[0] == '\0')
|
||||
strcpy(emsg, "Is not ITUFAX.");
|
||||
span_log(logging, SPAN_LOG_FLOW, "Is not an ITU FAX.\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -552,12 +612,13 @@ SPAN_DECLARE(int) t42_itulab_to_jpeg(lab_params_t *s, tdata_t *dst, tsize_t *dst
|
|||
jpeg_create_compress(&compressor);
|
||||
jpeg_stdio_dest(&compressor, out);
|
||||
|
||||
/* Force the destination color space */
|
||||
/* Force the destination colour space */
|
||||
compressor.in_color_space = JCS_RGB;
|
||||
compressor.input_components = 3;
|
||||
|
||||
jpeg_set_defaults(&compressor);
|
||||
//jpeg_set_quality(&compressor, quality, TRUE /* limit to baseline-JPEG values */);
|
||||
/* Limit to baseline-JPEG values */
|
||||
//jpeg_set_quality(&compressor, quality, TRUE);
|
||||
|
||||
/* Copy size, resolution, etc */
|
||||
jpeg_copy_critical_parameters(&decompressor, &compressor);
|
||||
|
@ -592,64 +653,106 @@ SPAN_DECLARE(int) t42_itulab_to_jpeg(lab_params_t *s, tdata_t *dst, tsize_t *dst
|
|||
jpeg_destroy_decompress(&decompressor);
|
||||
jpeg_destroy_compress(&compressor);
|
||||
fclose(in);
|
||||
fclose(out);
|
||||
|
||||
#if defined(HAVE_OPEN_MEMSTREAM)
|
||||
fclose(out);
|
||||
*dst = outptr;
|
||||
*dstlen = outsize;
|
||||
#else
|
||||
*dstlen = ftell(out);
|
||||
*dst = malloc(*dstlen);
|
||||
if (fseek(out, 0, SEEK_SET) != 0)
|
||||
{
|
||||
fclose(out);
|
||||
return FALSE;
|
||||
}
|
||||
if (fread(*dst, 1, *dstlen, out) != *dstlen)
|
||||
{
|
||||
free(*dst);
|
||||
fclose(out);
|
||||
return FALSE;
|
||||
}
|
||||
fclose(out);
|
||||
#endif
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
SPAN_DECLARE(int) t42_jpeg_to_itulab(lab_params_t *s, tdata_t *dst, tsize_t *dstlen, tdata_t src, tsize_t srclen, char *emsg, size_t max_emsg_bytes)
|
||||
SPAN_DECLARE(int) t42_jpeg_to_itulab(logging_state_t *logging, lab_params_t *s, tdata_t *dst, tsize_t *dstlen, tdata_t src, tsize_t srclen)
|
||||
{
|
||||
struct jpeg_decompress_struct decompressor;
|
||||
struct jpeg_compress_struct compressor;
|
||||
char *outptr;
|
||||
size_t outsize;
|
||||
FILE *in;
|
||||
FILE *out;
|
||||
int m;
|
||||
JSAMPROW scan_line_in;
|
||||
JSAMPROW scan_line_out;
|
||||
escape_route_t escape;
|
||||
#if defined(HAVE_OPEN_MEMSTREAM)
|
||||
char *outptr;
|
||||
size_t outsize;
|
||||
#endif
|
||||
|
||||
escape.error_message[0] = '\0';
|
||||
emsg[0] = '\0';
|
||||
|
||||
#if defined(HAVE_OPEN_MEMSTREAM)
|
||||
in = fmemopen(src, srclen, "r");
|
||||
#else
|
||||
in = tmpfile();
|
||||
fwrite(src, 1, srclen, in);
|
||||
rewind(in);
|
||||
#endif
|
||||
if (in == NULL)
|
||||
if ((in = fmemopen(src, srclen, "r")) == NULL)
|
||||
{
|
||||
if (emsg[0] == '\0')
|
||||
strcpy(emsg, "Failed to fmemopen().");
|
||||
span_log(logging, SPAN_LOG_FLOW, "Failed to fmemopen().\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#if defined(HAVE_OPEN_MEMSTREAM)
|
||||
out = open_memstream(&outptr, &outsize);
|
||||
#else
|
||||
out = tmpfile();
|
||||
#endif
|
||||
if (out == NULL)
|
||||
outsize = 0;
|
||||
if ((out = open_memstream(&outptr, &outsize)) == NULL)
|
||||
{
|
||||
if (emsg[0] == '\0')
|
||||
strcpy(emsg, "Failed to open_memstream().");
|
||||
span_log(logging, SPAN_LOG_FLOW, "Failed to open_memstream().\n");
|
||||
fclose(in);
|
||||
return FALSE;
|
||||
}
|
||||
if (fseek(out, 0, SEEK_SET) != 0)
|
||||
{
|
||||
fclose(in);
|
||||
fclose(out);
|
||||
return FALSE;
|
||||
}
|
||||
#else
|
||||
if ((in = tmpfile()) == NULL)
|
||||
{
|
||||
span_log(logging, SPAN_LOG_FLOW, "Failed to tmpfile().\n");
|
||||
return FALSE;
|
||||
}
|
||||
if (fwrite(src, 1, srclen, in) != srclen)
|
||||
{
|
||||
fclose(in);
|
||||
return FALSE;
|
||||
}
|
||||
if (fseek(in, 0, SEEK_SET) != 0)
|
||||
{
|
||||
fclose(in);
|
||||
return FALSE;
|
||||
}
|
||||
if ((out = tmpfile()) == NULL)
|
||||
{
|
||||
span_log(logging, SPAN_LOG_FLOW, "Failed to tmpfile().\n");
|
||||
fclose(in);
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
scan_line_out = NULL;
|
||||
|
||||
if (setjmp(escape.escape))
|
||||
{
|
||||
strncpy(emsg, escape.error_message, max_emsg_bytes - 1);
|
||||
emsg[max_emsg_bytes - 1] = '\0';
|
||||
if (escape.error_message[0])
|
||||
span_log(logging, SPAN_LOG_FLOW, "%s\n", escape.error_message);
|
||||
else
|
||||
span_log(logging, SPAN_LOG_FLOW, "Unspecified libjpeg error.\n");
|
||||
if (scan_line_out)
|
||||
free(scan_line_out);
|
||||
fclose(in);
|
||||
fclose(out);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Create input decompressor. */
|
||||
decompressor.err = jpeg_std_error(&error_handler);
|
||||
decompressor.client_data = (void *) &escape;
|
||||
error_handler.error_exit = jpg_error_exit;
|
||||
|
@ -669,7 +772,7 @@ SPAN_DECLARE(int) t42_jpeg_to_itulab(lab_params_t *s, tdata_t *dst, tsize_t *dst
|
|||
/* Take the header */
|
||||
jpeg_read_header(&decompressor, TRUE);
|
||||
|
||||
/* Now we can force the input colorspace. For ITULab, we will use YCbCr as a "don't touch" marker */
|
||||
/* Now we can force the input colour space. For ITULab, we use YCbCr as a "don't touch" marker */
|
||||
decompressor.out_color_space = JCS_RGB;
|
||||
|
||||
compressor.err = jpeg_std_error(&error_handler);
|
||||
|
@ -680,12 +783,13 @@ SPAN_DECLARE(int) t42_jpeg_to_itulab(lab_params_t *s, tdata_t *dst, tsize_t *dst
|
|||
jpeg_create_compress(&compressor);
|
||||
jpeg_stdio_dest(&compressor, out);
|
||||
|
||||
/* Force the destination color space */
|
||||
/* Force the destination colour space */
|
||||
compressor.in_color_space = JCS_YCbCr;
|
||||
compressor.input_components = 3;
|
||||
|
||||
jpeg_set_defaults(&compressor);
|
||||
//jpeg_set_quality(&compressor, quality, TRUE /* limit to baseline-JPEG values */);
|
||||
/* Limit to baseline-JPEG values */
|
||||
//jpeg_set_quality(&compressor, quality, TRUE);
|
||||
|
||||
jpeg_copy_critical_parameters(&decompressor, &compressor);
|
||||
|
||||
|
@ -697,7 +801,7 @@ SPAN_DECLARE(int) t42_jpeg_to_itulab(lab_params_t *s, tdata_t *dst, tsize_t *dst
|
|||
jpeg_start_decompress(&decompressor);
|
||||
jpeg_start_compress(&compressor, TRUE);
|
||||
|
||||
SetITUFax(&compressor);
|
||||
set_itu_fax(&compressor);
|
||||
|
||||
if ((scan_line_in = (JSAMPROW) malloc(decompressor.output_width*decompressor.num_components)) == NULL)
|
||||
return FALSE;
|
||||
|
@ -722,45 +826,77 @@ SPAN_DECLARE(int) t42_jpeg_to_itulab(lab_params_t *s, tdata_t *dst, tsize_t *dst
|
|||
jpeg_destroy_decompress(&decompressor);
|
||||
jpeg_destroy_compress(&compressor);
|
||||
fclose(in);
|
||||
fclose(out);
|
||||
|
||||
#if defined(HAVE_OPEN_MEMSTREAM)
|
||||
fclose(out);
|
||||
*dst = outptr;
|
||||
*dstlen = outsize;
|
||||
#else
|
||||
*dstlen = ftell(out);
|
||||
*dst = malloc(*dstlen);
|
||||
if (fseek(out, 0, SEEK_SET) != 0)
|
||||
{
|
||||
fclose(out);
|
||||
return FALSE;
|
||||
}
|
||||
if (fread(*dst, 1, *dstlen, out) != *dstlen)
|
||||
{
|
||||
free(*dst);
|
||||
fclose(out);
|
||||
return FALSE;
|
||||
}
|
||||
fclose(out);
|
||||
#endif
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
SPAN_DECLARE(int) t42_srgb_to_itulab(lab_params_t *s, tdata_t *dst, tsize_t *dstlen, tdata_t src, tsize_t srclen, uint32_t width, uint32_t height, char *emsg, size_t max_emsg_bytes)
|
||||
SPAN_DECLARE(int) t42_srgb_to_itulab(logging_state_t *logging, lab_params_t *s, tdata_t *dst, tsize_t *dstlen, tdata_t src, tsize_t srclen, uint32_t width, uint32_t height)
|
||||
{
|
||||
struct jpeg_compress_struct compressor;
|
||||
FILE *out;
|
||||
char *outptr;
|
||||
size_t outsize;
|
||||
JSAMPROW scan_line_out;
|
||||
JSAMPROW scan_line_in;
|
||||
tsize_t pos;
|
||||
escape_route_t escape;
|
||||
#if defined(HAVE_OPEN_MEMSTREAM)
|
||||
char *outptr;
|
||||
size_t outsize;
|
||||
#endif
|
||||
|
||||
escape.error_message[0] = '\0';
|
||||
emsg[0] = '\0';
|
||||
|
||||
#if defined(HAVE_OPEN_MEMSTREAM)
|
||||
out = open_memstream(&outptr, &outsize);
|
||||
#else
|
||||
out = tmpfile();
|
||||
#endif
|
||||
if (out == NULL)
|
||||
outsize = 0;
|
||||
if ((out = open_memstream(&outptr, &outsize)) == NULL)
|
||||
{
|
||||
if (emsg[0] == '\0')
|
||||
strcpy(emsg, "Failed to open_memstream().");
|
||||
span_log(logging, SPAN_LOG_FLOW, "Failed to open_memstream().\n");
|
||||
return FALSE;
|
||||
}
|
||||
if (fseek(out, 0, SEEK_SET) != 0)
|
||||
{
|
||||
fclose(out);
|
||||
return FALSE;
|
||||
}
|
||||
#else
|
||||
if ((out = tmpfile()) == NULL)
|
||||
{
|
||||
span_log(logging, SPAN_LOG_FLOW, "Failed to tmpfile().\n");
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
scan_line_out = NULL;
|
||||
|
||||
if (setjmp(escape.escape))
|
||||
{
|
||||
strncpy(emsg, escape.error_message, max_emsg_bytes - 1);
|
||||
emsg[max_emsg_bytes - 1] = '\0';
|
||||
if (escape.error_message[0])
|
||||
span_log(logging, SPAN_LOG_FLOW, "%s\n", escape.error_message);
|
||||
else
|
||||
span_log(logging, SPAN_LOG_FLOW, "Unspecified libjpeg error.\n");
|
||||
if (scan_line_out)
|
||||
free(scan_line_out);
|
||||
fclose(out);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -772,12 +908,13 @@ SPAN_DECLARE(int) t42_srgb_to_itulab(lab_params_t *s, tdata_t *dst, tsize_t *dst
|
|||
jpeg_create_compress(&compressor);
|
||||
jpeg_stdio_dest(&compressor, out);
|
||||
|
||||
/* Force the destination color space */
|
||||
/* Force the destination colour space */
|
||||
compressor.in_color_space = JCS_YCbCr;
|
||||
compressor.input_components = 3;
|
||||
|
||||
jpeg_set_defaults(&compressor);
|
||||
//jpeg_set_quality(&compressor, quality, TRUE /* limit to baseline-JPEG values */);
|
||||
/* Limit to baseline-JPEG values */
|
||||
//jpeg_set_quality(&compressor, quality, TRUE);
|
||||
|
||||
/* Size, resolution, etc */
|
||||
compressor.image_width = width;
|
||||
|
@ -785,7 +922,7 @@ SPAN_DECLARE(int) t42_srgb_to_itulab(lab_params_t *s, tdata_t *dst, tsize_t *dst
|
|||
|
||||
jpeg_start_compress(&compressor, TRUE);
|
||||
|
||||
SetITUFax(&compressor);
|
||||
set_itu_fax(&compressor);
|
||||
|
||||
if ((scan_line_out = (JSAMPROW) malloc(compressor.image_width*compressor.num_components)) == NULL)
|
||||
return FALSE;
|
||||
|
@ -800,44 +937,73 @@ SPAN_DECLARE(int) t42_srgb_to_itulab(lab_params_t *s, tdata_t *dst, tsize_t *dst
|
|||
free(scan_line_out);
|
||||
jpeg_finish_compress(&compressor);
|
||||
jpeg_destroy_compress(&compressor);
|
||||
fclose(out);
|
||||
|
||||
#if defined(HAVE_OPEN_MEMSTREAM)
|
||||
fclose(out);
|
||||
*dst = outptr;
|
||||
*dstlen = outsize;
|
||||
#else
|
||||
*dstlen = ftell(out);
|
||||
*dst = malloc(*dstlen);
|
||||
if (fseek(out, 0, SEEK_SET) != 0)
|
||||
{
|
||||
fclose(out);
|
||||
return FALSE;
|
||||
}
|
||||
if (fread(*dst, 1, *dstlen, out) != *dstlen)
|
||||
{
|
||||
free(*dst);
|
||||
fclose(out);
|
||||
return FALSE;
|
||||
}
|
||||
fclose(out);
|
||||
#endif
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
SPAN_DECLARE(int) t42_itulab_to_itulab(tdata_t *dst, tsize_t *dstlen, tdata_t src, tsize_t srclen, uint32_t width, uint32_t height, char *emsg, size_t max_emsg_bytes)
|
||||
SPAN_DECLARE(int) t42_itulab_to_itulab(logging_state_t *logging, tdata_t *dst, tsize_t *dstlen, tdata_t src, tsize_t srclen, uint32_t width, uint32_t height)
|
||||
{
|
||||
struct jpeg_compress_struct compressor;
|
||||
FILE *out;
|
||||
char *outptr;
|
||||
size_t outsize;
|
||||
JSAMPROW scan_line_in;
|
||||
tsize_t pos;
|
||||
escape_route_t escape;
|
||||
#if defined(HAVE_OPEN_MEMSTREAM)
|
||||
char *outptr;
|
||||
size_t outsize;
|
||||
#endif
|
||||
|
||||
escape.error_message[0] = '\0';
|
||||
emsg[0] = '\0';
|
||||
|
||||
#if defined(HAVE_OPEN_MEMSTREAM)
|
||||
out = open_memstream(&outptr, &outsize);
|
||||
#else
|
||||
out = tmpfile();
|
||||
#endif
|
||||
if (out == NULL)
|
||||
outsize = 0;
|
||||
if ((out = open_memstream(&outptr, &outsize)) == NULL)
|
||||
{
|
||||
if (emsg[0] == '\0')
|
||||
strcpy(emsg, "Failed to open_memstream().");
|
||||
span_log(logging, SPAN_LOG_FLOW, "Failed to open_memstream().\n");
|
||||
return FALSE;
|
||||
}
|
||||
if (fseek(out, 0, SEEK_SET) != 0)
|
||||
{
|
||||
fclose(out);
|
||||
return FALSE;
|
||||
}
|
||||
#else
|
||||
if ((out = tmpfile()) == NULL)
|
||||
{
|
||||
span_log(logging, SPAN_LOG_FLOW, "Failed to tmpfile().\n");
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (setjmp(escape.escape))
|
||||
{
|
||||
strncpy(emsg, escape.error_message, max_emsg_bytes - 1);
|
||||
emsg[max_emsg_bytes - 1] = '\0';
|
||||
if (escape.error_message[0])
|
||||
span_log(logging, SPAN_LOG_FLOW, "%s\n", escape.error_message);
|
||||
else
|
||||
span_log(logging, SPAN_LOG_FLOW, "Unspecified libjpeg error.\n");
|
||||
fclose(out);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -849,12 +1015,13 @@ SPAN_DECLARE(int) t42_itulab_to_itulab(tdata_t *dst, tsize_t *dstlen, tdata_t sr
|
|||
jpeg_create_compress(&compressor);
|
||||
jpeg_stdio_dest(&compressor, out);
|
||||
|
||||
/* Force the destination color space */
|
||||
/* Force the destination colour space */
|
||||
compressor.in_color_space = JCS_YCbCr;
|
||||
compressor.input_components = 3;
|
||||
|
||||
jpeg_set_defaults(&compressor);
|
||||
//jpeg_set_quality(&compressor, quality, TRUE /* limit to baseline-JPEG values */);
|
||||
/* Limit to baseline-JPEG values */
|
||||
//jpeg_set_quality(&compressor, quality, TRUE);
|
||||
|
||||
/* Size, resolution, etc */
|
||||
compressor.image_width = width;
|
||||
|
@ -862,7 +1029,7 @@ SPAN_DECLARE(int) t42_itulab_to_itulab(tdata_t *dst, tsize_t *dstlen, tdata_t sr
|
|||
|
||||
jpeg_start_compress(&compressor, TRUE);
|
||||
|
||||
SetITUFax(&compressor);
|
||||
set_itu_fax(&compressor);
|
||||
|
||||
for (pos = 0; pos < srclen; pos += compressor.image_width*compressor.num_components)
|
||||
{
|
||||
|
@ -872,16 +1039,33 @@ SPAN_DECLARE(int) t42_itulab_to_itulab(tdata_t *dst, tsize_t *dstlen, tdata_t sr
|
|||
|
||||
jpeg_finish_compress(&compressor);
|
||||
jpeg_destroy_compress(&compressor);
|
||||
fclose(out);
|
||||
|
||||
#if defined(HAVE_OPEN_MEMSTREAM)
|
||||
fclose(out);
|
||||
*dst = outptr;
|
||||
*dstlen = outsize;
|
||||
#else
|
||||
*dstlen = ftell(out);
|
||||
*dst = malloc(*dstlen);
|
||||
if (fseek(out, 0, SEEK_SET) != 0)
|
||||
{
|
||||
fclose(out);
|
||||
return FALSE;
|
||||
}
|
||||
if (fread(*dst, 1, *dstlen, out) != *dstlen)
|
||||
{
|
||||
free(*dst);
|
||||
fclose(out);
|
||||
return FALSE;
|
||||
}
|
||||
fclose(out);
|
||||
#endif
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
SPAN_DECLARE(int) t42_itulab_to_srgb(lab_params_t *s, tdata_t dst, tsize_t *dstlen, tdata_t src, tsize_t srclen, uint32_t *width, uint32_t *height, char *emsg, size_t max_emsg_bytes)
|
||||
SPAN_DECLARE(int) t42_itulab_to_srgb(logging_state_t *logging, lab_params_t *s, tdata_t dst, tsize_t *dstlen, tdata_t src, tsize_t srclen, uint32_t *width, uint32_t *height)
|
||||
{
|
||||
struct jpeg_decompress_struct decompressor;
|
||||
JSAMPROW scan_line_out;
|
||||
|
@ -892,28 +1076,41 @@ SPAN_DECLARE(int) t42_itulab_to_srgb(lab_params_t *s, tdata_t dst, tsize_t *dstl
|
|||
escape_route_t escape;
|
||||
|
||||
escape.error_message[0] = '\0';
|
||||
emsg[0] = '\0';
|
||||
|
||||
#if defined(HAVE_OPEN_MEMSTREAM)
|
||||
in = fmemopen(src, srclen, "r");
|
||||
#else
|
||||
in = tmpfile();
|
||||
fwrite(src, 1, srclen, in);
|
||||
rewind(in);
|
||||
#endif
|
||||
if (in == NULL)
|
||||
if ((in = fmemopen(src, srclen, "r")) == NULL)
|
||||
{
|
||||
if (emsg[0] == '\0')
|
||||
strcpy(emsg, "Failed to fmemopen().");
|
||||
span_log(logging, SPAN_LOG_FLOW, "Failed to fmemopen().\n");
|
||||
return FALSE;
|
||||
}
|
||||
#else
|
||||
if ((in = tmpfile()) == NULL)
|
||||
{
|
||||
span_log(logging, SPAN_LOG_FLOW, "Failed to tmpfile().\n");
|
||||
return FALSE;
|
||||
}
|
||||
if (fwrite(src, 1, srclen, in) != srclen)
|
||||
{
|
||||
fclose(in);
|
||||
return FALSE;
|
||||
}
|
||||
if (fseek(in, 0, SEEK_SET) != 0)
|
||||
{
|
||||
fclose(in);
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
scan_line_out = NULL;
|
||||
|
||||
if (setjmp(escape.escape))
|
||||
{
|
||||
strncpy(emsg, escape.error_message, max_emsg_bytes - 1);
|
||||
emsg[max_emsg_bytes - 1] = '\0';
|
||||
if (emsg[0] == '\0')
|
||||
strcpy(emsg, "Unspecified libjpeg error.");
|
||||
if (escape.error_message[0])
|
||||
span_log(logging, SPAN_LOG_FLOW, "%s\n", escape.error_message);
|
||||
else
|
||||
span_log(logging, SPAN_LOG_FLOW, "Unspecified libjpeg error.\n");
|
||||
if (scan_line_out)
|
||||
free(scan_line_out);
|
||||
fclose(in);
|
||||
return FALSE;
|
||||
}
|
||||
/* Create input decompressor. */
|
||||
|
@ -932,21 +1129,16 @@ SPAN_DECLARE(int) t42_itulab_to_srgb(lab_params_t *s, tdata_t dst, tsize_t *dstl
|
|||
/* Rewind the file */
|
||||
if (fseek(in, 0, SEEK_SET) != 0)
|
||||
return FALSE;
|
||||
printf("XXXX 10\n");
|
||||
/* Take the header */
|
||||
jpeg_read_header(&decompressor, FALSE);
|
||||
printf("XXXX 11\n");
|
||||
/* Now we can force the input colorspace. For ITULab, we will use YCbCr as a "don't touch" marker */
|
||||
/* Now we can force the input colour space. For ITULab, we use YCbCr as a "don't touch" marker */
|
||||
decompressor.out_color_space = JCS_YCbCr;
|
||||
printf("XXXX 12\n");
|
||||
/* Sanity check and parameter check */
|
||||
if (!isITUfax(s, decompressor.marker_list))
|
||||
if (!is_itu_fax(logging, s, decompressor.marker_list))
|
||||
{
|
||||
if (emsg[0] == '\0')
|
||||
strcpy(emsg, "Is not ITUFAX.");
|
||||
//return FALSE;
|
||||
span_log(logging, SPAN_LOG_FLOW, "Is not an ITU FAX.\n");
|
||||
return FALSE;
|
||||
}
|
||||
printf("XXXX 13\n");
|
||||
/* Copy size, resolution, etc */
|
||||
*width = decompressor.image_width;
|
||||
*height = decompressor.image_height;
|
||||
|
@ -1030,7 +1222,7 @@ SPAN_DECLARE(uint32_t) t42_encode_get_image_length(t42_encode_state_t *s)
|
|||
|
||||
SPAN_DECLARE(int) t42_encode_get_compressed_image_size(t42_encode_state_t *s)
|
||||
{
|
||||
return 0;
|
||||
return s->compressed_image_size;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
|
@ -1044,6 +1236,9 @@ SPAN_DECLARE(int) t42_encode_set_row_read_handler(t42_encode_state_t *s,
|
|||
|
||||
SPAN_DECLARE(int) t42_encode_restart(t42_encode_state_t *s, uint32_t image_width, uint32_t image_length)
|
||||
{
|
||||
//s->image_width = image_width;
|
||||
//s->image_length = image_length;
|
||||
s->compressed_image_size = 0;
|
||||
return 0;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
@ -1065,6 +1260,7 @@ SPAN_DECLARE(t42_encode_state_t *) t42_encode_init(t42_encode_state_t *s,
|
|||
|
||||
s->row_read_handler = handler;
|
||||
s->row_read_user_data = user_data;
|
||||
t42_encode_restart(s, image_width, image_length);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
@ -1078,7 +1274,11 @@ SPAN_DECLARE(int) t42_encode_release(t42_encode_state_t *s)
|
|||
|
||||
SPAN_DECLARE(int) t42_encode_free(t42_encode_state_t *s)
|
||||
{
|
||||
return 0;
|
||||
int ret;
|
||||
|
||||
ret = t42_encode_release(s);
|
||||
free(s);
|
||||
return ret;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
|
@ -1097,6 +1297,17 @@ SPAN_DECLARE(int) t42_decode_put_chunk(t42_decode_state_t *s,
|
|||
const uint8_t data[],
|
||||
size_t len)
|
||||
{
|
||||
uint8_t *buf;
|
||||
|
||||
if (s->compressed_image_size + len > s->buf_size)
|
||||
{
|
||||
if ((buf = (uint8_t *) realloc(s->compressed_buf, s->compressed_image_size + 1000)) == NULL)
|
||||
return -1;
|
||||
s->buf_size = s->compressed_image_size + 1000;
|
||||
s->compressed_buf = buf;
|
||||
}
|
||||
memcpy(&s->compressed_buf[s->compressed_image_size], data, len);
|
||||
s->compressed_image_size += len;
|
||||
return 0;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
@ -1105,6 +1316,8 @@ SPAN_DECLARE(int) t42_decode_set_row_write_handler(t42_decode_state_t *s,
|
|||
t4_row_write_handler_t handler,
|
||||
void *user_data)
|
||||
{
|
||||
s->row_write_handler = handler;
|
||||
s->row_write_user_data = user_data;
|
||||
return 0;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
@ -1114,6 +1327,9 @@ SPAN_DECLARE(int) t42_decode_set_comment_handler(t42_decode_state_t *s,
|
|||
t4_row_write_handler_t handler,
|
||||
void *user_data)
|
||||
{
|
||||
s->max_comment_len = max_comment_len;
|
||||
s->comment_handler = handler;
|
||||
s->comment_user_data = user_data;
|
||||
return 0;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
@ -1140,7 +1356,7 @@ SPAN_DECLARE(uint32_t) t42_decode_get_image_length(t42_decode_state_t *s)
|
|||
|
||||
SPAN_DECLARE(int) t42_decode_get_compressed_image_size(t42_decode_state_t *s)
|
||||
{
|
||||
return 0;
|
||||
return s->compressed_image_size;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
|
@ -1152,6 +1368,7 @@ SPAN_DECLARE(int) t42_decode_new_plane(t42_decode_state_t *s)
|
|||
|
||||
SPAN_DECLARE(int) t42_decode_restart(t42_decode_state_t *s)
|
||||
{
|
||||
s->compressed_image_size = 0;
|
||||
return 0;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
@ -1172,6 +1389,11 @@ SPAN_DECLARE(t42_decode_state_t *) t42_decode_init(t42_decode_state_t *s,
|
|||
s->row_write_handler = handler;
|
||||
s->row_write_user_data = user_data;
|
||||
|
||||
s->buf_size = 0;
|
||||
s->compressed_buf = NULL;
|
||||
|
||||
t42_decode_restart(s);
|
||||
|
||||
return s;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* SpanDSP - a series of DSP components for telephony
|
||||
*
|
||||
* t42_t43_local.h - definitions for T.42 and T.43 shared processing
|
||||
*
|
||||
* Written by Steve Underwood <steveu@coppice.org>
|
||||
*
|
||||
* Copyright (C) 2011 Steve Underwood
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License version 2.1,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
|
||||
#if !defined(_T42_T43_LOCAL_H_)
|
||||
#define _T42_T43_LOCAL_H_
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
void set_illuminant_from_code(logging_state_t *logging, lab_params_t *s, const uint8_t code[4]);
|
||||
void set_gamut_from_code(logging_state_t *logging, lab_params_t *s, const uint8_t code[12]);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/*- End of file ------------------------------------------------------------*/
|
|
@ -54,6 +54,7 @@
|
|||
#include "spandsp/timezone.h"
|
||||
#include "spandsp/t4_rx.h"
|
||||
#include "spandsp/t4_tx.h"
|
||||
#include "spandsp/image_translate.h"
|
||||
#include "spandsp/t81_t82_arith_coding.h"
|
||||
#include "spandsp/t85.h"
|
||||
#if defined(SPANDSP_SUPPORT_T42)
|
||||
|
@ -77,6 +78,7 @@
|
|||
#endif
|
||||
#include "spandsp/private/t4_t6_decode.h"
|
||||
#include "spandsp/private/t4_t6_encode.h"
|
||||
#include "spandsp/private/image_translate.h"
|
||||
#include "spandsp/private/t4_rx.h"
|
||||
#include "spandsp/private/t4_tx.h"
|
||||
|
||||
|
@ -374,7 +376,7 @@ SPAN_DECLARE(int) t4_rx_put_byte(t4_rx_state_t *s, uint8_t byte)
|
|||
case T4_COMPRESSION_ITU_T85_L0:
|
||||
return t85_decode_put_byte(&s->decoder.t85, byte);
|
||||
}
|
||||
return TRUE;
|
||||
return T4_DECODE_OK;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
|
@ -399,7 +401,7 @@ SPAN_DECLARE(int) t4_rx_put_chunk(t4_rx_state_t *s, const uint8_t buf[], int len
|
|||
case T4_COMPRESSION_ITU_T85_L0:
|
||||
return t85_decode_put_chunk(&s->decoder.t85, buf, len);
|
||||
}
|
||||
return TRUE;
|
||||
return T4_DECODE_OK;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
|
|
|
@ -85,6 +85,7 @@
|
|||
#include "spandsp/timezone.h"
|
||||
#include "spandsp/t4_rx.h"
|
||||
#include "spandsp/t4_tx.h"
|
||||
#include "spandsp/image_translate.h"
|
||||
#include "spandsp/t81_t82_arith_coding.h"
|
||||
#include "spandsp/t85.h"
|
||||
#if defined(SPANDSP_SUPPORT_T42)
|
||||
|
@ -107,6 +108,7 @@
|
|||
#endif
|
||||
#include "spandsp/private/t4_t6_decode.h"
|
||||
#include "spandsp/private/t4_t6_encode.h"
|
||||
#include "spandsp/private/image_translate.h"
|
||||
#include "spandsp/private/t4_rx.h"
|
||||
#include "spandsp/private/t4_tx.h"
|
||||
|
||||
|
@ -764,9 +766,9 @@ SPAN_DECLARE(int) t4_t6_decode_put_chunk(t4_t6_decode_state_t *s, const uint8_t
|
|||
s->compressed_image_size += 8;
|
||||
byte = buf[i];
|
||||
if (put_bits(s, byte & 0xFF, 8))
|
||||
return TRUE;
|
||||
return T4_DECODE_OK;
|
||||
}
|
||||
return FALSE;
|
||||
return T4_DECODE_MORE_DATA;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
|
@ -875,10 +877,7 @@ SPAN_DECLARE(int) t4_t6_decode_restart(t4_t6_decode_state_t *s, int image_width)
|
|||
if (s->ref_runs)
|
||||
{
|
||||
memset(s->ref_runs, 0, run_space);
|
||||
s->ref_runs[0] =
|
||||
s->ref_runs[1] =
|
||||
s->ref_runs[2] =
|
||||
s->ref_runs[3] = s->image_width;
|
||||
s->ref_runs[0] = s->image_width;
|
||||
}
|
||||
if (s->row_buf)
|
||||
memset(s->row_buf, 0, s->bytes_per_row);
|
||||
|
|
|
@ -82,6 +82,7 @@
|
|||
#include "spandsp/timezone.h"
|
||||
#include "spandsp/t4_rx.h"
|
||||
#include "spandsp/t4_tx.h"
|
||||
#include "spandsp/image_translate.h"
|
||||
#include "spandsp/t81_t82_arith_coding.h"
|
||||
#include "spandsp/t85.h"
|
||||
#if defined(SPANDSP_SUPPORT_T42)
|
||||
|
@ -104,6 +105,7 @@
|
|||
#endif
|
||||
#include "spandsp/private/t4_t6_decode.h"
|
||||
#include "spandsp/private/t4_t6_encode.h"
|
||||
#include "spandsp/private/image_translate.h"
|
||||
#include "spandsp/private/t4_rx.h"
|
||||
#include "spandsp/private/t4_tx.h"
|
||||
|
||||
|
@ -544,6 +546,22 @@ static int row_to_run_lengths(uint32_t list[], const uint8_t row[], int width)
|
|||
list[entry++] = pos;
|
||||
}
|
||||
}
|
||||
#if defined(T4_STATE_DEBUGGING)
|
||||
/* Dump the runs of black and white for analysis */
|
||||
{
|
||||
int prev;
|
||||
int x;
|
||||
|
||||
printf("Runs (%d)", list[entry - 1]);
|
||||
prev = 0;
|
||||
for (x = 0; x < entry; x++)
|
||||
{
|
||||
printf(" %" PRIu32, list[x] - prev);
|
||||
prev = list[x];
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
#endif
|
||||
return entry;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
|
|
@ -54,6 +54,7 @@
|
|||
#include "spandsp/timezone.h"
|
||||
#include "spandsp/t4_rx.h"
|
||||
#include "spandsp/t4_tx.h"
|
||||
#include "spandsp/image_translate.h"
|
||||
#include "spandsp/t81_t82_arith_coding.h"
|
||||
#include "spandsp/t85.h"
|
||||
#if defined(SPANDSP_SUPPORT_T42)
|
||||
|
@ -76,6 +77,7 @@
|
|||
#endif
|
||||
#include "spandsp/private/t4_t6_decode.h"
|
||||
#include "spandsp/private/t4_t6_encode.h"
|
||||
#include "spandsp/private/image_translate.h"
|
||||
#include "spandsp/private/t4_rx.h"
|
||||
#include "spandsp/private/t4_tx.h"
|
||||
|
||||
|
@ -180,21 +182,39 @@ static int get_tiff_directory_info(t4_tx_state_t *s)
|
|||
float y_resolution;
|
||||
int i;
|
||||
t4_tx_tiff_state_t *t;
|
||||
uint16_t bits_per_sample;
|
||||
uint16_t samples_per_pixel;
|
||||
|
||||
t = &s->tiff;
|
||||
parm16 = 0;
|
||||
TIFFGetField(t->tiff_file, TIFFTAG_BITSPERSAMPLE, &parm16);
|
||||
if (parm16 != 1)
|
||||
return -1;
|
||||
bits_per_sample = parm16;
|
||||
parm16 = 0;
|
||||
TIFFGetField(t->tiff_file, TIFFTAG_SAMPLESPERPIXEL, &parm16);
|
||||
if (parm16 != 1)
|
||||
samples_per_pixel = parm16;
|
||||
if (samples_per_pixel == 1 && bits_per_sample == 1)
|
||||
t->image_type = T4_IMAGE_TYPE_BILEVEL;
|
||||
else if (samples_per_pixel == 1 && bits_per_sample == 8)
|
||||
t->image_type = T4_IMAGE_TYPE_GRAY_8BIT;
|
||||
else if (samples_per_pixel == 1 && bits_per_sample > 8)
|
||||
t->image_type = T4_IMAGE_TYPE_GRAY_12BIT;
|
||||
else if (samples_per_pixel == 3 && bits_per_sample == 8)
|
||||
t->image_type = T4_IMAGE_TYPE_COLOUR_8BIT;
|
||||
else if (samples_per_pixel == 3 && bits_per_sample > 8)
|
||||
t->image_type = T4_IMAGE_TYPE_COLOUR_12BIT;
|
||||
else
|
||||
return -1;
|
||||
#if 0
|
||||
/* Limit ourselves to plain black and white pages */
|
||||
if (t->image_type != T4_IMAGE_TYPE_BILEVEL)
|
||||
return -1;
|
||||
#endif
|
||||
parm32 = 0;
|
||||
TIFFGetField(t->tiff_file, TIFFTAG_IMAGEWIDTH, &parm32);
|
||||
s->image_width = parm32;
|
||||
parm32 = 0;
|
||||
TIFFGetField(t->tiff_file, TIFFTAG_IMAGELENGTH, &parm32);
|
||||
s->tiff.image_length =
|
||||
s->image_length = parm32;
|
||||
x_resolution = 0.0f;
|
||||
TIFFGetField(t->tiff_file, TIFFTAG_XRESOLUTION, &x_resolution);
|
||||
|
@ -206,8 +226,6 @@ static int get_tiff_directory_info(t4_tx_state_t *s)
|
|||
TIFFGetField(t->tiff_file, TIFFTAG_PHOTOMETRIC, &t->photo_metric);
|
||||
/* TIFFGetField(t->tiff_file, TIFFTAG_COMPRESSION, &t->????); */
|
||||
|
||||
if (t->photo_metric != PHOTOMETRIC_MINISWHITE)
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "%s: Photometric needs swapping.\n", s->tiff.file);
|
||||
t->fill_order = FILLORDER_LSB2MSB;
|
||||
|
||||
/* Allow a little range for the X resolution in centimeters. The spec doesn't pin down the
|
||||
|
@ -388,61 +406,102 @@ static int open_tiff_input_file(t4_tx_state_t *s, const char *file)
|
|||
static int tiff_row_read_handler(void *user_data, uint8_t buf[], size_t len)
|
||||
{
|
||||
t4_tx_state_t *s;
|
||||
int i;
|
||||
|
||||
s = (t4_tx_state_t *) user_data;
|
||||
if (s->tiff.row >= s->image_length)
|
||||
return 0;
|
||||
#if 0
|
||||
if (TIFFReadScanline(s->tiff.tiff_file, buf, s->tiff.row, 0) < 0)
|
||||
span_log(&s->logging, SPAN_LOG_WARNING, "%s: Error reading TIFF row.\n", s->tiff.file);
|
||||
#else
|
||||
memcpy(buf, &s->tiff.image_buffer[s->tiff.row*len], len);
|
||||
#endif
|
||||
if (s->tiff.photo_metric != PHOTOMETRIC_MINISWHITE)
|
||||
{
|
||||
for (i = 0; i < len; i++)
|
||||
buf[i] = ~buf[i];
|
||||
}
|
||||
if (s->tiff.fill_order != FILLORDER_LSB2MSB)
|
||||
bit_reverse(buf, buf, len);
|
||||
s->tiff.row++;
|
||||
return len;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static int row_read(void *user_data, uint8_t buf[], size_t len)
|
||||
{
|
||||
t4_tx_state_t *s;
|
||||
|
||||
s = (t4_tx_state_t *) user_data;
|
||||
|
||||
if (s->tiff.raw_row >= s->tiff.image_length)
|
||||
return 0;
|
||||
if (TIFFReadScanline(s->tiff.tiff_file, buf, s->tiff.raw_row, 0) < 0)
|
||||
return 0;
|
||||
s->tiff.raw_row++;
|
||||
return len;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static int read_tiff_image(t4_tx_state_t *s)
|
||||
{
|
||||
int total_len;
|
||||
int len;
|
||||
int bytes_per_row;
|
||||
int i;
|
||||
uint8_t *t;
|
||||
image_translate_state_t *translator;
|
||||
int mode;
|
||||
|
||||
s->image_width = 0;
|
||||
TIFFGetField(s->tiff.tiff_file, TIFFTAG_IMAGEWIDTH, &s->image_width);
|
||||
s->image_length = 0;
|
||||
TIFFGetField(s->tiff.tiff_file, TIFFTAG_IMAGELENGTH, &s->image_length);
|
||||
bytes_per_row = TIFFScanlineSize(s->tiff.tiff_file);
|
||||
s->tiff.image_size = s->image_length*bytes_per_row;
|
||||
if (s->tiff.image_size >= s->tiff.image_buffer_size)
|
||||
if (s->tiff.image_type != T4_IMAGE_TYPE_BILEVEL)
|
||||
{
|
||||
if ((t = realloc(s->tiff.image_buffer, s->tiff.image_size)) == NULL)
|
||||
/* 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;
|
||||
s->tiff.image_buffer_size += s->tiff.image_size;
|
||||
s->tiff.image_buffer = t;
|
||||
}
|
||||
|
||||
#if 1
|
||||
for (i = 0, total_len = 0; total_len < s->tiff.image_size; i++, total_len += len)
|
||||
{
|
||||
if ((len = TIFFReadEncodedStrip(s->tiff.tiff_file, i, &s->tiff.image_buffer[total_len], s->tiff.image_size - total_len)) < 0)
|
||||
if ((translator = image_translate_init(NULL, mode, s->image_width, s->image_length, 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);
|
||||
s->metadata.x_resolution = T4_X_RESOLUTION_R8;
|
||||
s->metadata.y_resolution = T4_Y_RESOLUTION_FINE;
|
||||
s->tiff.image_size = (s->image_width*s->image_length + 7)/8;
|
||||
if (s->tiff.image_size >= s->tiff.image_buffer_size)
|
||||
{
|
||||
span_log(&s->logging, SPAN_LOG_WARNING, "%s: Read error.\n", s->tiff.file);
|
||||
return -1;
|
||||
if ((t = realloc(s->tiff.image_buffer, s->tiff.image_size)) == NULL)
|
||||
return -1;
|
||||
s->tiff.image_buffer_size = s->tiff.image_size;
|
||||
s->tiff.image_buffer = t;
|
||||
}
|
||||
s->tiff.raw_row = 0;
|
||||
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);
|
||||
image_translate_free(translator);
|
||||
}
|
||||
else
|
||||
{
|
||||
s->tiff.image_size = s->image_length*TIFFScanlineSize(s->tiff.tiff_file);
|
||||
if (s->tiff.image_size >= s->tiff.image_buffer_size)
|
||||
{
|
||||
if ((t = realloc(s->tiff.image_buffer, s->tiff.image_size)) == NULL)
|
||||
return -1;
|
||||
s->tiff.image_buffer_size = s->tiff.image_size;
|
||||
s->tiff.image_buffer = t;
|
||||
}
|
||||
|
||||
for (i = 0, total_len = 0; total_len < s->tiff.image_size; i++, total_len += len)
|
||||
{
|
||||
if ((len = TIFFReadEncodedStrip(s->tiff.tiff_file, i, &s->tiff.image_buffer[total_len], s->tiff.image_size - total_len)) < 0)
|
||||
{
|
||||
span_log(&s->logging, SPAN_LOG_WARNING, "%s: Read error.\n", s->tiff.file);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (s->tiff.photo_metric != PHOTOMETRIC_MINISWHITE)
|
||||
{
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "%s: Photometric needs swapping.\n", s->tiff.file);
|
||||
for (i = 0; i < s->tiff.image_size; i++)
|
||||
s->tiff.image_buffer[i] = ~s->tiff.image_buffer[i];
|
||||
}
|
||||
if (s->tiff.fill_order != FILLORDER_LSB2MSB)
|
||||
bit_reverse(s->tiff.image_buffer, s->tiff.image_buffer, s->tiff.image_size);
|
||||
}
|
||||
#endif
|
||||
s->tiff.row = 0;
|
||||
return s->image_length;
|
||||
}
|
||||
|
@ -901,8 +960,6 @@ SPAN_DECLARE(int) t4_tx_get_chunk(t4_tx_state_t *s, uint8_t buf[], int max_len)
|
|||
|
||||
SPAN_DECLARE(int) t4_tx_start_page(t4_tx_state_t *s)
|
||||
{
|
||||
uint32_t image_length;
|
||||
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Start tx page %d - compression %s\n", s->current_page, t4_encoding_to_str(s->line_encoding));
|
||||
if (s->current_page > s->stop_page)
|
||||
return -1;
|
||||
|
@ -911,7 +968,7 @@ SPAN_DECLARE(int) t4_tx_start_page(t4_tx_state_t *s)
|
|||
if (!TIFFSetDirectory(s->tiff.tiff_file, (tdir_t) s->current_page))
|
||||
return -1;
|
||||
get_tiff_directory_info(s);
|
||||
if ((image_length = read_tiff_image(s)) < 0)
|
||||
if (read_tiff_image(s) < 0)
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -286,13 +286,13 @@ static int check_bih(t85_decode_state_t *s)
|
|||
#endif
|
||||
{
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "BIH invalid. Fixed bytes do not contain expected values.\n");
|
||||
return T85_INVALID_DATA;
|
||||
return T4_DECODE_INVALID_DATA;
|
||||
}
|
||||
/* P - Number of bit planes */
|
||||
if (s->buffer[2] < s->min_bit_planes || s->buffer[2] > s->max_bit_planes)
|
||||
{
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "BIH invalid. %d bit planes. Should be %d to %d.\n", s->buffer[2], s->min_bit_planes, s->max_bit_planes);
|
||||
return T85_INVALID_DATA;
|
||||
return T4_DECODE_INVALID_DATA;
|
||||
}
|
||||
s->bit_planes = s->buffer[2];
|
||||
s->current_bit_plane = 0;
|
||||
|
@ -302,38 +302,38 @@ static int check_bih(t85_decode_state_t *s)
|
|||
if (s->xd == 0 || (s->max_xd && s->xd > s->max_xd))
|
||||
{
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "BIH invalid. Width is %" PRIu32 "\n", s->xd);
|
||||
return T85_INVALID_DATA;
|
||||
return T4_DECODE_INVALID_DATA;
|
||||
}
|
||||
/* YD - Vertical image size at layer D */
|
||||
s->yd = pack_32(&s->buffer[8]);
|
||||
if (s->yd == 0 || (s->max_yd && s->yd > s->max_yd))
|
||||
{
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "BIH invalid. Length is %" PRIu32 "\n", s->yd);
|
||||
return T85_INVALID_DATA;
|
||||
return T4_DECODE_INVALID_DATA;
|
||||
}
|
||||
/* L0 - Rows per stripe, at the lowest resolution */
|
||||
s->l0 = pack_32(&s->buffer[12]);
|
||||
if (s->l0 == 0)
|
||||
{
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "BIH invalid. L0 is %" PRIu32 "\n", s->l0);
|
||||
return T85_INVALID_DATA;
|
||||
return T4_DECODE_INVALID_DATA;
|
||||
}
|
||||
/* MX - Maximum horizontal offset allowed for AT pixel */
|
||||
s->mx = s->buffer[16];
|
||||
if (s->mx > 127)
|
||||
{
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "BIH invalid. MX is %d\n", s->mx);
|
||||
return T85_INVALID_DATA;
|
||||
return T4_DECODE_INVALID_DATA;
|
||||
}
|
||||
/* Options byte */
|
||||
s->options = s->buffer[19];
|
||||
if ((s->options & 0x97))
|
||||
{
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "BIH invalid. Options are 0x%X\n", s->options);
|
||||
return T85_INVALID_DATA;
|
||||
return T4_DECODE_INVALID_DATA;
|
||||
}
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "BIH is OK. Image is %" PRIu32 "x%" PRIu32 " pixels\n", s->xd, s->yd);
|
||||
return T85_OK;
|
||||
return T4_DECODE_OK;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
|
@ -368,7 +368,7 @@ SPAN_DECLARE(int) t85_decode_put_byte(t85_decode_state_t *s, int byte)
|
|||
if (byte < 0)
|
||||
{
|
||||
t85_decode_rx_status(s, byte);
|
||||
return (s->y >= s->yd) ? T85_OK : T85_MORE_DATA;
|
||||
return (s->y >= s->yd) ? T4_DECODE_OK : T4_DECODE_MORE_DATA;
|
||||
}
|
||||
data[0] = byte;
|
||||
return t85_decode_put_chunk(s, data, 1);
|
||||
|
@ -399,8 +399,8 @@ SPAN_DECLARE(int) t85_decode_put_chunk(t85_decode_state_t *s,
|
|||
s->bie_len += i;
|
||||
cnt = i;
|
||||
if (s->bie_len < 20)
|
||||
return T85_MORE_DATA;
|
||||
if ((ret = check_bih(s)) != T85_OK)
|
||||
return T4_DECODE_MORE_DATA;
|
||||
if ((ret = check_bih(s)) != T4_DECODE_OK)
|
||||
return ret;
|
||||
/* Set up the two/three row buffer */
|
||||
bytes_per_row = (s->xd + 7) >> 3;
|
||||
|
@ -409,7 +409,7 @@ SPAN_DECLARE(int) t85_decode_put_chunk(t85_decode_state_t *s,
|
|||
{
|
||||
/* We need to expand the 3 row buffer */
|
||||
if ((buf = (uint8_t *) realloc(s->row_buf, min_len)) == NULL)
|
||||
return T85_NOMEM;
|
||||
return T4_DECODE_NOMEM;
|
||||
s->row_buf = buf;
|
||||
s->row_buf_len = min_len;
|
||||
}
|
||||
|
@ -500,11 +500,11 @@ SPAN_DECLARE(int) t85_decode_put_chunk(t85_decode_state_t *s,
|
|||
s->buf_len = 0;
|
||||
|
||||
if (s->interrupt)
|
||||
return T85_INTERRUPT;
|
||||
return T4_DECODE_INTERRUPT;
|
||||
break;
|
||||
case T82_ABORT:
|
||||
s->buf_len = 0;
|
||||
return T85_ABORTED;
|
||||
return T4_DECODE_ABORTED;
|
||||
case T82_COMMENT:
|
||||
s->buf_needed = 6;
|
||||
if (s->buf_len < 6)
|
||||
|
@ -531,7 +531,7 @@ SPAN_DECLARE(int) t85_decode_put_chunk(t85_decode_state_t *s,
|
|||
s->buf_len = 0;
|
||||
|
||||
if (s->at_moves >= T85_ATMOVES_MAX)
|
||||
return T85_INVALID_DATA;
|
||||
return T4_DECODE_INVALID_DATA;
|
||||
s->at_row[s->at_moves] = pack_32(&s->buffer[2]);
|
||||
s->at_tx[s->at_moves] = s->buffer[6];
|
||||
if (s->at_tx[s->at_moves] > s->mx
|
||||
|
@ -540,7 +540,7 @@ SPAN_DECLARE(int) t85_decode_put_chunk(t85_decode_state_t *s,
|
|||
||
|
||||
s->buffer[7] != 0)
|
||||
{
|
||||
return T85_INVALID_DATA;
|
||||
return T4_DECODE_INVALID_DATA;
|
||||
}
|
||||
s->at_moves++;
|
||||
break;
|
||||
|
@ -552,12 +552,12 @@ SPAN_DECLARE(int) t85_decode_put_chunk(t85_decode_state_t *s,
|
|||
s->buf_len = 0;
|
||||
|
||||
if (!(s->options & T85_VLENGTH))
|
||||
return T85_INVALID_DATA;
|
||||
return T4_DECODE_INVALID_DATA;
|
||||
s->options &= ~T85_VLENGTH;
|
||||
y = pack_32(&s->buffer[2]);
|
||||
/* An update to the image length is not allowed to stretch it. */
|
||||
if (y > s->yd)
|
||||
return T85_INVALID_DATA;
|
||||
return T4_DECODE_INVALID_DATA;
|
||||
s->yd = y;
|
||||
break;
|
||||
case T82_SDNORM:
|
||||
|
@ -567,12 +567,12 @@ SPAN_DECLARE(int) t85_decode_put_chunk(t85_decode_state_t *s,
|
|||
/* A plain SDNORM or SDRST with no peek ahead required */
|
||||
s->buf_len = 0;
|
||||
if (finish_sde(s))
|
||||
return T85_INTERRUPT;
|
||||
return T4_DECODE_INTERRUPT;
|
||||
/* Check whether this was the last SDE */
|
||||
if (s->y >= s->yd)
|
||||
{
|
||||
s->compressed_image_size -= (len - cnt);
|
||||
return T85_OK;
|
||||
return T4_DECODE_OK;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -594,12 +594,12 @@ SPAN_DECLARE(int) t85_decode_put_chunk(t85_decode_state_t *s,
|
|||
cnt--;
|
||||
/* Process the T82_SDNORM or T82_SDRST */
|
||||
if (finish_sde(s))
|
||||
return T85_INTERRUPT;
|
||||
return T4_DECODE_INTERRUPT;
|
||||
/* Check whether this was the last SDE */
|
||||
if (s->y >= s->yd)
|
||||
{
|
||||
s->compressed_image_size -= (len - cnt);
|
||||
return T85_OK;
|
||||
return T4_DECODE_OK;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -613,12 +613,12 @@ SPAN_DECLARE(int) t85_decode_put_chunk(t85_decode_state_t *s,
|
|||
|
||||
/* Process the T82_SDNORM or T82_SDRST */
|
||||
if (finish_sde(s))
|
||||
return T85_INTERRUPT;
|
||||
return T4_DECODE_INTERRUPT;
|
||||
/* Check whether this was the last SDE */
|
||||
if (s->y >= s->yd)
|
||||
{
|
||||
s->compressed_image_size -= (len - cnt);
|
||||
return T85_OK;
|
||||
return T4_DECODE_OK;
|
||||
}
|
||||
/* Recycle the two peek-ahead marker sequence bytes to
|
||||
be processed later. */
|
||||
|
@ -639,12 +639,12 @@ SPAN_DECLARE(int) t85_decode_put_chunk(t85_decode_state_t *s,
|
|||
y = pack_32(&s->buffer[4]);
|
||||
/* An update to the image length is not allowed to stretch it. */
|
||||
if (y > s->yd)
|
||||
return T85_INVALID_DATA;
|
||||
return T4_DECODE_INVALID_DATA;
|
||||
/* Things look OK, so accept this new length, and proceed. */
|
||||
s->yd = y;
|
||||
/* Now process the T82_SDNORM or T82_SDRST */
|
||||
if (finish_sde(s))
|
||||
return T85_INTERRUPT;
|
||||
return T4_DECODE_INTERRUPT;
|
||||
/* We might be at the end of the image now, but even if we are
|
||||
there should still be a final training T82_SDNORM or T82_SDRST
|
||||
that we should pick up. When we do, we won't wait for further
|
||||
|
@ -653,7 +653,7 @@ SPAN_DECLARE(int) t85_decode_put_chunk(t85_decode_state_t *s,
|
|||
break;
|
||||
default:
|
||||
s->buf_len = 0;
|
||||
return T85_INVALID_DATA;
|
||||
return T4_DECODE_INVALID_DATA;
|
||||
}
|
||||
}
|
||||
else if (cnt < len && data[cnt] == T82_ESC)
|
||||
|
@ -665,15 +665,15 @@ SPAN_DECLARE(int) t85_decode_put_chunk(t85_decode_state_t *s,
|
|||
/* We have found PSCD bytes */
|
||||
cnt += decode_pscd(s, data + cnt, len - cnt);
|
||||
if (s->interrupt)
|
||||
return T85_INTERRUPT;
|
||||
return T4_DECODE_INTERRUPT;
|
||||
/* We should only have stopped processing PSCD if
|
||||
we ran out of data, or hit a T82_ESC */
|
||||
if (cnt < len && data[cnt] != T82_ESC)
|
||||
return T85_INVALID_DATA;
|
||||
return T4_DECODE_INVALID_DATA;
|
||||
}
|
||||
}
|
||||
|
||||
return T85_MORE_DATA;
|
||||
return T4_DECODE_MORE_DATA;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
|
|
|
@ -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, row_read, &im);
|
||||
s = image_translate_init(s, IMAGE_TRANSLATE_FROM_GRAY_16, im.width, im.length, -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, row_read, &im);
|
||||
s = image_translate_init(s, IMAGE_TRANSLATE_FROM_GRAY_8, im.width, im.length, -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, row_read, &im);
|
||||
s = image_translate_init(s, IMAGE_TRANSLATE_FROM_COLOUR_16, im.width, im.length, -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, row_read, &im);
|
||||
s = image_translate_init(s, IMAGE_TRANSLATE_FROM_COLOUR_8, im.width, im.length, -1, -1, row_read, &im);
|
||||
get_flattened_image(s, TRUE);
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
@ -331,13 +331,13 @@ static void grow_tests_colour8(void)
|
|||
}
|
||||
}
|
||||
|
||||
s1 = image_translate_init(s1, IMAGE_TRANSLATE_FROM_COLOUR_8, im.width, im.length, 200, row_read, &im);
|
||||
s1 = image_translate_init(s1, IMAGE_TRANSLATE_FROM_COLOUR_8, im.width, im.length, 200, -1, row_read, &im);
|
||||
|
||||
get_flattened_image(s1, FALSE);
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static void lenna_tests(int output_width, const char *file)
|
||||
static void lenna_tests(int output_width, int output_length_scaling, const char *file)
|
||||
{
|
||||
TIFF *in_file;
|
||||
TIFF *out_file;
|
||||
|
@ -355,6 +355,9 @@ static void lenna_tests(int output_width, const char *file)
|
|||
image_translate_state_t bw;
|
||||
image_translate_state_t *s = &bw;
|
||||
image_descriptor_t im;
|
||||
float x_resolution;
|
||||
float y_resolution;
|
||||
uint16_t res_unit;
|
||||
|
||||
printf("Dithering Lenna from colour to bi-level test\n");
|
||||
if ((in_file = TIFFOpen(INPUT_TIFF_FILE_NAME, "r")) == NULL)
|
||||
|
@ -367,11 +370,17 @@ static void lenna_tests(int output_width, const char *file)
|
|||
TIFFGetField(in_file, TIFFTAG_IMAGELENGTH, &image_length);
|
||||
if (image_length <= 0)
|
||||
return;
|
||||
x_resolution = 200.0;
|
||||
TIFFGetField(in_file, TIFFTAG_XRESOLUTION, &x_resolution);
|
||||
y_resolution = 200.0;
|
||||
TIFFGetField(in_file, TIFFTAG_YRESOLUTION, &y_resolution);
|
||||
res_unit = RESUNIT_INCH;
|
||||
TIFFSetField(in_file, TIFFTAG_RESOLUTIONUNIT, &res_unit);
|
||||
bits_per_sample = 0;
|
||||
TIFFGetField(in_file, TIFFTAG_BITSPERSAMPLE, &bits_per_sample);
|
||||
samples_per_pixel = 0;
|
||||
TIFFGetField(in_file, TIFFTAG_SAMPLESPERPIXEL, &samples_per_pixel);
|
||||
printf("Original image is %d x %d, %d bits per sample, %d samples per pixel\n", image_width, image_length, bits_per_sample, samples_per_pixel);
|
||||
printf("Original image is %d x %d, %f x %f resolution, %d bits per sample, %d samples per pixel\n", image_width, image_length, x_resolution, y_resolution, bits_per_sample, samples_per_pixel);
|
||||
if ((image = malloc(image_width*image_length*samples_per_pixel)) == NULL)
|
||||
return;
|
||||
for (total = 0, i = 0; i < 1000; i++)
|
||||
|
@ -389,13 +398,18 @@ static void lenna_tests(int output_width, const char *file)
|
|||
printf("Image size %d %d\n", total, image_width*image_length*samples_per_pixel);
|
||||
TIFFClose(in_file);
|
||||
|
||||
if (output_length_scaling > 0)
|
||||
output_length = (double) image_length*output_length_scaling*output_width/image_width;
|
||||
else
|
||||
output_length = -1;
|
||||
|
||||
im.image = image;
|
||||
im.width = image_width;
|
||||
im.length = image_length;
|
||||
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, row_read, &im);
|
||||
s = image_translate_init(s, IMAGE_TRANSLATE_FROM_COLOUR_8, image_width, image_length, output_width, output_length, row_read, &im);
|
||||
output_width = image_translate_get_output_width(s);
|
||||
output_length = image_translate_get_output_length(s);
|
||||
|
||||
|
@ -403,6 +417,11 @@ static void lenna_tests(int output_width, const char *file)
|
|||
return;
|
||||
TIFFSetField(out_file, TIFFTAG_IMAGEWIDTH, output_width);
|
||||
TIFFSetField(out_file, TIFFTAG_IMAGELENGTH, output_length);
|
||||
TIFFSetField(out_file, TIFFTAG_XRESOLUTION, x_resolution);
|
||||
if (output_length_scaling > 0)
|
||||
y_resolution *= output_length_scaling;
|
||||
TIFFSetField(out_file, TIFFTAG_YRESOLUTION, y_resolution);
|
||||
TIFFSetField(out_file, TIFFTAG_RESOLUTIONUNIT, res_unit);
|
||||
TIFFSetField(out_file, TIFFTAG_BITSPERSAMPLE, 1);
|
||||
TIFFSetField(out_file, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
|
||||
TIFFSetField(out_file, TIFFTAG_SAMPLESPERPIXEL, 1);
|
||||
|
@ -441,9 +460,10 @@ int main(int argc, char **argv)
|
|||
grow_tests_colour8();
|
||||
#endif
|
||||
#if 1
|
||||
lenna_tests(0, "lenna-bw.tif");
|
||||
lenna_tests(1728, "lenna-bw-1728.tif");
|
||||
lenna_tests(200, "lenna-bw-200.tif");
|
||||
lenna_tests(0, 0, "lenna-bw.tif");
|
||||
lenna_tests(200, 0, "lenna-bw-200.tif");
|
||||
lenna_tests(1728, 0, "lenna-bw-1728.tif");
|
||||
lenna_tests(1728, 2, "lenna-bw-1728-superfine.tif");
|
||||
#endif
|
||||
printf("Tests passed.\n");
|
||||
return 0;
|
||||
|
|
|
@ -45,7 +45,8 @@
|
|||
|
||||
#include "spandsp.h"
|
||||
|
||||
#define IN_FILE_NAME "../test-data/itu/t24/F21_200.TIF"
|
||||
//#define IN_FILE_NAME "../test-data/itu/t24/F21_200.TIF"
|
||||
#define IN_FILE_NAME "../test-data/itu/t24/F21B400.TIF"
|
||||
#define OUT_FILE_NAME "t42_tests_receive.tif"
|
||||
|
||||
uint8_t data5[50000000];
|
||||
|
@ -59,55 +60,6 @@ lab_params_t lab_param;
|
|||
|
||||
int write_row = 0;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float L;
|
||||
float a;
|
||||
float b;
|
||||
} cielab_t;
|
||||
|
||||
#if 0
|
||||
static void generate_luts(void)
|
||||
{
|
||||
float r;
|
||||
uint8_t srgb;
|
||||
int i;
|
||||
|
||||
printf("static const float srgb_to_linear[256] =\n");
|
||||
printf("{\n");
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
/* Start with "i" as the sRGB value */
|
||||
r = i/256.0f;
|
||||
|
||||
/* sRGB to Linear RGB */
|
||||
r = (r > 0.04045f) ? powf((r + 0.055f)/1.055f, 2.4f) : r/12.92f;
|
||||
|
||||
printf((i < 255) ? " %f,\n" : " %f\n", r);
|
||||
}
|
||||
printf("};\n");
|
||||
|
||||
printf("static const uint8_t linear_to_srgb[4096] =\n");
|
||||
printf("{\n");
|
||||
for (i = 0; i < 4096; i++)
|
||||
{
|
||||
/* Start with "i" as the linear RGB value */
|
||||
/* Linear RGB to sRGB */
|
||||
r = i/4096.0f;
|
||||
|
||||
r = (r > 0.0031308f) ? (1.055f*powf(r, 1.0f/2.4f) - 0.055f) : r*12.92f;
|
||||
|
||||
r = floorf(r*256.0f);
|
||||
|
||||
srgb = (r < 0) ? 0 : (r <= 255) ? r : 255;
|
||||
|
||||
printf((i < 4095) ? " %d,\n" : " %d\n", srgb);
|
||||
}
|
||||
printf("};\n");
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
#endif
|
||||
|
||||
static __inline__ uint16_t pack_16(uint8_t *s)
|
||||
{
|
||||
uint16_t value;
|
||||
|
@ -159,7 +111,6 @@ static int t85_comment_handler(void *user_data, const uint8_t buf[], size_t len)
|
|||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char kk[256];
|
||||
TIFF *tif;
|
||||
uint32_t w;
|
||||
uint32_t h;
|
||||
|
@ -194,18 +145,17 @@ int main(int argc, char *argv[])
|
|||
uint16_t *yyya;
|
||||
uint16_t *yyyb;
|
||||
uint16_t *yyyz;
|
||||
logging_state_t *logging;
|
||||
|
||||
printf("Demo of ITU/Lab library.\n");
|
||||
|
||||
logging = span_log_init(NULL, SPAN_LOG_FLOW, "T.42");
|
||||
|
||||
TIFF_FX_init();
|
||||
|
||||
set_lab_illuminant(&lab_param, 0.9638f, 1.0f, 0.8245f);
|
||||
set_lab_gamut(&lab_param, 0, 100, -85, 85, -75, 125, FALSE);
|
||||
|
||||
#if 0
|
||||
generate_luts();
|
||||
#endif
|
||||
|
||||
source_file = (argc > 1) ? argv[1] : IN_FILE_NAME;
|
||||
/* sRGB to ITU */
|
||||
if ((tif = TIFFOpen(source_file, "r")) == NULL)
|
||||
|
@ -307,6 +257,7 @@ int main(int argc, char *argv[])
|
|||
printf("Unexpected compression %d\n", compression);
|
||||
break;
|
||||
}
|
||||
|
||||
if (process_raw)
|
||||
{
|
||||
nstrips = TIFFNumberOfStrips(tif);
|
||||
|
@ -337,7 +288,7 @@ int main(int argc, char *argv[])
|
|||
t85_decode_init(&t85_dec, t85_row_write_handler, NULL);
|
||||
t85_decode_set_comment_handler(&t85_dec, 1000, t85_comment_handler, NULL);
|
||||
result = t85_decode_put_chunk(&t85_dec, data, total_len);
|
||||
if (result == T85_MORE_DATA)
|
||||
if (result == T4_DECODE_MORE_DATA)
|
||||
result = t85_decode_put_byte(&t85_dec, SIG_STATUS_END_OF_DATA);
|
||||
len = t85_decode_get_compressed_image_size(&t85_dec);
|
||||
printf("Compressed image is %d bytes, %d rows\n", len/8, write_row);
|
||||
|
@ -396,7 +347,7 @@ int main(int argc, char *argv[])
|
|||
len = t85_decode_get_compressed_image_size(&t85_dec);
|
||||
printf("Compressed image is %d bytes, %d rows\n", len/8, write_row);
|
||||
}
|
||||
if (result == T85_MORE_DATA)
|
||||
if (result == T4_DECODE_MORE_DATA)
|
||||
{
|
||||
printf("More\n");
|
||||
result = t85_decode_put_byte(&t85_dec, SIG_STATUS_END_OF_DATA);
|
||||
|
@ -435,7 +386,7 @@ int main(int argc, char *argv[])
|
|||
TIFFSetField(tif, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH);
|
||||
TIFFSetField(tif, TIFFTAG_SOFTWARE, "spandsp");
|
||||
TIFFSetField(tif, TIFFTAG_IMAGEDESCRIPTION, "Test");
|
||||
TIFFSetField(tif, TIFFTAG_DATETIME, "2011/02/03 12:30:45");
|
||||
TIFFSetField(tif, TIFFTAG_DATETIME, "2012/07/03 12:30:45");
|
||||
TIFFSetField(tif, TIFFTAG_MAKE, "soft-switch.org");
|
||||
TIFFSetField(tif, TIFFTAG_MODEL, "spandsp");
|
||||
TIFFSetField(tif, TIFFTAG_HOSTCOMPUTER, "i7.coppice.org");
|
||||
|
@ -477,9 +428,9 @@ int main(int argc, char *argv[])
|
|||
{
|
||||
printf("YYY ITULAB\n");
|
||||
|
||||
if (!t42_itulab_to_itulab((tdata_t) &outptr, &outsize, data, off, w, h, kk, 256))
|
||||
if (!t42_itulab_to_itulab(logging, (tdata_t) &outptr, &outsize, data, off, w, h))
|
||||
{
|
||||
printf("Failed to convert to ITULAB - %s\n", kk);
|
||||
printf("Failed to convert to ITULAB\n");
|
||||
return 1;
|
||||
}
|
||||
free(data);
|
||||
|
@ -500,9 +451,9 @@ int main(int argc, char *argv[])
|
|||
|
||||
set_lab_illuminant(&lab_param, 0.9638f, 1.0f, 0.8245f);
|
||||
set_lab_gamut(&lab_param, 0, 100, -85, 85, -75, 125, FALSE);
|
||||
if (!t42_srgb_to_itulab(&lab_param, (tdata_t) &outptr, &outsize, data, off, w, h, kk, 256))
|
||||
if (!t42_srgb_to_itulab(logging, &lab_param, (tdata_t) &outptr, &outsize, data, off, w, h))
|
||||
{
|
||||
printf("Failed to convert to ITULAB - %s\n", kk);
|
||||
printf("Failed to convert to ITULAB\n");
|
||||
return 1;
|
||||
}
|
||||
end = rdtscll();
|
||||
|
@ -539,7 +490,7 @@ int main(int argc, char *argv[])
|
|||
TIFFSetField(tif, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH);
|
||||
TIFFSetField(tif, TIFFTAG_SOFTWARE, "spandsp");
|
||||
TIFFSetField(tif, TIFFTAG_IMAGEDESCRIPTION, "Test");
|
||||
TIFFSetField(tif, TIFFTAG_DATETIME, "2011/02/03 12:30:45");
|
||||
TIFFSetField(tif, TIFFTAG_DATETIME, "2012/07/03 12:30:45");
|
||||
TIFFSetField(tif, TIFFTAG_MAKE, "soft-switch.org");
|
||||
TIFFSetField(tif, TIFFTAG_MODEL, "spandsp");
|
||||
TIFFSetField(tif, TIFFTAG_HOSTCOMPUTER, "i7.coppice.org");
|
||||
|
@ -564,22 +515,22 @@ int main(int argc, char *argv[])
|
|||
start = rdtscll();
|
||||
data2 = NULL;
|
||||
totdata = 0;
|
||||
t42_itulab_to_JPEG(&lab_param, (void **) &data2, &totdata, data, off, kk, 256);
|
||||
t42_itulab_to_jpeg(logging, &lab_param, (void **) &data2, &totdata, data, off);
|
||||
end = rdtscll();
|
||||
printf("Duration %" PRIu64 "\n", end - start);
|
||||
printf("Compressed length %d (%p)\n", totdata, data2);
|
||||
if (TIFFWriteRawStrip(tif, 0, data2, totdata) < 0)
|
||||
{
|
||||
printf("Failed to convert from ITULAB - %s\n", kk);
|
||||
printf("Failed to convert from ITULAB\n");
|
||||
return 1;
|
||||
}
|
||||
free(data);
|
||||
#else
|
||||
data2 = malloc(totdata);
|
||||
start = rdtscll();
|
||||
if (!t42_itulab_to_srgb(&lab_param, data2, &off, data, off, &w, &h, kk, 256))
|
||||
if (!t42_itulab_to_srgb(logging, &lab_param, data2, &off, data, off, &w, &h))
|
||||
{
|
||||
printf("Failed to convert from ITULAB - %s\n", kk);
|
||||
printf("Failed to convert from ITULAB\n");
|
||||
return 1;
|
||||
}
|
||||
end = rdtscll();
|
||||
|
|
|
@ -293,27 +293,32 @@ int main(int argc, char *argv[])
|
|||
properly. */
|
||||
min_row_bits = 50;
|
||||
block_size = 0;
|
||||
while ((opt = getopt(argc, argv, "126b:m:")) != -1)
|
||||
while ((opt = getopt(argc, argv, "b:c:m:")) != -1)
|
||||
{
|
||||
switch (opt)
|
||||
{
|
||||
case '1':
|
||||
compression = T4_COMPRESSION_ITU_T4_1D;
|
||||
compression_step = -1;
|
||||
break;
|
||||
case '2':
|
||||
compression = T4_COMPRESSION_ITU_T4_2D;
|
||||
compression_step = -1;
|
||||
break;
|
||||
case '6':
|
||||
compression = T4_COMPRESSION_ITU_T6;
|
||||
compression_step = -1;
|
||||
break;
|
||||
case 'b':
|
||||
block_size = atoi(optarg);
|
||||
if (block_size > 1024)
|
||||
block_size = 1024;
|
||||
break;
|
||||
case 'c':
|
||||
if (strcmp(optarg, "T41D") == 0)
|
||||
{
|
||||
compression = T4_COMPRESSION_ITU_T4_1D;
|
||||
compression_step = -1;
|
||||
}
|
||||
else if (strcmp(optarg, "T42D") == 0)
|
||||
{
|
||||
compression = T4_COMPRESSION_ITU_T4_2D;
|
||||
compression_step = -1;
|
||||
}
|
||||
else if (strcmp(optarg, "T6") == 0)
|
||||
{
|
||||
compression = T4_COMPRESSION_ITU_T6;
|
||||
compression_step = -1;
|
||||
}
|
||||
break;
|
||||
case 'm':
|
||||
min_row_bits = atoi(optarg);
|
||||
break;
|
||||
|
|
|
@ -542,7 +542,7 @@ int main(int argc, char *argv[])
|
|||
#if 1
|
||||
printf("Testing image_function->compress->decompress->image_function\n");
|
||||
/* Send end gets image from a function */
|
||||
if (t4_tx_init(&send_state, FALSE, -1, -1) == NULL)
|
||||
if (t4_tx_init(&send_state, NULL, -1, -1) == NULL)
|
||||
{
|
||||
printf("Failed to init T.4 tx\n");
|
||||
exit(2);
|
||||
|
@ -680,9 +680,6 @@ int main(int argc, char *argv[])
|
|||
exit(2);
|
||||
}
|
||||
span_log_set_level(&receive_state.logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_SHOW_TAG | SPAN_LOG_FLOW);
|
||||
t4_rx_set_x_resolution(&receive_state, t4_tx_get_x_resolution(&send_state));
|
||||
t4_rx_set_y_resolution(&receive_state, t4_tx_get_y_resolution(&send_state));
|
||||
t4_rx_set_image_width(&receive_state, t4_tx_get_image_width(&send_state));
|
||||
|
||||
/* Now send and receive all the pages in the source TIFF file */
|
||||
sends = 0;
|
||||
|
@ -725,6 +722,9 @@ int main(int argc, char *argv[])
|
|||
|
||||
if (t4_tx_start_page(&send_state))
|
||||
break;
|
||||
t4_rx_set_x_resolution(&receive_state, t4_tx_get_x_resolution(&send_state));
|
||||
t4_rx_set_y_resolution(&receive_state, t4_tx_get_y_resolution(&send_state));
|
||||
t4_rx_set_image_width(&receive_state, t4_tx_get_image_width(&send_state));
|
||||
}
|
||||
t4_rx_start_page(&receive_state);
|
||||
detect_page_end(-1000000, compression);
|
||||
|
|
|
@ -262,11 +262,11 @@ static int test_cycle(const char *test_id,
|
|||
t85_decode_set_comment_handler(&t85_dec, 1000, comment_handler, NULL);
|
||||
write_row = 0;
|
||||
result = t85_decode_put_chunk(&t85_dec, testbuf, testbuf_len);
|
||||
if (result == T85_MORE_DATA)
|
||||
if (result == T4_DECODE_MORE_DATA)
|
||||
result = t85_decode_put_byte(&t85_dec, SIG_STATUS_END_OF_DATA);
|
||||
cnt_a = t85_encode_get_compressed_image_size(&t85_enc);
|
||||
cnt_b = t85_decode_get_compressed_image_size(&t85_dec);
|
||||
if (cnt_a != cnt_b || cnt_a != testbuf_len*8 || result != T85_OK)
|
||||
if (cnt_a != cnt_b || cnt_a != testbuf_len*8 || result != T4_DECODE_OK)
|
||||
{
|
||||
printf("Decode result %d\n", result);
|
||||
printf("%ld/%ld bits of %ld bits of BIE read. %lu lines decoded.\n",
|
||||
|
@ -297,19 +297,19 @@ static int test_cycle(const char *test_id,
|
|||
if (comment && comment[0] != 'X')
|
||||
t85_decode_set_comment_handler(&t85_dec, 1000, comment_handler, NULL);
|
||||
write_row = 0;
|
||||
result = T85_MORE_DATA;
|
||||
result = T4_DECODE_MORE_DATA;
|
||||
for (l = 0; l < testbuf_len; l++)
|
||||
{
|
||||
result = t85_decode_put_chunk(&t85_dec, &testbuf[l], 1);
|
||||
if (result != T85_MORE_DATA)
|
||||
if (result != T4_DECODE_MORE_DATA)
|
||||
{
|
||||
l++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (result == T85_MORE_DATA)
|
||||
if (result == T4_DECODE_MORE_DATA)
|
||||
result = t85_decode_put_byte(&t85_dec, SIG_STATUS_END_OF_DATA);
|
||||
if (l != testbuf_len || result != T85_OK)
|
||||
if (l != testbuf_len || result != T4_DECODE_OK)
|
||||
{
|
||||
printf("Decode result %d\n", result);
|
||||
printf("%ld bytes of %ld bytes of BIE read. %lu lines decoded.\n",
|
||||
|
|
Loading…
Reference in New Issue