From ba5125a7e4d366e6e5cfd4c8a0da387a0cf28b79 Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Thu, 5 Feb 2009 15:54:02 +0000 Subject: [PATCH] update to snapshot spandsp-20090205 git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@11654 d0543943-73ff-0310-b7d9-9358b9ac24b2 --- libs/spandsp/src/async.c | 2 +- libs/spandsp/src/libspandsp.vcproj | 128 +------ libs/spandsp/src/msvc/vc8proj.head | 2 +- libs/spandsp/src/silence_gen.c | 2 +- libs/spandsp/src/spandsp/async.h | 2 +- .../src/spandsp/complex_vector_float.h | 2 +- libs/spandsp/src/spandsp/fast_convert.h | 25 +- libs/spandsp/src/spandsp/private/t4.h | 62 ++-- libs/spandsp/src/spandsp/saturated.h | 28 +- libs/spandsp/src/spandsp/silence_gen.h | 2 +- libs/spandsp/src/spandsp/t30.h | 2 +- libs/spandsp/src/spandsp/t38_non_ecm_buffer.h | 2 +- libs/spandsp/src/spandsp/t4.h | 6 +- libs/spandsp/src/spandsp/v42.h | 2 +- libs/spandsp/src/spandsp/version.h | 4 +- libs/spandsp/src/t30.c | 2 +- libs/spandsp/src/t38_non_ecm_buffer.c | 2 +- libs/spandsp/src/t4.c | 331 ++++++++++-------- libs/spandsp/src/v42.c | 2 +- 19 files changed, 302 insertions(+), 306 deletions(-) diff --git a/libs/spandsp/src/async.c b/libs/spandsp/src/async.c index 66c6da9ab2..2214b6500e 100644 --- a/libs/spandsp/src/async.c +++ b/libs/spandsp/src/async.c @@ -22,7 +22,7 @@ * License along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * $Id: async.c,v 1.16 2009/02/03 16:28:39 steveu Exp $ + * $Id: async.c,v 1.17 2009/02/04 13:18:53 steveu Exp $ */ /*! \file */ diff --git a/libs/spandsp/src/libspandsp.vcproj b/libs/spandsp/src/libspandsp.vcproj index 84a56fbe24..6f2d6cb9cf 100644 --- a/libs/spandsp/src/libspandsp.vcproj +++ b/libs/spandsp/src/libspandsp.vcproj @@ -8,37 +8,22 @@ Keyword="Win32Proj" TargetFrameworkVersion="131072" > - - + - - - - - + + + + - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - + + + + + \ No newline at end of file + > diff --git a/libs/spandsp/src/silence_gen.c b/libs/spandsp/src/silence_gen.c index 7af8a366c0..a702d3a91d 100644 --- a/libs/spandsp/src/silence_gen.c +++ b/libs/spandsp/src/silence_gen.c @@ -22,7 +22,7 @@ * License along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * $Id: silence_gen.c,v 1.18 2009/02/03 16:28:40 steveu Exp $ + * $Id: silence_gen.c,v 1.19 2009/02/04 13:18:53 steveu Exp $ */ /*! \file */ diff --git a/libs/spandsp/src/spandsp/async.h b/libs/spandsp/src/spandsp/async.h index 773a99be9a..e73f62f6c7 100644 --- a/libs/spandsp/src/spandsp/async.h +++ b/libs/spandsp/src/spandsp/async.h @@ -22,7 +22,7 @@ * License along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * $Id: async.h,v 1.21 2009/02/03 16:28:40 steveu Exp $ + * $Id: async.h,v 1.22 2009/02/04 13:18:53 steveu Exp $ */ /*! \file */ diff --git a/libs/spandsp/src/spandsp/complex_vector_float.h b/libs/spandsp/src/spandsp/complex_vector_float.h index b9ed454424..abfb8bd0ef 100644 --- a/libs/spandsp/src/spandsp/complex_vector_float.h +++ b/libs/spandsp/src/spandsp/complex_vector_float.h @@ -22,7 +22,7 @@ * License along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * $Id: complex_vector_float.h,v 1.12 2009/01/31 08:48:11 steveu Exp $ + * $Id: complex_vector_float.h,v 1.13 2009/02/04 13:18:53 steveu Exp $ */ #if !defined(_SPANDSP_COMPLEX_VECTOR_FLOAT_H_) diff --git a/libs/spandsp/src/spandsp/fast_convert.h b/libs/spandsp/src/spandsp/fast_convert.h index 2d13cbafcc..33be635b78 100644 --- a/libs/spandsp/src/spandsp/fast_convert.h +++ b/libs/spandsp/src/spandsp/fast_convert.h @@ -22,7 +22,7 @@ * License along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * $Id: fast_convert.h,v 1.1 2009/02/03 16:28:41 steveu Exp $ + * $Id: fast_convert.h,v 1.2 2009/02/05 12:21:36 steveu Exp $ */ #if !defined(_SPANDSP_FAST_CONVERT_H_) @@ -90,7 +90,6 @@ extern "C" * These replacement functions (pulled from the Public Domain MinGW * math.h header) replace the native versions. */ -#if 0 static __inline__ long int lrint(double x) { long int retval; @@ -119,8 +118,8 @@ extern "C" ); return retval; } -#endif + /* The fastest way to convert is the equivalent of lrint() */ static __inline__ long int lfastrint(double x) { long int retval; @@ -149,7 +148,7 @@ extern "C" ); return retval; } -#elif defined(HAVE_LRINT) && defined(HAVE_LRINTF) +#elif defined(__GNUC__) #if defined(__i386__) /* These routines are guaranteed fast on an i386 machine. Using the built in @@ -235,6 +234,7 @@ extern "C" * Win32 doesn't seem to have the lrint() and lrintf() functions. * Therefore implement inline versions of these functions here. */ + __inline long int lrint(double x) { long int i; @@ -269,7 +269,7 @@ extern "C" __inline double rint(double dbl) { - __asm + _asm { fld dbl frndint @@ -300,7 +300,7 @@ extern "C" return i; } #elif defined(WIN64) || defined(_WIN64) - /* Win64 machines will do best with a simple assignment. */ + /* x86_64 machines will do best with a simple assignment. */ __inline long int lfastrint(double x) { @@ -377,12 +377,21 @@ extern "C" the accuracy issues related to changing the rounding scheme are of little concern to us. */ -#if 0 #if !defined(__sgi) #warning "No usable lrint() and lrintf() functions available." #warning "Replacing these functions with a simple C cast." #endif -#endif + + static __inline__ long int lrint(double x) + { + return (long int) (x); + } + + static __inline__ long int lrintf(float x) + { + return (long int) (x); + } + static __inline__ long int lfastrint(double x) { return (long int) (x); diff --git a/libs/spandsp/src/spandsp/private/t4.h b/libs/spandsp/src/spandsp/private/t4.h index 961e320529..926ed2d9ac 100644 --- a/libs/spandsp/src/spandsp/private/t4.h +++ b/libs/spandsp/src/spandsp/private/t4.h @@ -22,12 +22,40 @@ * License along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * $Id: t4.h,v 1.1 2008/10/13 13:14:01 steveu Exp $ + * $Id: t4.h,v 1.2 2009/02/05 12:21:36 steveu Exp $ */ #if !defined(_SPANDSP_PRIVATE_T4_H_) #define _SPANDSP_PRIVATE_T4_H_ +/*! + TIFF specific state information to go with T.4 compression or decompression handling. +*/ +typedef struct +{ + /*! \brief The libtiff context for the current TIFF file */ + TIFF *tiff_file; + + /*! \brief The compression type for output to the TIFF file. */ + int output_compression; + /*! \brief The TIFF G3 FAX options. */ + int output_t4_options; + + /* "Background" information about the FAX, which can be stored in the image file. */ + /*! \brief The vendor of the machine which produced the file. */ + const char *vendor; + /*! \brief The model of machine which produced the file. */ + const char *model; + /*! \brief The local ident string. */ + const char *local_ident; + /*! \brief The remote end's ident string. */ + const char *far_ident; + /*! \brief The FAX sub-address. */ + const char *sub_address; + /*! \brief The FAX DCS information, as an ASCII string. */ + const char *dcs; +} t4_tiff_state_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. @@ -37,22 +65,6 @@ struct t4_state_s /*! \brief The same structure is used for T.4 transmit and receive. This variable records which mode is in progress. */ int rx; - /* "Background" information about the FAX, which can be stored in a TIFF file. */ - /*! \brief The vendor of the machine which produced the TIFF file. */ - const char *vendor; - /*! \brief The model of machine which produced the TIFF file. */ - const char *model; - /*! \brief The local ident string. */ - const char *local_ident; - /*! \brief The remote end's ident string. */ - const char *far_ident; - /*! \brief The FAX sub-address. */ - const char *sub_address; - /*! \brief The FAX DCS information, as an ASCII string. */ - const char *dcs; - /*! \brief The text which will be used in FAX page header. No text results - in no header line. */ - const char *header_info; /*! \brief The type of compression used between the FAX machines. */ int line_encoding; @@ -60,11 +72,6 @@ struct t4_state_s for hardware FAX machines. */ int min_bits_per_row; - /*! \brief The compression type for output to the TIFF file. */ - int output_compression; - /*! \brief The TIFF G3 FAX options. */ - int output_t4_options; - /*! \brief Callback function to read a row of pixels from the image source. */ t4_row_read_handler_t row_read_handler; /*! \brief Opaque pointer passed to row_read_handler. */ @@ -88,8 +95,6 @@ struct t4_state_s /*! \brief A point to the image buffer. */ uint8_t *image_buffer; - /*! \brief The libtiff context for the current TIFF file */ - TIFF *tiff_file; /*! \brief The current file name. */ const char *file; /*! \brief The first page to transfer. -1 to start at the beginning of the file. */ @@ -99,7 +104,7 @@ struct t4_state_s /*! \brief The number of pages transferred to date. */ int pages_transferred; - /*! \brief The number of pages in the current TIFF file. */ + /*! \brief The number of pages in the current image file. */ int pages_in_file; /*! \brief Column-to-column (X) resolution in pixels per metre. */ int x_resolution; @@ -193,8 +198,15 @@ struct t4_state_s /*! \brief The maximum bits in any row of the current page. For monitoring only. */ int max_row_bits; + /*! \brief The text which will be used in FAX page header. No text results + in no header line. */ + const char *header_info; + /*! \brief Error and flow logging control */ logging_state_t logging; + + /*! \brief All TIFF file specific state information for the T.4 context. */ + t4_tiff_state_t tiff; }; #endif diff --git a/libs/spandsp/src/spandsp/saturated.h b/libs/spandsp/src/spandsp/saturated.h index ad9d3ff0fe..2038b25216 100644 --- a/libs/spandsp/src/spandsp/saturated.h +++ b/libs/spandsp/src/spandsp/saturated.h @@ -22,7 +22,7 @@ * License along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * $Id: saturated.h,v 1.3 2009/02/03 17:25:53 steveu Exp $ + * $Id: saturated.h,v 1.4 2009/02/05 12:21:36 steveu Exp $ */ /*! \file */ @@ -75,7 +75,6 @@ static __inline__ int16_t fsaturatef(float famp) return INT16_MAX; if (famp < (float) INT16_MIN) return INT16_MIN; - //return (int16_t) lfastrintf(famp); return (int16_t) lrintf(famp); } /*- End of function --------------------------------------------------------*/ @@ -86,11 +85,33 @@ static __inline__ int16_t fsaturate(double damp) return INT16_MAX; if (damp < (double) INT16_MIN) return INT16_MIN; - //return (int16_t) lfastrint(damp); return (int16_t) lrint(damp); } /*- End of function --------------------------------------------------------*/ +/* Saturate to a 16 bit integer, using the fastest float to int conversion */ +static __inline__ int16_t ffastsaturatef(float famp) +{ + if (famp > (float) INT16_MAX) + return INT16_MAX; + if (famp < (float) INT16_MIN) + return INT16_MIN; + return (int16_t) lfastrintf(famp); +} +/*- End of function --------------------------------------------------------*/ + +/* Saturate to a 16 bit integer, using the fastest double to int conversion */ +static __inline__ int16_t ffastsaturate(double damp) +{ + if (damp > (double) INT16_MAX) + return INT16_MAX; + if (damp < (double) INT16_MIN) + return INT16_MIN; + return (int16_t) lfastrint(damp); +} +/*- End of function --------------------------------------------------------*/ + +/* Saturate to a 16 bit integer, using the closest float to int conversion */ static __inline__ float ffsaturatef(float famp) { if (famp > (float) INT16_MAX) @@ -101,6 +122,7 @@ static __inline__ float ffsaturatef(float famp) } /*- End of function --------------------------------------------------------*/ +/* Saturate to a 16 bit integer, using the closest double to int conversion */ static __inline__ double ffsaturate(double famp) { if (famp > (double) INT16_MAX) diff --git a/libs/spandsp/src/spandsp/silence_gen.h b/libs/spandsp/src/spandsp/silence_gen.h index f1e8a9995b..e65509b73d 100644 --- a/libs/spandsp/src/spandsp/silence_gen.h +++ b/libs/spandsp/src/spandsp/silence_gen.h @@ -22,7 +22,7 @@ * License along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * $Id: silence_gen.h,v 1.14 2009/02/03 16:28:41 steveu Exp $ + * $Id: silence_gen.h,v 1.15 2009/02/04 13:18:53 steveu Exp $ */ #if !defined(_SPANDSP_SILENCE_GEN_H_) diff --git a/libs/spandsp/src/spandsp/t30.h b/libs/spandsp/src/spandsp/t30.h index 405ce60da1..1b71adec96 100644 --- a/libs/spandsp/src/spandsp/t30.h +++ b/libs/spandsp/src/spandsp/t30.h @@ -22,7 +22,7 @@ * License along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * $Id: t30.h,v 1.122 2009/02/03 16:28:41 steveu Exp $ + * $Id: t30.h,v 1.123 2009/02/04 13:18:53 steveu Exp $ */ /*! \file */ diff --git a/libs/spandsp/src/spandsp/t38_non_ecm_buffer.h b/libs/spandsp/src/spandsp/t38_non_ecm_buffer.h index 69629b07d4..5f6f2d247b 100644 --- a/libs/spandsp/src/spandsp/t38_non_ecm_buffer.h +++ b/libs/spandsp/src/spandsp/t38_non_ecm_buffer.h @@ -23,7 +23,7 @@ * License along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * $Id: t38_non_ecm_buffer.h,v 1.5 2009/02/03 16:28:41 steveu Exp $ + * $Id: t38_non_ecm_buffer.h,v 1.6 2009/02/04 13:18:53 steveu Exp $ */ /*! \file */ diff --git a/libs/spandsp/src/spandsp/t4.h b/libs/spandsp/src/spandsp/t4.h index 3717b8ad19..3e3ff4a002 100644 --- a/libs/spandsp/src/spandsp/t4.h +++ b/libs/spandsp/src/spandsp/t4.h @@ -22,7 +22,7 @@ * License along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * $Id: t4.h,v 1.55 2009/02/03 16:28:41 steveu Exp $ + * $Id: t4.h,v 1.56 2009/02/05 12:21:36 steveu Exp $ */ /*! \file */ @@ -249,7 +249,7 @@ SPAN_DECLARE(int) t4_rx_end_page(t4_state_t *s); started with t4_rx_init. \param s The T.4 receive context. \return 0 for success, otherwise -1. */ -SPAN_DECLARE(int) t4_rx_delete(t4_state_t *s); +SPAN_DECLARE(int) t4_rx_free(t4_state_t *s); /*! \brief End reception of a document. Tidy up and close the file. This should be used to end T.4 reception started with @@ -379,7 +379,7 @@ SPAN_DECLARE(int) t4_tx_check_bit(t4_state_t *s); started with t4_tx_init. \param s The T.4 context. \return 0 for success, otherwise -1. */ -SPAN_DECLARE(int) t4_tx_delete(t4_state_t *s); +SPAN_DECLARE(int) t4_tx_free(t4_state_t *s); /*! \brief End the transmission of a document. Tidy up and close the file. This should be used to end T.4 transmission started with t4_tx_init. diff --git a/libs/spandsp/src/spandsp/v42.h b/libs/spandsp/src/spandsp/v42.h index dd651c2a2b..5dedf61d49 100644 --- a/libs/spandsp/src/spandsp/v42.h +++ b/libs/spandsp/src/spandsp/v42.h @@ -22,7 +22,7 @@ * License along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * $Id: v42.h,v 1.28 2009/02/03 16:28:41 steveu Exp $ + * $Id: v42.h,v 1.29 2009/02/04 13:18:53 steveu Exp $ */ /*! \page v42_page V.42 modem error correction diff --git a/libs/spandsp/src/spandsp/version.h b/libs/spandsp/src/spandsp/version.h index c22108a75d..dd161426aa 100644 --- a/libs/spandsp/src/spandsp/version.h +++ b/libs/spandsp/src/spandsp/version.h @@ -30,8 +30,8 @@ /* The date and time of the version are in UTC form. */ -#define SPANDSP_RELEASE_DATE 20090203 -#define SPANDSP_RELEASE_TIME 172817 +#define SPANDSP_RELEASE_DATE 20090205 +#define SPANDSP_RELEASE_TIME 122416 #endif /*- End of file ------------------------------------------------------------*/ diff --git a/libs/spandsp/src/t30.c b/libs/spandsp/src/t30.c index 3e88b0714d..c0d3191d7b 100644 --- a/libs/spandsp/src/t30.c +++ b/libs/spandsp/src/t30.c @@ -22,7 +22,7 @@ * License along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * $Id: t30.c,v 1.283 2009/02/03 16:28:40 steveu Exp $ + * $Id: t30.c,v 1.284 2009/02/04 13:18:53 steveu Exp $ */ /*! \file */ diff --git a/libs/spandsp/src/t38_non_ecm_buffer.c b/libs/spandsp/src/t38_non_ecm_buffer.c index faab671338..c07b393c6d 100644 --- a/libs/spandsp/src/t38_non_ecm_buffer.c +++ b/libs/spandsp/src/t38_non_ecm_buffer.c @@ -23,7 +23,7 @@ * License along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * $Id: t38_non_ecm_buffer.c,v 1.6 2009/02/03 16:28:40 steveu Exp $ + * $Id: t38_non_ecm_buffer.c,v 1.7 2009/02/04 13:18:53 steveu Exp $ */ /*! \file */ diff --git a/libs/spandsp/src/t4.c b/libs/spandsp/src/t4.c index b9198b6e2f..6cbc119584 100644 --- a/libs/spandsp/src/t4.c +++ b/libs/spandsp/src/t4.c @@ -24,7 +24,7 @@ * License along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * $Id: t4.c,v 1.121 2009/02/03 16:28:40 steveu Exp $ + * $Id: t4.c,v 1.123 2009/02/05 12:21:36 steveu Exp $ */ /* @@ -117,6 +117,8 @@ enum #include "faxfont.h" +static int encode_row(t4_state_t *s); + #if defined(T4_STATE_DEBUGGING) static void STATE_TRACE(const char *format, ...) { @@ -156,66 +158,68 @@ static int set_tiff_directory_info(t4_state_t *s) uint16_t resunit; float x_resolution; float y_resolution; + t4_tiff_state_t *t; + t = &s->tiff; /* Prepare the directory entry fully before writing the image, or libtiff complains */ - TIFFSetField(s->tiff_file, TIFFTAG_COMPRESSION, s->output_compression); - if (s->output_compression == COMPRESSION_CCITT_T4) + TIFFSetField(t->tiff_file, TIFFTAG_COMPRESSION, t->output_compression); + if (t->output_compression == COMPRESSION_CCITT_T4) { - TIFFSetField(s->tiff_file, TIFFTAG_T4OPTIONS, s->output_t4_options); - TIFFSetField(s->tiff_file, TIFFTAG_FAXMODE, FAXMODE_CLASSF); + TIFFSetField(t->tiff_file, TIFFTAG_T4OPTIONS, t->output_t4_options); + TIFFSetField(t->tiff_file, TIFFTAG_FAXMODE, FAXMODE_CLASSF); } - TIFFSetField(s->tiff_file, TIFFTAG_IMAGEWIDTH, s->image_width); - TIFFSetField(s->tiff_file, TIFFTAG_BITSPERSAMPLE, 1); - TIFFSetField(s->tiff_file, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT); - TIFFSetField(s->tiff_file, TIFFTAG_SAMPLESPERPIXEL, 1); - if (s->output_compression == COMPRESSION_CCITT_T4 + TIFFSetField(t->tiff_file, TIFFTAG_IMAGEWIDTH, s->image_width); + TIFFSetField(t->tiff_file, TIFFTAG_BITSPERSAMPLE, 1); + TIFFSetField(t->tiff_file, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT); + TIFFSetField(t->tiff_file, TIFFTAG_SAMPLESPERPIXEL, 1); + if (t->output_compression == COMPRESSION_CCITT_T4 || - s->output_compression == COMPRESSION_CCITT_T6) + t->output_compression == COMPRESSION_CCITT_T6) { - TIFFSetField(s->tiff_file, TIFFTAG_ROWSPERSTRIP, -1L); + TIFFSetField(t->tiff_file, TIFFTAG_ROWSPERSTRIP, -1L); } else { - TIFFSetField(s->tiff_file, + TIFFSetField(t->tiff_file, TIFFTAG_ROWSPERSTRIP, - TIFFDefaultStripSize(s->tiff_file, 0)); + TIFFDefaultStripSize(t->tiff_file, 0)); } - TIFFSetField(s->tiff_file, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); - TIFFSetField(s->tiff_file, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISWHITE); - TIFFSetField(s->tiff_file, TIFFTAG_FILLORDER, FILLORDER_LSB2MSB); + TIFFSetField(t->tiff_file, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); + TIFFSetField(t->tiff_file, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISWHITE); + TIFFSetField(t->tiff_file, TIFFTAG_FILLORDER, FILLORDER_LSB2MSB); x_resolution = s->x_resolution/100.0f; y_resolution = s->y_resolution/100.0f; /* Metric seems the sane thing to use in the 21st century, but a lot of lousy software gets FAX resolutions wrong, and more get it wrong using metric than using inches. */ #if 0 - TIFFSetField(s->tiff_file, TIFFTAG_XRESOLUTION, x_resolution); - TIFFSetField(s->tiff_file, TIFFTAG_YRESOLUTION, y_resolution); + TIFFSetField(t->tiff_file, TIFFTAG_XRESOLUTION, x_resolution); + TIFFSetField(t->tiff_file, TIFFTAG_YRESOLUTION, y_resolution); resunit = RESUNIT_CENTIMETER; - TIFFSetField(s->tiff_file, TIFFTAG_RESOLUTIONUNIT, resunit); + TIFFSetField(t->tiff_file, TIFFTAG_RESOLUTIONUNIT, resunit); #else - TIFFSetField(s->tiff_file, TIFFTAG_XRESOLUTION, floorf(x_resolution*CM_PER_INCH + 0.5f)); - TIFFSetField(s->tiff_file, TIFFTAG_YRESOLUTION, floorf(y_resolution*CM_PER_INCH + 0.5f)); + TIFFSetField(t->tiff_file, TIFFTAG_XRESOLUTION, floorf(x_resolution*CM_PER_INCH + 0.5f)); + TIFFSetField(t->tiff_file, TIFFTAG_YRESOLUTION, floorf(y_resolution*CM_PER_INCH + 0.5f)); resunit = RESUNIT_INCH; - TIFFSetField(s->tiff_file, TIFFTAG_RESOLUTIONUNIT, resunit); + TIFFSetField(t->tiff_file, TIFFTAG_RESOLUTIONUNIT, resunit); #endif /* TODO: add the version of spandsp */ - TIFFSetField(s->tiff_file, TIFFTAG_SOFTWARE, "spandsp"); + TIFFSetField(t->tiff_file, TIFFTAG_SOFTWARE, "spandsp"); if (gethostname(buf, sizeof(buf)) == 0) - TIFFSetField(s->tiff_file, TIFFTAG_HOSTCOMPUTER, buf); + TIFFSetField(t->tiff_file, TIFFTAG_HOSTCOMPUTER, buf); #if defined(TIFFTAG_FAXDCS) - if (s->dcs) - TIFFSetField(s->tiff_file, TIFFTAG_FAXDCS, s->dcs); + if (t->dcs) + TIFFSetField(t->tiff_file, TIFFTAG_FAXDCS, t->dcs); #endif - if (s->sub_address) - TIFFSetField(s->tiff_file, TIFFTAG_FAXSUBADDRESS, s->sub_address); - if (s->far_ident) - TIFFSetField(s->tiff_file, TIFFTAG_IMAGEDESCRIPTION, s->far_ident); - if (s->vendor) - TIFFSetField(s->tiff_file, TIFFTAG_MAKE, s->vendor); - if (s->model) - TIFFSetField(s->tiff_file, TIFFTAG_MODEL, s->model); + if (t->sub_address) + TIFFSetField(t->tiff_file, TIFFTAG_FAXSUBADDRESS, t->sub_address); + if (t->far_ident) + TIFFSetField(t->tiff_file, TIFFTAG_IMAGEDESCRIPTION, t->far_ident); + if (t->vendor) + TIFFSetField(t->tiff_file, TIFFTAG_MAKE, t->vendor); + if (t->model) + TIFFSetField(t->tiff_file, TIFFTAG_MODEL, t->model); time(&now); tm = localtime(&now); @@ -227,43 +231,33 @@ static int set_tiff_directory_info(t4_state_t *s) tm->tm_hour, tm->tm_min, tm->tm_sec); - TIFFSetField(s->tiff_file, TIFFTAG_DATETIME, buf); - TIFFSetField(s->tiff_file, TIFFTAG_FAXRECVTIME, now - s->page_start_time); + TIFFSetField(t->tiff_file, TIFFTAG_DATETIME, buf); + TIFFSetField(t->tiff_file, TIFFTAG_FAXRECVTIME, now - s->page_start_time); - TIFFSetField(s->tiff_file, TIFFTAG_IMAGELENGTH, s->image_length); + TIFFSetField(t->tiff_file, TIFFTAG_IMAGELENGTH, s->image_length); /* Set the total pages to 1. For any one page document we will get this right. For multi-page documents we will need to come back and fill in the right answer when we know it. */ - TIFFSetField(s->tiff_file, TIFFTAG_PAGENUMBER, s->pages_transferred++, 1); + TIFFSetField(t->tiff_file, TIFFTAG_PAGENUMBER, s->pages_transferred++, 1); s->pages_in_file = s->pages_transferred; - if (s->output_compression == COMPRESSION_CCITT_T4) + if (t->output_compression == COMPRESSION_CCITT_T4) { if (s->bad_rows) { - TIFFSetField(s->tiff_file, TIFFTAG_BADFAXLINES, s->bad_rows); - TIFFSetField(s->tiff_file, TIFFTAG_CLEANFAXDATA, CLEANFAXDATA_REGENERATED); - TIFFSetField(s->tiff_file, TIFFTAG_CONSECUTIVEBADFAXLINES, s->longest_bad_row_run); + TIFFSetField(t->tiff_file, TIFFTAG_BADFAXLINES, s->bad_rows); + TIFFSetField(t->tiff_file, TIFFTAG_CLEANFAXDATA, CLEANFAXDATA_REGENERATED); + TIFFSetField(t->tiff_file, TIFFTAG_CONSECUTIVEBADFAXLINES, s->longest_bad_row_run); } else { - TIFFSetField(s->tiff_file, TIFFTAG_CLEANFAXDATA, CLEANFAXDATA_CLEAN); + TIFFSetField(t->tiff_file, TIFFTAG_CLEANFAXDATA, CLEANFAXDATA_CLEAN); } } - TIFFSetField(s->tiff_file, TIFFTAG_IMAGEWIDTH, s->image_width); + TIFFSetField(t->tiff_file, TIFFTAG_IMAGEWIDTH, s->image_width); return 0; } /*- End of function --------------------------------------------------------*/ -static void update_row_bit_info(t4_state_t *s) -{ - if (s->row_bits > s->max_row_bits) - s->max_row_bits = s->row_bits; - if (s->row_bits < s->min_row_bits) - s->min_row_bits = s->row_bits; - s->row_bits = 0; -} -/*- End of function --------------------------------------------------------*/ - static int test_resolution(int res_unit, float actual, float expected) { if (res_unit == RESUNIT_INCH) @@ -310,24 +304,26 @@ static int get_tiff_directory_info(t4_state_t *s) float x_resolution; float y_resolution; int i; + t4_tiff_state_t *t; + t = &s->tiff; parm = 0; - TIFFGetField(s->tiff_file, TIFFTAG_BITSPERSAMPLE, &parm); + TIFFGetField(t->tiff_file, TIFFTAG_BITSPERSAMPLE, &parm); if (parm != 1) return -1; parm = 0; - TIFFGetField(s->tiff_file, TIFFTAG_IMAGEWIDTH, &parm); + TIFFGetField(t->tiff_file, TIFFTAG_IMAGEWIDTH, &parm); s->image_width = parm; s->bytes_per_row = (s->image_width + 7)/8; parm = 0; - TIFFGetField(s->tiff_file, TIFFTAG_IMAGELENGTH, &parm); + TIFFGetField(t->tiff_file, TIFFTAG_IMAGELENGTH, &parm); s->image_length = parm; x_resolution = 0.0f; - TIFFGetField(s->tiff_file, TIFFTAG_XRESOLUTION, &x_resolution); + TIFFGetField(t->tiff_file, TIFFTAG_XRESOLUTION, &x_resolution); y_resolution = 0.0f; - TIFFGetField(s->tiff_file, TIFFTAG_YRESOLUTION, &y_resolution); + TIFFGetField(t->tiff_file, TIFFTAG_YRESOLUTION, &y_resolution); res_unit = RESUNIT_INCH; - TIFFGetField(s->tiff_file, TIFFTAG_RESOLUTIONUNIT, &res_unit); + TIFFGetField(t->tiff_file, TIFFTAG_RESOLUTIONUNIT, &res_unit); /* Allow a little range for the X resolution in centimeters. The spec doesn't pin down the precise value. The other value should be exact. */ @@ -360,16 +356,37 @@ static int get_tiff_directory_info(t4_state_t *s) static int open_tiff_input_file(t4_state_t *s, const char *file) { - if ((s->tiff_file = TIFFOpen(file, "r")) == NULL) + if ((s->tiff.tiff_file = TIFFOpen(file, "r")) == NULL) return -1; return 0; } /*- End of function --------------------------------------------------------*/ +static int read_tiff_image(t4_state_t *s) +{ + int row; + int image_length; + + image_length = 0; + TIFFGetField(s->tiff.tiff_file, TIFFTAG_IMAGELENGTH, &image_length); + for (row = 0; row < image_length; row++) + { + if (TIFFReadScanline(s->tiff.tiff_file, s->row_buf, row, 0) <= 0) + { + span_log(&s->logging, SPAN_LOG_WARNING, "%s: Read error at row %d.\n", s->file, row); + break; + } + if (encode_row(s)) + return -1; + } + return image_length; +} +/*- End of function --------------------------------------------------------*/ + static int close_tiff_input_file(t4_state_t *s) { - TIFFClose(s->tiff_file); - s->tiff_file = NULL; + TIFFClose(s->tiff.tiff_file); + s->tiff.tiff_file = NULL; if (s->file) free((char *) s->file); s->file = NULL; @@ -379,16 +396,30 @@ static int close_tiff_input_file(t4_state_t *s) static int open_tiff_output_file(t4_state_t *s, const char *file) { - if ((s->tiff_file = TIFFOpen(file, "w")) == NULL) + if ((s->tiff.tiff_file = TIFFOpen(file, "w")) == NULL) return -1; return 0; } /*- End of function --------------------------------------------------------*/ +static void write_tiff_image(t4_state_t *s) +{ + /* Set up the TIFF directory info... */ + set_tiff_directory_info(s); + /* ..and then write the image... */ + if (TIFFWriteEncodedStrip(s->tiff.tiff_file, 0, s->image_buffer, s->image_length*s->bytes_per_row) < 0) + span_log(&s->logging, SPAN_LOG_WARNING, "%s: Error writing TIFF strip.\n", s->file); + /* ...then the directory entry, and libtiff is happy. */ + TIFFWriteDirectory(s->tiff.tiff_file); +} +/*- End of function --------------------------------------------------------*/ + static int close_tiff_output_file(t4_state_t *s) { int i; + t4_tiff_state_t *t; + t = &s->tiff; /* Perform any operations needed to tidy up a written TIFF file before closure. */ if (s->pages_transferred > 1) @@ -398,13 +429,13 @@ static int close_tiff_output_file(t4_state_t *s) need to set the correct total page count associated with each page. */ for (i = 0; i < s->pages_transferred; i++) { - TIFFSetDirectory(s->tiff_file, (tdir_t) i); - TIFFSetField(s->tiff_file, TIFFTAG_PAGENUMBER, i, s->pages_transferred); - TIFFWriteDirectory(s->tiff_file); + TIFFSetDirectory(t->tiff_file, (tdir_t) i); + TIFFSetField(t->tiff_file, TIFFTAG_PAGENUMBER, i, s->pages_transferred); + TIFFWriteDirectory(t->tiff_file); } } - TIFFClose(s->tiff_file); - s->tiff_file = NULL; + TIFFClose(t->tiff_file); + t->tiff_file = NULL; if (s->file) { /* Try not to leave a file behind, if we didn't receive any pages to @@ -418,6 +449,16 @@ static int close_tiff_output_file(t4_state_t *s) } /*- End of function --------------------------------------------------------*/ +static void update_row_bit_info(t4_state_t *s) +{ + if (s->row_bits > s->max_row_bits) + s->max_row_bits = s->row_bits; + if (s->row_bits < s->min_row_bits) + s->min_row_bits = s->row_bits; + s->row_bits = 0; +} +/*- End of function --------------------------------------------------------*/ + #if defined(__i386__) || defined(__x86_64__) || defined(__ppc__) || defined(__powerpc__) static __inline__ int run_length(unsigned int bits) { @@ -780,13 +821,7 @@ SPAN_DECLARE(int) t4_rx_end_page(t4_state_t *s) } else { - /* Set up the TIFF directory info... */ - set_tiff_directory_info(s); - /* ..and then write the image... */ - if (TIFFWriteEncodedStrip(s->tiff_file, 0, s->image_buffer, s->image_length*s->bytes_per_row) < 0) - span_log(&s->logging, SPAN_LOG_WARNING, "%s: Error writing TIFF strip.\n", s->file); - /* ...then the directory entry, and libtiff is happy. */ - TIFFWriteDirectory(s->tiff_file); + write_tiff_image(s); } s->rx_bits = 0; s->rx_skip_bits = 0; @@ -801,7 +836,8 @@ SPAN_DECLARE(int) t4_rx_end_page(t4_state_t *s) static __inline__ void drop_rx_bits(t4_state_t *s, int bits) { /* Only remove one bit right now. The rest need to be removed step by step, - checking for a misaligned EOL along the way. */ + checking for a misaligned EOL along the way. This is time consuming, but + if we don't do it a single bit error can severely damage an image. */ s->row_bits += bits; s->rx_skip_bits += (bits - 1); s->rx_bits--; @@ -1162,6 +1198,11 @@ SPAN_DECLARE(int) t4_rx_set_row_write_handler(t4_state_t *s, t4_row_write_handle SPAN_DECLARE(t4_state_t *) t4_rx_init(t4_state_t *s, const char *file, int output_encoding) { + if (s == NULL) + { + if ((s = (t4_state_t *) malloc(sizeof(*s))) == NULL) + return NULL; + } memset(s, 0, sizeof(*s)); span_log_init(&s->logging, SPAN_LOG_NONE, NULL); span_log_set_protocol(&s->logging, "T.4"); @@ -1179,16 +1220,16 @@ SPAN_DECLARE(t4_state_t *) t4_rx_init(t4_state_t *s, const char *file, int outpu switch (output_encoding) { case T4_COMPRESSION_ITU_T4_1D: - s->output_compression = COMPRESSION_CCITT_T4; - s->output_t4_options = GROUP3OPT_FILLBITS; + s->tiff.output_compression = COMPRESSION_CCITT_T4; + s->tiff.output_t4_options = GROUP3OPT_FILLBITS; break; case T4_COMPRESSION_ITU_T4_2D: - s->output_compression = COMPRESSION_CCITT_T4; - s->output_t4_options = GROUP3OPT_FILLBITS | GROUP3OPT_2DENCODING; + s->tiff.output_compression = COMPRESSION_CCITT_T4; + s->tiff.output_t4_options = GROUP3OPT_FILLBITS | GROUP3OPT_2DENCODING; break; case T4_COMPRESSION_ITU_T6: - s->output_compression = COMPRESSION_CCITT_T6; - s->output_t4_options = 0; + s->tiff.output_compression = COMPRESSION_CCITT_T6; + s->tiff.output_t4_options = 0; break; } @@ -1220,7 +1261,7 @@ SPAN_DECLARE(int) t4_rx_start_page(t4_state_t *s) uint32_t *bufptr; span_log(&s->logging, SPAN_LOG_FLOW, "Start rx page - compression %d\n", s->line_encoding); - if (s->tiff_file == NULL) + if (s->tiff.tiff_file == NULL) return -1; /* Calculate the scanline/tile width. */ @@ -1286,27 +1327,26 @@ SPAN_DECLARE(int) t4_rx_start_page(t4_state_t *s) } /*- End of function --------------------------------------------------------*/ -SPAN_DECLARE(int) t4_rx_delete(t4_state_t *s) -{ - if (t4_rx_end(s)) - return -1; - free_buffers(s); - free(s); - return 0; -} -/*- End of function --------------------------------------------------------*/ - SPAN_DECLARE(int) t4_rx_end(t4_state_t *s) { if (!s->rx) return -1; - if (s->tiff_file) + if (s->tiff.tiff_file) close_tiff_output_file(s); free_buffers(s); return 0; } /*- End of function --------------------------------------------------------*/ +SPAN_DECLARE(int) t4_rx_free(t4_state_t *s) +{ + if (t4_rx_end(s)) + return -1; + free(s); + return 0; +} +/*- End of function --------------------------------------------------------*/ + SPAN_DECLARE(void) t4_rx_set_rx_encoding(t4_state_t *s, int encoding) { s->line_encoding = encoding; @@ -1333,31 +1373,31 @@ SPAN_DECLARE(void) t4_rx_set_x_resolution(t4_state_t *s, int resolution) SPAN_DECLARE(void) t4_rx_set_dcs(t4_state_t *s, const char *dcs) { - s->dcs = (dcs && dcs[0]) ? dcs : NULL; + s->tiff.dcs = (dcs && dcs[0]) ? dcs : NULL; } /*- End of function --------------------------------------------------------*/ SPAN_DECLARE(void) t4_rx_set_sub_address(t4_state_t *s, const char *sub_address) { - s->sub_address = (sub_address && sub_address[0]) ? sub_address : NULL; + s->tiff.sub_address = (sub_address && sub_address[0]) ? sub_address : NULL; } /*- End of function --------------------------------------------------------*/ SPAN_DECLARE(void) t4_rx_set_far_ident(t4_state_t *s, const char *ident) { - s->far_ident = (ident && ident[0]) ? ident : NULL; + s->tiff.far_ident = (ident && ident[0]) ? ident : NULL; } /*- End of function --------------------------------------------------------*/ SPAN_DECLARE(void) t4_rx_set_vendor(t4_state_t *s, const char *vendor) { - s->vendor = vendor; + s->tiff.vendor = vendor; } /*- End of function --------------------------------------------------------*/ SPAN_DECLARE(void) t4_rx_set_model(t4_state_t *s, const char *model) { - s->model = model; + s->tiff.model = model; } /*- End of function --------------------------------------------------------*/ @@ -1721,6 +1761,11 @@ SPAN_DECLARE(t4_state_t *) t4_tx_init(t4_state_t *s, const char *file, int start { int run_space; + if (s == NULL) + { + if ((s = (t4_state_t *) malloc(sizeof(*s))) == NULL) + return NULL; + } memset(s, 0, sizeof(*s)); span_log_init(&s->logging, SPAN_LOG_NONE, NULL); span_log_set_protocol(&s->logging, "T.4"); @@ -1801,7 +1846,7 @@ static void make_header(t4_state_t *s, char *header) tm.tm_hour, tm.tm_min, s->header_info, - s->local_ident, + s->tiff.local_ident, s->pages_transferred + 1); } /*- End of function --------------------------------------------------------*/ @@ -1813,9 +1858,9 @@ SPAN_DECLARE(int) t4_tx_start_page(t4_state_t *s) int repeats; int pattern; int row_bufptr; - int parm; int run_space; int len; + int this_image_width; char *t; char header[132 + 1]; uint8_t *bufptr8; @@ -1824,23 +1869,26 @@ SPAN_DECLARE(int) t4_tx_start_page(t4_state_t *s) span_log(&s->logging, SPAN_LOG_FLOW, "Start tx page %d\n", s->pages_transferred); if (s->pages_transferred > s->stop_page) return -1; - if (s->tiff_file == NULL) - return -1; - if (!TIFFSetDirectory(s->tiff_file, (tdir_t) s->pages_transferred)) + if (s->tiff.tiff_file == NULL) return -1; + this_image_width = 0; + if (s->row_read_handler == NULL) + { + if (!TIFFSetDirectory(s->tiff.tiff_file, (tdir_t) s->pages_transferred)) + return -1; + TIFFGetField(s->tiff.tiff_file, TIFFTAG_IMAGEWIDTH, &this_image_width); + } s->image_size = 0; s->tx_bitstream = 0; s->tx_bits = 0; s->row_is_2d = (s->line_encoding == T4_COMPRESSION_ITU_T6); s->rows_to_next_1d_row = s->max_rows_to_next_1d_row - 1; - /* Allow for pages being of different width */ - parm = 0; - TIFFGetField(s->tiff_file, TIFFTAG_IMAGEWIDTH, &parm); - run_space = (parm + 4)*sizeof(uint32_t); - if (parm != s->image_width) + /* Allow for pages being of different width. */ + run_space = (this_image_width + 4)*sizeof(uint32_t); + if (this_image_width != s->image_width) { - s->image_width = parm; + s->image_width = this_image_width; s->bytes_per_row = (s->image_width + 7)/8; if ((bufptr = (uint32_t *) realloc(s->cur_runs, run_space)) == NULL) @@ -1928,18 +1976,8 @@ SPAN_DECLARE(int) t4_tx_start_page(t4_state_t *s) } else { - s->image_length = 0; - TIFFGetField(s->tiff_file, TIFFTAG_IMAGELENGTH, &s->image_length); - for (row = 0; row < s->image_length; row++) - { - if (TIFFReadScanline(s->tiff_file, s->row_buf, row, 0) <= 0) - { - span_log(&s->logging, SPAN_LOG_WARNING, "%s: Read error at row %d.\n", s->file, row); - break; - } - if (encode_row(s)) - return -1; - } + if ((s->image_length = read_tiff_image(s)) < 0) + return -1; } if (s->line_encoding == T4_COMPRESSION_ITU_T6) { @@ -1970,7 +2008,7 @@ SPAN_DECLARE(int) t4_tx_more_pages(t4_state_t *s) span_log(&s->logging, SPAN_LOG_FLOW, "Checking for the existance of page %d\n", s->pages_transferred + 1); if (s->pages_transferred >= s->stop_page) return -1; - if (s->tiff_file == NULL) + if (s->tiff.tiff_file == NULL) return -1; if (s->pages_in_file >= 0) { @@ -1979,8 +2017,11 @@ SPAN_DECLARE(int) t4_tx_more_pages(t4_state_t *s) } else { - if (!TIFFSetDirectory(s->tiff_file, (tdir_t) s->pages_transferred + 1)) - return -1; + if (s->row_read_handler == NULL) + { + if (!TIFFSetDirectory(s->tiff.tiff_file, (tdir_t) s->pages_transferred + 1)) + return -1; + } } return 0; } @@ -2048,27 +2089,26 @@ SPAN_DECLARE(int) t4_tx_check_bit(t4_state_t *s) } /*- End of function --------------------------------------------------------*/ -SPAN_DECLARE(int) t4_tx_delete(t4_state_t *s) -{ - if (t4_tx_end(s)) - return -1; - free_buffers(s); - free(s); - return 0; -} -/*- End of function --------------------------------------------------------*/ - SPAN_DECLARE(int) t4_tx_end(t4_state_t *s) { if (s->rx) return -1; - if (s->tiff_file) + if (s->tiff.tiff_file) close_tiff_input_file(s); free_buffers(s); return 0; } /*- End of function --------------------------------------------------------*/ +SPAN_DECLARE(int) t4_tx_free(t4_state_t *s) +{ + if (t4_tx_end(s)) + return -1; + free(s); + return 0; +} +/*- End of function --------------------------------------------------------*/ + SPAN_DECLARE(void) t4_tx_set_tx_encoding(t4_state_t *s, int encoding) { s->line_encoding = encoding; @@ -2085,7 +2125,7 @@ SPAN_DECLARE(void) t4_tx_set_min_row_bits(t4_state_t *s, int bits) SPAN_DECLARE(void) t4_tx_set_local_ident(t4_state_t *s, const char *ident) { - s->local_ident = (ident && ident[0]) ? ident : NULL; + s->tiff.local_ident = (ident && ident[0]) ? ident : NULL; } /*- End of function --------------------------------------------------------*/ @@ -2121,12 +2161,15 @@ SPAN_DECLARE(int) t4_tx_get_pages_in_file(t4_state_t *s) trusted? Some files say 0. Actually searching for the last page is more reliable. */ max = 0; - while (TIFFSetDirectory(s->tiff_file, (tdir_t) max)) - max++; + if (s->row_write_handler == NULL) + { + while (TIFFSetDirectory(s->tiff.tiff_file, (tdir_t) max)) + max++; + /* Back to the previous page */ + if (!TIFFSetDirectory(s->tiff.tiff_file, (tdir_t) s->pages_transferred)) + return -1; + } s->pages_in_file = max; - /* Back to the previous page */ - if (!TIFFSetDirectory(s->tiff_file, (tdir_t) s->pages_transferred)) - return -1; return max; } /*- End of function --------------------------------------------------------*/ diff --git a/libs/spandsp/src/v42.c b/libs/spandsp/src/v42.c index 61cd2ca68a..07df72d10f 100644 --- a/libs/spandsp/src/v42.c +++ b/libs/spandsp/src/v42.c @@ -22,7 +22,7 @@ * License along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * $Id: v42.c,v 1.48 2009/02/03 16:28:40 steveu Exp $ + * $Id: v42.c,v 1.49 2009/02/04 13:18:53 steveu Exp $ */ /* THIS IS A WORK IN PROGRESS. IT IS NOT FINISHED. */