1 /*
2  * SpanDSP - a series of DSP components for telephony
3  *
4  * t4_tx.c - ITU T.4 FAX image transmit processing
5  *
6  * Written by Steve Underwood <steveu@coppice.org>
7  *
8  * Copyright (C) 2003, 2007, 2010 Steve Underwood
9  *
10  * All rights reserved.
11  *
12  * This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU Lesser General Public License version 2.1,
14  * as published by the Free Software Foundation.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU Lesser General Public License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public
22  * License along with this program; if not, write to the Free Software
23  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24  */
25 
26 /*! \file */
27 
28 #if defined(HAVE_CONFIG_H)
29 #include "config.h"
30 #endif
31 
32 #include <inttypes.h>
33 #include <stdlib.h>
34 #include <limits.h>
35 #include <stdio.h>
36 #include <fcntl.h>
37 #include <unistd.h>
38 #include <time.h>
39 #include <memory.h>
40 #include <string.h>
41 #if defined(HAVE_TGMATH_H)
42 #include <tgmath.h>
43 #endif
44 #if defined(HAVE_MATH_H)
45 #include <math.h>
46 #endif
47 #if defined(HAVE_STDBOOL_H)
48 #include <stdbool.h>
49 #else
50 #include "spandsp/stdbool.h"
51 #endif
52 #include "floating_fudge.h"
53 #include <tiffio.h>
54 
55 #include "spandsp/telephony.h"
56 #include "spandsp/alloc.h"
57 #include "spandsp/logging.h"
58 #include "spandsp/bit_operations.h"
59 #include "spandsp/async.h"
60 #include "spandsp/timezone.h"
61 #include "spandsp/t4_rx.h"
62 #include "spandsp/t4_tx.h"
63 #include "spandsp/image_translate.h"
64 #include "spandsp/t81_t82_arith_coding.h"
65 #include "spandsp/t85.h"
66 #include "spandsp/t42.h"
67 #include "spandsp/t43.h"
68 #include "spandsp/t4_t6_decode.h"
69 #include "spandsp/t4_t6_encode.h"
70 
71 #include "spandsp/private/logging.h"
72 #include "spandsp/private/t81_t82_arith_coding.h"
73 #include "spandsp/private/t85.h"
74 #include "spandsp/private/t42.h"
75 #include "spandsp/private/t43.h"
76 #include "spandsp/private/t4_t6_decode.h"
77 #include "spandsp/private/t4_t6_encode.h"
78 #include "spandsp/private/image_translate.h"
79 #include "spandsp/private/t4_rx.h"
80 #include "spandsp/private/t4_tx.h"
81 
82 #include "faxfont.h"
83 
84 #if defined(SPANDSP_SUPPORT_TIFF_FX)  &&  defined(HAVE_TIF_DIR_H)
85 #include <tif_dir.h>
86 #endif
87 
88 /*! The number of centimetres in one inch */
89 #define CM_PER_INCH                 2.54f
90 
91 typedef struct
92 {
93     uint8_t *buf;
94     int ptr;
95     int row;
96     int size;
97     int bit_mask;
98 } packer_t;
99 
100 static void t4_tx_set_image_type(t4_tx_state_t *s, int image_type);
101 static void set_image_width(t4_tx_state_t *s, uint32_t image_width);
102 static void set_image_length(t4_tx_state_t *s, uint32_t image_length);
103 
104 static const float x_res_table[] =
105 {
106      100.0f*100.0f/CM_PER_INCH,
107      102.0f*100.0f/CM_PER_INCH,
108      200.0f*100.0f/CM_PER_INCH,
109      204.0f*100.0f/CM_PER_INCH,
110      300.0f*100.0f/CM_PER_INCH,
111      400.0f*100.0f/CM_PER_INCH,
112      408.0f*100.0f/CM_PER_INCH,
113      600.0f*100.0f/CM_PER_INCH,
114     1200.0f*100.0f/CM_PER_INCH,
115                         -1.00f
116 };
117 
118 static const float y_res_table[] =
119 {
120                  38.50f*100.0f,
121      100.0f*100.0f/CM_PER_INCH,
122                  77.00f*100.0f,
123      200.0f*100.0f/CM_PER_INCH,
124      300.0f*100.0f/CM_PER_INCH,
125                 154.00f*100.0f,
126      400.0f*100.0f/CM_PER_INCH,
127      600.0f*100.0f/CM_PER_INCH,
128      800.0f*100.0f/CM_PER_INCH,
129     1200.0f*100.0f/CM_PER_INCH,
130                         -1.00f
131 };
132 
133 static const int resolution_map[10][9] =
134 {
135     /*  x =           100 102                    200                         204                    300                    400                          408                     600                     1200 */
136     {                    0, 0,                     0,  T4_RESOLUTION_R8_STANDARD,                     0,                     0,                           0,                      0,                       0}, /* y = 3.85/mm */
137     {T4_RESOLUTION_100_100, 0, T4_RESOLUTION_200_100,                          0,                     0,                     0,                           0,                      0,                       0}, /* y = 100 */
138     {                    0, 0,                     0,      T4_RESOLUTION_R8_FINE,                     0,                     0,                           0,                      0,                       0}, /* y = 7.7/mm */
139     {                    0, 0, T4_RESOLUTION_200_200,                          0,                     0,                     0,                           0,                      0,                       0}, /* y = 200 */
140     {                    0, 0,                     0,                          0, T4_RESOLUTION_300_300,                     0,                           0,                      0,                       0}, /* y = 300 */
141     {                    0, 0,                     0, T4_RESOLUTION_R8_SUPERFINE,                     0,                     0, T4_RESOLUTION_R16_SUPERFINE,                      0,                       0}, /* y = 154/mm */
142     {                    0, 0, T4_RESOLUTION_200_400,                          0,                     0, T4_RESOLUTION_400_400,                           0,                      0,                       0}, /* y = 400 */
143     {                    0, 0,                     0,                          0, T4_RESOLUTION_300_600,                     0,                           0,  T4_RESOLUTION_600_600,                       0}, /* y = 600 */
144     {                    0, 0,                     0,                          0,                     0, T4_RESOLUTION_400_800,                           0,                      0,                       0}, /* y = 800 */
145     {                    0, 0,                     0,                          0,                     0,                     0,                           0, T4_RESOLUTION_600_1200, T4_RESOLUTION_1200_1200}  /* y = 1200 */
146 };
147 
148 #if defined(SPANDSP_SUPPORT_TIFF_FX)
149 /* TIFF-FX related extensions to the tag set supported by libtiff */
150 
151 static const TIFFFieldInfo tiff_fx_tiff_field_info[] =
152 {
153     {TIFFTAG_INDEXED, 1, 1, TIFF_SHORT, FIELD_CUSTOM, false, false, (char *) "Indexed"},
154     {TIFFTAG_GLOBALPARAMETERSIFD, 1, 1, TIFF_IFD8, FIELD_CUSTOM, false, false, (char *) "GlobalParametersIFD"},
155     {TIFFTAG_PROFILETYPE, 1, 1, TIFF_LONG, FIELD_CUSTOM, false, false, (char *) "ProfileType"},
156     {TIFFTAG_FAXPROFILE, 1, 1, TIFF_BYTE, FIELD_CUSTOM, false, false, (char *) "FaxProfile"},
157     {TIFFTAG_CODINGMETHODS, 1, 1, TIFF_LONG, FIELD_CUSTOM, false, false, (char *) "CodingMethods"},
158     {TIFFTAG_VERSIONYEAR, 4, 4, TIFF_BYTE, FIELD_CUSTOM, false, false, (char *) "VersionYear"},
159     {TIFFTAG_MODENUMBER, 1, 1, TIFF_BYTE, FIELD_CUSTOM, false, false, (char *) "ModeNumber"},
160     {TIFFTAG_DECODE, TIFF_VARIABLE, TIFF_VARIABLE, TIFF_SRATIONAL, FIELD_CUSTOM, false, true, (char *) "Decode"},
161     {TIFFTAG_IMAGEBASECOLOR, TIFF_VARIABLE, TIFF_VARIABLE, TIFF_SHORT, FIELD_CUSTOM, false, true, (char *) "ImageBaseColor"},
162     {TIFFTAG_T82OPTIONS, 1, 1, TIFF_LONG, FIELD_CUSTOM, false, false, (char *) "T82Options"},
163     {TIFFTAG_STRIPROWCOUNTS, TIFF_VARIABLE, TIFF_VARIABLE, TIFF_LONG, FIELD_CUSTOM, false, true, (char *) "StripRowCounts"},
164     {TIFFTAG_IMAGELAYER, 2, 2, TIFF_LONG, FIELD_CUSTOM, false, false, (char *) "ImageLayer"},
165 };
166 
167 #if TIFFLIB_VERSION >= 20120922  &&  defined(HAVE_TIF_DIR_H)
168 static TIFFField tiff_fx_tiff_fields[] =
169 {
170     { TIFFTAG_INDEXED, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, (char *) "Indexed" },
171     { TIFFTAG_GLOBALPARAMETERSIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_IFD8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, (char *) "GlobalParametersIFD", NULL },
172     { TIFFTAG_PROFILETYPE, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, (char *) "ProfileType", NULL },
173     { TIFFTAG_FAXPROFILE, 1, 1, TIFF_BYTE, 0, TIFF_SETGET_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, (char *) "FaxProfile", NULL },
174     { TIFFTAG_CODINGMETHODS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, (char *) "CodingMethods", NULL },
175     { TIFFTAG_VERSIONYEAR, 4, 4, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, (char *) "VersionYear", NULL },
176     { TIFFTAG_MODENUMBER, 1, 1, TIFF_BYTE, 0, TIFF_SETGET_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, (char *) "ModeNumber", NULL },
177     { TIFFTAG_DECODE, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, (char *) "Decode", NULL },
178     { TIFFTAG_IMAGEBASECOLOR, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, (char *) "ImageBaseColor", NULL },
179     { TIFFTAG_T82OPTIONS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, (char *) "T82Options", NULL },
180     { TIFFTAG_STRIPROWCOUNTS, -1, -1, TIFF_LONG, 0, TIFF_SETGET_C16_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, (char *) "StripRowCounts", NULL },
181     { TIFFTAG_IMAGELAYER, 2, 2, TIFF_LONG, 0, TIFF_SETGET_C0_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, (char *) "ImageLayer", NULL },
182 };
183 
184 TIFFFieldArray tiff_fx_field_array = { tfiatOther, 0, 12, tiff_fx_tiff_fields };
185 #endif
186 
187 static TIFFExtendProc _ParentExtender = NULL;
188 
TIFFFXDefaultDirectory(TIFF * tif)189 static void TIFFFXDefaultDirectory(TIFF *tif)
190 {
191     /* Install the extended tag field info */
192     TIFFMergeFieldInfo(tif, tiff_fx_tiff_field_info, 12);
193 
194     /* Since we may have overriddden another directory method, we call it now to
195        allow it to set up the rest of its own methods. */
196     if (_ParentExtender)
197         (*_ParentExtender)(tif);
198 }
199 /*- End of function --------------------------------------------------------*/
200 
TIFF_FX_init(void)201 SPAN_DECLARE(void) TIFF_FX_init(void)
202 {
203     static int first_time = true;
204 
205     if (!first_time)
206         return;
207     first_time = false;
208 
209     /* Grab the inherited method and install */
210     _ParentExtender = TIFFSetTagExtender(TIFFFXDefaultDirectory);
211 }
212 /*- End of function --------------------------------------------------------*/
213 #endif
214 
code_to_x_resolution(int code)215 static int code_to_x_resolution(int code)
216 {
217     static const int xxx[] =
218     {
219         T4_X_RESOLUTION_R8,         /* R8 x standard */
220         T4_X_RESOLUTION_R8,         /* R8 x fine */
221         T4_X_RESOLUTION_R8,         /* R8 x superfine */
222         T4_X_RESOLUTION_R16,        /* R16 x superfine */
223         T4_X_RESOLUTION_100,        /* 100x100 */
224         T4_X_RESOLUTION_200,        /* 200x100 */
225         T4_X_RESOLUTION_200,        /* 200x200 */
226         T4_X_RESOLUTION_200,        /* 200x400 */
227         T4_X_RESOLUTION_300,        /* 300x300 */
228         T4_X_RESOLUTION_300,        /* 300x600 */
229         T4_X_RESOLUTION_400,        /* 400x400 */
230         T4_X_RESOLUTION_400,        /* 400x800 */
231         T4_X_RESOLUTION_600,        /* 600x600 */
232         T4_X_RESOLUTION_600,        /* 600x1200 */
233         T4_X_RESOLUTION_1200        /* 1200x1200 */
234     };
235     int entry;
236 
237     entry = top_bit(code);
238     if (entry < 0  ||  entry > 14)
239         return 0;
240     return xxx[entry];
241 }
242 /*- End of function --------------------------------------------------------*/
243 
code_to_y_resolution(int code)244 static int code_to_y_resolution(int code)
245 {
246     static const int yyy[] =
247     {
248         T4_Y_RESOLUTION_STANDARD,   /* R8 x standard */
249         T4_Y_RESOLUTION_FINE,       /* R8 x fine */
250         T4_Y_RESOLUTION_SUPERFINE,  /* R8 x superfine */
251         T4_Y_RESOLUTION_SUPERFINE,  /* R16 x superfine */
252         T4_Y_RESOLUTION_100,        /* 100x100 */
253         T4_Y_RESOLUTION_100,        /* 200x100 */
254         T4_Y_RESOLUTION_200,        /* 200x200 */
255         T4_Y_RESOLUTION_400,        /* 200x400 */
256         T4_Y_RESOLUTION_300,        /* 300x300 */
257         T4_Y_RESOLUTION_600,        /* 300x600 */
258         T4_Y_RESOLUTION_400,        /* 400x400 */
259         T4_Y_RESOLUTION_800,        /* 400x800 */
260         T4_Y_RESOLUTION_600,        /* 600x600 */
261         T4_Y_RESOLUTION_1200,       /* 600x1200 */
262         T4_Y_RESOLUTION_1200        /* 1200x1200 */
263     };
264     int entry;
265 
266     entry = top_bit(code);
267     if (entry < 0  ||  entry > 14)
268         return 0;
269     return yyy[entry];
270 }
271 /*- End of function --------------------------------------------------------*/
272 
match_resolution(float actual,const float table[])273 static int match_resolution(float actual, const float table[])
274 {
275     int i;
276     int best_entry;
277     float best_ratio;
278     float ratio;
279 
280     if (actual == 0.0f)
281         return -1;
282 
283     best_ratio = 0.0f;
284     best_entry = -1;
285     for (i = 0;  table[i] > 0.0f;  i++)
286     {
287         if (actual > table[i])
288             ratio = table[i]/actual;
289         else
290             ratio = actual/table[i];
291         if (ratio > best_ratio)
292         {
293             best_entry = i;
294             best_ratio = ratio;
295         }
296     }
297     if (best_ratio < 0.95f)
298         return -1;
299     return best_entry;
300 }
301 /*- End of function --------------------------------------------------------*/
302 
303 #if 0
304 static int best_colour_resolution(float actual, int allowed_resolutions)
305 {
306     static const struct
307     {
308         float resolution;
309         int resolution_code;
310     } x_res_table[] =
311     {
312         { 100.0f*100.0f/CM_PER_INCH, T4_RESOLUTION_100_100},
313         { 200.0f*100.0f/CM_PER_INCH, T4_RESOLUTION_200_200},
314         { 300.0f*100.0f/CM_PER_INCH, T4_RESOLUTION_300_300},
315         { 400.0f*100.0f/CM_PER_INCH, T4_RESOLUTION_400_400},
316         { 600.0f*100.0f/CM_PER_INCH, T4_RESOLUTION_600_600},
317         {1200.0f*100.0f/CM_PER_INCH, T4_RESOLUTION_1200_1200},
318         {                    -1.00f, -1}
319     };
320     int i;
321     int best_entry;
322     float best_ratio;
323     float ratio;
324 
325     if (actual == 0.0f)
326         return -1;
327 
328     best_ratio = 0.0f;
329     best_entry = 0;
330     for (i = 0;  x_res_table[i].resolution > 0.0f;  i++)
331     {
332         if (!(allowed_resolutions & x_res_table[i].resolution_code))
333             continue;
334         if (actual > x_res_table[i].resolution)
335             ratio = x_res_table[i].resolution/actual;
336         else
337             ratio = actual/x_res_table[i].resolution;
338         if (ratio > best_ratio)
339         {
340             best_entry = i;
341             best_ratio = ratio;
342         }
343     }
344     return x_res_table[best_entry].resolution_code;
345 }
346 /*- End of function --------------------------------------------------------*/
347 #endif
348 
349 #if defined(SPANDSP_SUPPORT_TIFF_FX)
read_colour_map(t4_tx_state_t * s,int bits_per_sample)350 static int read_colour_map(t4_tx_state_t *s, int bits_per_sample)
351 {
352     int i;
353     uint16_t *map_L;
354     uint16_t *map_a;
355     uint16_t *map_b;
356     uint16_t *map_z;
357 
358     map_L = NULL;
359     map_a = NULL;
360     map_b = NULL;
361     map_z = NULL;
362     if (!TIFFGetField(s->tiff.tiff_file, TIFFTAG_COLORMAP, &map_L, &map_a, &map_b, &map_z))
363         return -1;
364 
365     /* TODO: This only allows for 8 bit deep maps */
366     span_log(&s->logging, SPAN_LOG_FLOW, "Got a colour map\n");
367     s->colour_map_entries = 1 << bits_per_sample;
368     if ((s->colour_map = span_realloc(s->colour_map, 3*s->colour_map_entries)) == NULL)
369         return -1;
370 #if 0
371     /* Sweep the colormap in the proper order */
372     for (i = 0;  i < s->colour_map_entries;  i++)
373     {
374         s->colour_map[3*i + 0] = (map_L[i] >> 8) & 0xFF;
375         s->colour_map[3*i + 1] = (map_a[i] >> 8) & 0xFF;
376         s->colour_map[3*i + 2] = (map_b[i] >> 8) & 0xFF;
377         span_log(&s->logging, SPAN_LOG_FLOW, "Map %3d - %5d %5d %5d\n", i, s->colour_map[3*i], s->colour_map[3*i + 1], s->colour_map[3*i + 2]);
378     }
379 #else
380     /* Sweep the colormap in the order that seems to work for l04x_02x.tif */
381     for (i = 0;  i < s->colour_map_entries;  i++)
382     {
383         s->colour_map[0*s->colour_map_entries + i] = (map_L[i] >> 8) & 0xFF;
384         s->colour_map[1*s->colour_map_entries + i] = (map_a[i] >> 8) & 0xFF;
385         s->colour_map[2*s->colour_map_entries + i] = (map_b[i] >> 8) & 0xFF;
386     }
387 #endif
388     lab_to_srgb(&s->lab_params, s->colour_map, s->colour_map, s->colour_map_entries);
389     for (i = 0;  i < s->colour_map_entries;  i++)
390         span_log(&s->logging, SPAN_LOG_FLOW, "Map %3d - %5d %5d %5d\n", i, s->colour_map[3*i], s->colour_map[3*i + 1], s->colour_map[3*i + 2]);
391     return 0;
392 }
393 /*- End of function --------------------------------------------------------*/
394 #endif
395 
get_tiff_directory_info(t4_tx_state_t * s)396 static int get_tiff_directory_info(t4_tx_state_t *s)
397 {
398 #if defined(SPANDSP_SUPPORT_TIFF_FX)
399     static const char *tiff_fx_fax_profiles[] =
400     {
401         "???",
402         "profile S",
403         "profile F",
404         "profile J",
405         "profile C",
406         "profile L",
407         "profile M"
408     };
409     char *u;
410     char uu[10];
411     float *fl_parms;
412     toff_t diroff;
413     float lmin;
414     float lmax;
415     float amin;
416     float amax;
417     float bmin;
418     float bmax;
419     uint8_t parm8;
420 #endif
421 #if defined(SPANDSP_SUPPORT_TIFF_FX)
422     uint16_t parm16;
423 #endif
424     uint32_t parm32;
425     int best_x_entry;
426     int best_y_entry;
427     float x_resolution;
428     float y_resolution;
429     t4_tx_tiff_state_t *t;
430     uint16_t bits_per_sample;
431     uint16_t samples_per_pixel;
432     uint16_t res_unit;
433     uint16_t YCbCrSubsample_horiz;
434     uint16_t YCbCrSubsample_vert;
435 
436     t = &s->tiff;
437     bits_per_sample = 1;
438     TIFFGetField(t->tiff_file, TIFFTAG_BITSPERSAMPLE, &bits_per_sample);
439     samples_per_pixel = 1;
440     TIFFGetField(t->tiff_file, TIFFTAG_SAMPLESPERPIXEL, &samples_per_pixel);
441     if (samples_per_pixel == 1  &&  bits_per_sample == 1)
442         t->image_type = T4_IMAGE_TYPE_BILEVEL;
443     else if (samples_per_pixel == 3  &&  bits_per_sample == 1)
444         t->image_type = T4_IMAGE_TYPE_COLOUR_BILEVEL;
445     else if (samples_per_pixel == 4  &&  bits_per_sample == 1)
446         t->image_type = T4_IMAGE_TYPE_COLOUR_BILEVEL;
447     else if (samples_per_pixel == 1  &&  bits_per_sample == 8)
448         t->image_type = T4_IMAGE_TYPE_GRAY_8BIT;
449     else if (samples_per_pixel == 1  &&  bits_per_sample > 8)
450         t->image_type = T4_IMAGE_TYPE_GRAY_12BIT;
451     else if (samples_per_pixel == 3  &&  bits_per_sample == 8)
452         t->image_type = T4_IMAGE_TYPE_COLOUR_8BIT;
453     else if (samples_per_pixel == 3  &&  bits_per_sample > 8)
454         t->image_type = T4_IMAGE_TYPE_COLOUR_12BIT;
455     else
456         return -1;
457 
458 #if defined(SPANDSP_SUPPORT_TIFF_FX)
459     parm16 = 0;
460     if (TIFFGetField(t->tiff_file, TIFFTAG_INDEXED, &parm16))
461     {
462         span_log(&s->logging, SPAN_LOG_FLOW, "Indexed %s (%u)\n", (parm16)  ?  "palette image"  :  "non-palette image", parm16);
463         if (parm16 == 1)
464         {
465             /* Its an indexed image, so its really a colour image, even though it may have only one sample per pixel */
466             if (samples_per_pixel == 1  &&  bits_per_sample == 8)
467                 t->image_type = T4_IMAGE_TYPE_COLOUR_8BIT;
468             else if (samples_per_pixel == 1  &&  bits_per_sample > 8)
469                 t->image_type = T4_IMAGE_TYPE_COLOUR_12BIT;
470         }
471     }
472 #endif
473 
474     parm32 = 0;
475     TIFFGetField(t->tiff_file, TIFFTAG_IMAGEWIDTH, &parm32);
476     t->image_width = parm32;
477     parm32 = 0;
478     TIFFGetField(t->tiff_file, TIFFTAG_IMAGELENGTH, &parm32);
479     t->image_length = parm32;
480 
481     x_resolution = 0.0f;
482     TIFFGetField(t->tiff_file, TIFFTAG_XRESOLUTION, &x_resolution);
483     y_resolution = 0.0f;
484     TIFFGetField(t->tiff_file, TIFFTAG_YRESOLUTION, &y_resolution);
485     res_unit = RESUNIT_INCH;
486     TIFFGetField(t->tiff_file, TIFFTAG_RESOLUTIONUNIT, &res_unit);
487 
488     t->x_resolution = x_resolution*100.0f;
489     t->y_resolution = y_resolution*100.0f;
490     if (res_unit == RESUNIT_INCH)
491     {
492         t->x_resolution /= CM_PER_INCH;
493         t->y_resolution /= CM_PER_INCH;
494     }
495 
496     if (((best_x_entry = match_resolution(t->x_resolution, x_res_table)) >= 0)
497         &&
498         ((best_y_entry = match_resolution(t->y_resolution, y_res_table)) >= 0))
499     {
500         t->resolution_code = resolution_map[best_y_entry][best_x_entry];
501     }
502     else
503     {
504         t->resolution_code = 0;
505     }
506 
507     t->photo_metric = PHOTOMETRIC_MINISWHITE;
508     TIFFGetField(t->tiff_file, TIFFTAG_PHOTOMETRIC, &t->photo_metric);
509 
510     /* The default luminant is D50 */
511     set_lab_illuminant(&s->lab_params, 96.422f, 100.000f,  82.521f);
512     set_lab_gamut(&s->lab_params, 0, 100, -85, 85, -75, 125, false);
513 
514     t->compression = -1;
515     TIFFGetField(t->tiff_file, TIFFTAG_COMPRESSION, &t->compression);
516     switch (t->compression)
517     {
518     case COMPRESSION_CCITT_T4:
519         span_log(&s->logging, SPAN_LOG_FLOW, "T.4\n");
520         break;
521     case COMPRESSION_CCITT_T6:
522         span_log(&s->logging, SPAN_LOG_FLOW, "T.6\n");
523         break;
524     case COMPRESSION_T85:
525         span_log(&s->logging, SPAN_LOG_FLOW, "T.85\n");
526         break;
527     case COMPRESSION_T43:
528         span_log(&s->logging, SPAN_LOG_FLOW, "T.43\n");
529         break;
530     case COMPRESSION_JPEG:
531         span_log(&s->logging, SPAN_LOG_FLOW, "JPEG\n");
532         if (t->photo_metric == PHOTOMETRIC_ITULAB)
533             span_log(&s->logging, SPAN_LOG_FLOW, "ITULAB\n");
534         break;
535     case COMPRESSION_NONE:
536         span_log(&s->logging, SPAN_LOG_FLOW, "No compression\n");
537         break;
538     default:
539         span_log(&s->logging, SPAN_LOG_FLOW, "Unexpected compression %d\n", t->compression);
540         break;
541     }
542 
543 #if defined(SPANDSP_SUPPORT_TIFF_FX)
544     read_colour_map(s, bits_per_sample);
545 #endif
546 
547     YCbCrSubsample_horiz = 0;
548     YCbCrSubsample_vert = 0;
549     if (TIFFGetField(t->tiff_file, TIFFTAG_YCBCRSUBSAMPLING, &YCbCrSubsample_horiz, &YCbCrSubsample_vert))
550         span_log(&s->logging, SPAN_LOG_FLOW, "Subsampling %d %d\n", YCbCrSubsample_horiz, YCbCrSubsample_vert);
551 
552     t->fill_order = FILLORDER_LSB2MSB;
553 
554 #if defined(SPANDSP_SUPPORT_TIFF_FX)
555     if (TIFFGetField(t->tiff_file, TIFFTAG_PROFILETYPE, &parm32))
556         span_log(&s->logging, SPAN_LOG_FLOW, "Profile type %u\n", parm32);
557     if (TIFFGetField(t->tiff_file, TIFFTAG_FAXPROFILE, &parm8))
558         span_log(&s->logging, SPAN_LOG_FLOW, "FAX profile %s (%u)\n", tiff_fx_fax_profiles[parm8], parm8);
559 
560     if (TIFFGetField(t->tiff_file, TIFFTAG_CODINGMETHODS, &parm32))
561         span_log(&s->logging, SPAN_LOG_FLOW, "Coding methods 0x%x\n", parm32);
562     if (TIFFGetField(t->tiff_file, TIFFTAG_VERSIONYEAR, &u))
563     {
564         memcpy(uu, u, 4);
565         uu[4] = '\0';
566         span_log(&s->logging, SPAN_LOG_FLOW, "Version year \"%s\"\n", uu);
567     }
568     if (TIFFGetField(t->tiff_file, TIFFTAG_MODENUMBER, &parm8))
569         span_log(&s->logging, SPAN_LOG_FLOW, "Mode number %u\n", parm8);
570 
571     switch (t->photo_metric)
572     {
573     case PHOTOMETRIC_ITULAB:
574 #if 1
575         /* 8 bit version */
576         lmin = 0.0f;
577         lmax = 100.0f;
578         amin = -21760.0f/255.0f;
579         amax = 21590.0f/255.0f;
580         bmin = -19200.0f/255.0f;
581         bmax = 31800.0f/255.0f;
582 #else
583         /* 12 bit version */
584         lmin = 0.0f;
585         lmax = 100.0f;
586         amin = -348160.0f/4095.0f
587         amax = 347990.0f/4095.0f
588         bmin = -307200.0f/4095.0f
589         bmax = 511800.0f/4095.0f
590 #endif
591         break;
592     default:
593         lmin = 0.0f;
594         lmax = 0.0f;
595         amin = 0.0f;
596         amax = 0.0f;
597         bmin = 0.0f;
598         bmax = 0.0f;
599         break;
600     }
601 
602     if (TIFFGetField(t->tiff_file, TIFFTAG_DECODE, &parm16, &fl_parms))
603     {
604         lmin = fl_parms[0];
605         lmax = fl_parms[1];
606         amin = fl_parms[2];
607         amax = fl_parms[3];
608         bmin = fl_parms[4];
609         bmax = fl_parms[5];
610         span_log(&s->logging, SPAN_LOG_FLOW, "Got decode tag %f %f %f %f %f %f\n", lmin, lmax, amin, amax, bmin, bmax);
611     }
612 
613     /* TIFFTAG_IMAGEBASECOLOR */
614 
615     if (TIFFGetField(t->tiff_file, TIFFTAG_T82OPTIONS, &parm32))
616         span_log(&s->logging, SPAN_LOG_FLOW, "T.82 options 0x%x\n", parm32);
617 
618     /* TIFFTAG_STRIPROWCOUNTS */
619     /* TIFFTAG_IMAGELAYER */
620 
621     /* If global parameters are present they should only be on the first page of the file.
622        However, as we scan the file we might as well look for them on any page. */
623     diroff = 0;
624     if (TIFFGetField(t->tiff_file, TIFFTAG_GLOBALPARAMETERSIFD, &diroff))
625     {
626 #if TIFFLIB_VERSION >= 20120922  &&  defined(HAVE_TIF_DIR_H)
627         if (!TIFFReadCustomDirectory(t->tiff_file, diroff, &tiff_fx_field_array))
628         {
629             span_log(&s->logging, SPAN_LOG_FLOW, "Global parameter read failed\n");
630         }
631         else
632         {
633             span_log(&s->logging, SPAN_LOG_FLOW, "Global parameters\n");
634             if (TIFFGetField(t->tiff_file, TIFFTAG_PROFILETYPE, &parm32))
635                 span_log(&s->logging, SPAN_LOG_FLOW, "  Profile type %u\n", parm32);
636             if (TIFFGetField(t->tiff_file, TIFFTAG_FAXPROFILE, &parm8))
637                 span_log(&s->logging, SPAN_LOG_FLOW, "  FAX profile %s (%u)\n", tiff_fx_fax_profiles[parm8], parm8);
638             if (TIFFGetField(t->tiff_file, TIFFTAG_CODINGMETHODS, &parm32))
639                 span_log(&s->logging, SPAN_LOG_FLOW, "  Coding methods 0x%x\n", parm32);
640             if (TIFFGetField(t->tiff_file, TIFFTAG_VERSIONYEAR, &u))
641             {
642                 memcpy(uu, u, 4);
643                 uu[4] = '\0';
644                 span_log(&s->logging, SPAN_LOG_FLOW, "  Version year \"%s\"\n", uu);
645             }
646             if (TIFFGetField(t->tiff_file, TIFFTAG_MODENUMBER, &parm8))
647                 span_log(&s->logging, SPAN_LOG_FLOW, "  Mode number %u\n", parm8);
648 
649             if (!TIFFSetDirectory(t->tiff_file, (tdir_t) s->current_page))
650                 span_log(&s->logging, SPAN_LOG_FLOW, "Failed to set directory to page %d\n", s->current_page);
651         }
652 #endif
653     }
654 #endif
655     return 0;
656 }
657 /*- End of function --------------------------------------------------------*/
658 
test_tiff_directory_info(t4_tx_state_t * s)659 static int test_tiff_directory_info(t4_tx_state_t *s)
660 {
661     uint16_t res_unit;
662     uint32_t parm32;
663     uint16_t bits_per_sample;
664     uint16_t samples_per_pixel;
665     int image_type;
666     float x_resolution;
667     float y_resolution;
668     t4_tx_tiff_state_t *t;
669 
670     t = &s->tiff;
671     bits_per_sample = 1;
672     TIFFGetField(t->tiff_file, TIFFTAG_BITSPERSAMPLE, &bits_per_sample);
673     samples_per_pixel = 1;
674     TIFFGetField(t->tiff_file, TIFFTAG_SAMPLESPERPIXEL, &samples_per_pixel);
675     if (samples_per_pixel == 1  &&  bits_per_sample == 1)
676         image_type = T4_IMAGE_TYPE_BILEVEL;
677     else if (samples_per_pixel == 3  &&  bits_per_sample == 1)
678         image_type = T4_IMAGE_TYPE_COLOUR_BILEVEL;
679     else if (samples_per_pixel == 4  &&  bits_per_sample == 1)
680         image_type = T4_IMAGE_TYPE_COLOUR_BILEVEL;
681     else if (samples_per_pixel == 1  &&  bits_per_sample == 8)
682         image_type = T4_IMAGE_TYPE_GRAY_8BIT;
683     else if (samples_per_pixel == 1  &&  bits_per_sample > 8)
684         image_type = T4_IMAGE_TYPE_GRAY_12BIT;
685     else if (samples_per_pixel == 3  &&  bits_per_sample == 8)
686         image_type = T4_IMAGE_TYPE_COLOUR_8BIT;
687     else if (samples_per_pixel == 3  &&  bits_per_sample > 8)
688         image_type = T4_IMAGE_TYPE_COLOUR_12BIT;
689     else
690         image_type = -1;
691     if (t->image_type != image_type)
692         return 1;
693 
694     parm32 = 0;
695     TIFFGetField(t->tiff_file, TIFFTAG_IMAGEWIDTH, &parm32);
696     if (s->tiff.image_width != (int) parm32)
697         return 2;
698 
699     x_resolution = 0.0f;
700     TIFFGetField(t->tiff_file, TIFFTAG_XRESOLUTION, &x_resolution);
701     y_resolution = 0.0f;
702     TIFFGetField(t->tiff_file, TIFFTAG_YRESOLUTION, &y_resolution);
703     res_unit = RESUNIT_INCH;
704     TIFFGetField(t->tiff_file, TIFFTAG_RESOLUTIONUNIT, &res_unit);
705 
706     x_resolution *= 100.0f;
707     y_resolution *= 100.0f;
708     if (res_unit == RESUNIT_INCH)
709     {
710         x_resolution /= CM_PER_INCH;
711         y_resolution /= CM_PER_INCH;
712     }
713     if (s->tiff.x_resolution != (int) x_resolution)
714         return 3;
715     if (s->tiff.y_resolution != (int) y_resolution)
716         return 4;
717 
718     return 0;
719 }
720 /*- End of function --------------------------------------------------------*/
721 
get_tiff_total_pages(t4_tx_state_t * s)722 static int get_tiff_total_pages(t4_tx_state_t *s)
723 {
724     int max;
725 
726     /* Each page *should* contain the total number of pages, but can this be
727        trusted? Some files say 0. Actually searching for the last page is
728        more reliable. */
729     max = 0;
730     while (TIFFSetDirectory(s->tiff.tiff_file, (tdir_t) max))
731         max++;
732     /* Back to the previous page */
733     if (!TIFFSetDirectory(s->tiff.tiff_file, (tdir_t) s->current_page))
734         return -1;
735     return max;
736 }
737 /*- End of function --------------------------------------------------------*/
738 
open_tiff_input_file(t4_tx_state_t * s,const char * file)739 static int open_tiff_input_file(t4_tx_state_t *s, const char *file)
740 {
741     if ((s->tiff.tiff_file = TIFFOpen(file, "r")) == NULL)
742         return -1;
743     return 0;
744 }
745 /*- End of function --------------------------------------------------------*/
746 
metadata_row_read_handler(void * user_data,uint8_t buf[],size_t len)747 static int metadata_row_read_handler(void *user_data, uint8_t buf[], size_t len)
748 {
749     t4_tx_state_t *s;
750 
751     s = (t4_tx_state_t *) user_data;
752     if (s->tiff.row >= s->metadata.image_length)
753         return 0;
754     memcpy(buf, &s->tiff.image_buffer[s->tiff.row*len], len);
755     s->tiff.row++;
756     return len;
757 }
758 /*- End of function --------------------------------------------------------*/
759 
tiff_row_read_handler(void * user_data,uint8_t buf[],size_t len)760 static int tiff_row_read_handler(void *user_data, uint8_t buf[], size_t len)
761 {
762     t4_tx_state_t *s;
763     int i;
764     int j;
765 
766     s = (t4_tx_state_t *) user_data;
767     if (s->tiff.row >= s->tiff.image_length)
768         return 0;
769     if (s->tiff.image_buffer == NULL)
770         return 0;
771     memcpy(buf, &s->tiff.image_buffer[s->tiff.row*len], len);
772     s->tiff.row++;
773 
774     /* If this is a bi-level image which has more vertical resolution than the
775        far end will accept, we need to squash it down to size. */
776     for (i = 1;  i < s->row_squashing_ratio  &&  s->tiff.row < s->tiff.image_length;  i++)
777     {
778         for (j = 0;  j < len;  j++)
779             buf[j] |= s->tiff.image_buffer[s->tiff.row*len + j];
780         s->tiff.row++;
781     }
782     return len;
783 }
784 /*- End of function --------------------------------------------------------*/
785 
translate_row_read2(void * user_data,uint8_t buf[],size_t len)786 static int translate_row_read2(void *user_data, uint8_t buf[], size_t len)
787 {
788     t4_tx_state_t *s;
789 
790     s = (t4_tx_state_t *) user_data;
791     memcpy(buf, &s->pack_buf[s->pack_ptr], len);
792     s->pack_ptr += len;
793     s->pack_row++;
794     return len;
795 }
796 /*- End of function --------------------------------------------------------*/
797 
translate_row_read(void * user_data,uint8_t buf[],size_t len)798 static int translate_row_read(void *user_data, uint8_t buf[], size_t len)
799 {
800     t4_tx_state_t *s;
801     int i;
802     int j;
803 
804     s = (t4_tx_state_t *) user_data;
805 
806     if (s->tiff.raw_row >= s->tiff.image_length)
807         return 0;
808 
809     if (TIFFReadScanline(s->tiff.tiff_file, buf, s->tiff.raw_row, 0) < 0)
810         return 0;
811     s->tiff.raw_row++;
812 
813     /* If this is a bi-level image which is stretched more vertically than we are able
814        to send we need to squash it down to size. */
815     for (i = 1;  i < s->row_squashing_ratio;  i++)
816     {
817 #if defined(_MSC_VER)
818         uint8_t *extra_buf = (uint8_t *) _alloca(len);
819 #else
820         uint8_t extra_buf[len];
821 #endif
822 
823         if (TIFFReadScanline(s->tiff.tiff_file, extra_buf, s->tiff.raw_row, 0) < 0)
824             return 0;
825         s->tiff.raw_row++;
826         /* We know this is a bi-level image if we are squashing */
827         for (j = 0;  j < s->tiff.image_width/8;  j++)
828             buf[j] |= extra_buf[s->tiff.image_width/8 + j];
829     }
830     if (s->apply_lab)
831         lab_to_srgb(&s->lab_params, buf, buf, len/3);
832     return len;
833 }
834 /*- End of function --------------------------------------------------------*/
835 
packing_row_write_handler(void * user_data,const uint8_t buf[],size_t len)836 static int packing_row_write_handler(void *user_data, const uint8_t buf[], size_t len)
837 {
838     packer_t *s;
839 
840     s = (packer_t *) user_data;
841     memcpy(&s->buf[s->ptr], buf, len);
842     s->ptr += len;
843     s->row++;
844     return 0;
845 }
846 /*- End of function --------------------------------------------------------*/
847 
embedded_comment_handler(void * user_data,const uint8_t buf[],size_t len)848 static int embedded_comment_handler(void *user_data, const uint8_t buf[], size_t len)
849 {
850     t4_tx_state_t *s;
851 
852     s = (t4_tx_state_t *) user_data;
853     if (buf)
854         span_log(&s->logging, SPAN_LOG_WARNING, "T.85 comment (%d): %s\n", (int) len, buf);
855     else
856         span_log(&s->logging, SPAN_LOG_WARNING, "T.85 comment (%d): ---\n", (int) len);
857     return 0;
858 }
859 /*- End of function --------------------------------------------------------*/
860 
read_tiff_raw_image(t4_tx_state_t * s)861 static int read_tiff_raw_image(t4_tx_state_t *s)
862 {
863     int num_strips;
864     int total_len;
865     int len;
866     int i;
867 
868     num_strips = TIFFNumberOfStrips(s->tiff.tiff_file);
869     total_len = 0;
870     for (i = 0;  i < num_strips;  i++)
871         total_len += TIFFRawStripSize(s->tiff.tiff_file, i);
872     if ((s->no_encoder.buf = span_realloc(s->no_encoder.buf, total_len)) == NULL)
873         return -1;
874     total_len = 0;
875     for (i = 0;  i < num_strips;  i++, total_len += len)
876     {
877         len = TIFFRawStripSize(s->tiff.tiff_file, i);
878         if ((len = TIFFReadRawStrip(s->tiff.tiff_file, i, &s->no_encoder.buf[total_len], len)) < 0)
879         {
880             span_log(&s->logging, SPAN_LOG_WARNING, "%s: TIFFReadRawStrip error.\n", s->tiff.file);
881             return -1;
882         }
883     }
884     s->no_encoder.buf_len = total_len;
885     s->no_encoder.buf_ptr = 0;
886     return 0;
887 }
888 /*- End of function --------------------------------------------------------*/
889 
read_tiff_t85_image(t4_tx_state_t * s)890 static int read_tiff_t85_image(t4_tx_state_t *s)
891 {
892     int biggest;
893     int num_strips;
894     int len;
895     int i;
896     int result;
897     uint8_t *t;
898     uint8_t *raw_data;
899     t85_decode_state_t t85;
900     packer_t pack;
901 
902     /* Size up and allocate the buffer for the raw data */
903     num_strips = TIFFNumberOfStrips(s->tiff.tiff_file);
904     biggest = 0;
905     for (i = 0;  i < num_strips;  i++)
906     {
907         len = TIFFRawStripSize(s->tiff.tiff_file, i);
908         if (len > biggest)
909             biggest = len;
910     }
911     if ((raw_data = span_alloc(biggest)) == NULL)
912         return -1;
913 
914     s->tiff.image_size = s->tiff.image_length*((s->tiff.image_width + 7)/8);
915     if (s->tiff.image_size >= s->tiff.image_buffer_size)
916     {
917         if ((t = span_realloc(s->tiff.image_buffer, s->tiff.image_size)) == NULL)
918         {
919             span_free(raw_data);
920             return -1;
921         }
922         s->tiff.image_buffer_size = s->tiff.image_size;
923         s->tiff.image_buffer = t;
924     }
925 
926     pack.buf = s->tiff.image_buffer;
927     pack.ptr = 0;
928     pack.size = s->tiff.image_size;
929     pack.row = 0;
930     t85_decode_init(&t85, packing_row_write_handler, &pack);
931     t85_decode_set_comment_handler(&t85, 1000, embedded_comment_handler, s);
932     t85_decode_set_image_size_constraints(&t85, s->tiff.image_width, s->tiff.image_length);
933     result = -1;
934     for (i = 0;  i < num_strips;  i++)
935     {
936         len = TIFFRawStripSize(s->tiff.tiff_file, i);
937         if ((len = TIFFReadRawStrip(s->tiff.tiff_file, i, raw_data, len)) < 0)
938         {
939             span_log(&s->logging, SPAN_LOG_WARNING, "%s: TIFFReadRawStrip error.\n", s->tiff.file);
940             span_free(raw_data);
941             return -1;
942         }
943         if ((result = t85_decode_put(&t85, raw_data, len)) != T4_DECODE_MORE_DATA)
944             break;
945     }
946     if (result == T4_DECODE_MORE_DATA)
947         t85_decode_put(&t85, NULL, 0);
948 
949     len = t85_decode_get_compressed_image_size(&t85);
950     span_log(&s->logging, SPAN_LOG_WARNING, "Compressed image is %d bytes, %d rows\n", len/8, s->tiff.image_length);
951     t85_decode_release(&t85);
952     span_free(raw_data);
953     return 0;
954 }
955 /*- End of function --------------------------------------------------------*/
956 
957 #if defined(SPANDSP_SUPPORT_T43)
read_tiff_t43_image(t4_tx_state_t * s)958 static int read_tiff_t43_image(t4_tx_state_t *s)
959 {
960     int biggest;
961     int num_strips;
962     int len;
963     int i;
964     int result;
965     uint8_t *t;
966     uint8_t *raw_data;
967     logging_state_t *logging;
968     t43_decode_state_t t43;
969     packer_t pack;
970     uint16_t bits_per_sample;
971     uint16_t samples_per_pixel;
972 
973     bits_per_sample = 1;
974     TIFFGetField(s->tiff.tiff_file, TIFFTAG_BITSPERSAMPLE, &bits_per_sample);
975     samples_per_pixel = 3;
976     TIFFGetField(s->tiff.tiff_file, TIFFTAG_SAMPLESPERPIXEL, &samples_per_pixel);
977 
978     samples_per_pixel = 3;
979 
980     num_strips = TIFFNumberOfStrips(s->tiff.tiff_file);
981     biggest = 0;
982     for (i = 0;  i < num_strips;  i++)
983     {
984         len = TIFFRawStripSize(s->tiff.tiff_file, i);
985         if (len > biggest)
986             biggest = len;
987     }
988     if ((raw_data = span_alloc(biggest)) == NULL)
989         return -1;
990 
991     s->tiff.image_size = samples_per_pixel*s->tiff.image_width*s->tiff.image_length;
992     if (s->tiff.image_size >= s->tiff.image_buffer_size)
993     {
994         if ((t = span_realloc(s->tiff.image_buffer, s->tiff.image_size)) == NULL)
995         {
996             span_free(raw_data);
997             return -1;
998         }
999         s->tiff.image_buffer_size = s->tiff.image_size;
1000         s->tiff.image_buffer = t;
1001     }
1002 
1003     t43_decode_init(&t43, packing_row_write_handler, &pack);
1004     t43_decode_set_comment_handler(&t43, 1000, embedded_comment_handler, NULL);
1005     t43_decode_set_image_size_constraints(&t43, s->tiff.image_width, s->tiff.image_length);
1006     logging = t43_decode_get_logging_state(&t43);
1007     span_log_set_level(logging, SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
1008 
1009     pack.buf = s->tiff.image_buffer;
1010     pack.ptr = 0;
1011     pack.size = s->tiff.image_size;
1012     pack.row = 0;
1013 
1014     result = -1;
1015     for (i = 0;  i < num_strips;  i++)
1016     {
1017         len = TIFFRawStripSize(s->tiff.tiff_file, i);
1018         if ((len = TIFFReadRawStrip(s->tiff.tiff_file, i, raw_data, len)) < 0)
1019         {
1020             span_log(&s->logging, SPAN_LOG_WARNING, "%s: TIFFReadRawStrip error.\n", s->tiff.file);
1021             span_free(raw_data);
1022             return -1;
1023         }
1024         if ((result = t43_decode_put(&t43, raw_data, len)) != T4_DECODE_MORE_DATA)
1025             break;
1026     }
1027     if (result == T4_DECODE_MORE_DATA)
1028         result = t43_decode_put(&t43, NULL, 0);
1029 
1030     t43_decode_release(&t43);
1031     span_free(raw_data);
1032     return s->tiff.image_size;
1033 }
1034 /*- End of function --------------------------------------------------------*/
1035 #endif
1036 
read_tiff_t42_t81_image(t4_tx_state_t * s)1037 static int read_tiff_t42_t81_image(t4_tx_state_t *s)
1038 {
1039     int total_len;
1040     int len;
1041     int i;
1042     int num_strips;
1043     int total_image_len;
1044     uint8_t *t;
1045     uint8_t *raw_data;
1046     uint8_t *jpeg_table;
1047     uint32_t jpeg_table_len;
1048     packer_t pack;
1049     uint16_t bits_per_sample;
1050     uint16_t samples_per_pixel;
1051     t42_decode_state_t t42;
1052 
1053     bits_per_sample = 1;
1054     TIFFGetField(s->tiff.tiff_file, TIFFTAG_BITSPERSAMPLE, &bits_per_sample);
1055     samples_per_pixel = 1;
1056     TIFFGetField(s->tiff.tiff_file, TIFFTAG_SAMPLESPERPIXEL, &samples_per_pixel);
1057 
1058     num_strips = TIFFNumberOfStrips(s->tiff.tiff_file);
1059     total_image_len = 0;
1060     jpeg_table_len = 0;
1061     if (TIFFGetField(s->tiff.tiff_file, TIFFTAG_JPEGTABLES, &jpeg_table_len, &jpeg_table))
1062     {
1063         total_image_len += (jpeg_table_len - 4);
1064         span_log(&s->logging, SPAN_LOG_FLOW, "JPEG tables %u\n", jpeg_table_len);
1065     }
1066 
1067     for (i = 0;  i < num_strips;  i++)
1068         total_image_len += TIFFRawStripSize(s->tiff.tiff_file, i);
1069     if ((raw_data = span_alloc(total_image_len)) == NULL)
1070         return -1;
1071 
1072     total_len = 0;
1073     if (jpeg_table_len > 0)
1074         total_len += jpeg_table_len - 4;
1075     for (i = 0;  i < num_strips;  i++, total_len += len)
1076     {
1077         if ((len = TIFFReadRawStrip(s->tiff.tiff_file, i, &raw_data[total_len], total_image_len - total_len)) < 0)
1078         {
1079             span_log(&s->logging, SPAN_LOG_WARNING, "%s: TIFFReadRawStrip error.\n", s->tiff.file);
1080             span_free(raw_data);
1081             return -1;
1082         }
1083     }
1084     if (jpeg_table_len > 0)
1085         memcpy(raw_data, jpeg_table, jpeg_table_len - 2);
1086 
1087     if (total_len != total_image_len)
1088         span_log(&s->logging, SPAN_LOG_FLOW, "Size mismatch %d %d\n", (int) total_len, (int) total_image_len);
1089 
1090     s->tiff.image_size = samples_per_pixel*s->tiff.image_width*s->tiff.image_length;
1091     if (s->tiff.image_size >= s->tiff.image_buffer_size)
1092     {
1093         if ((t = span_realloc(s->tiff.image_buffer, s->tiff.image_size)) == NULL)
1094         {
1095             span_free(raw_data);
1096             return -1;
1097         }
1098         s->tiff.image_buffer_size = s->tiff.image_size;
1099         s->tiff.image_buffer = t;
1100     }
1101 
1102     t42_decode_init(&t42, packing_row_write_handler, &pack);
1103 
1104     pack.buf = s->tiff.image_buffer;
1105     pack.ptr = 0;
1106     pack.row = 0;
1107 
1108     t42_decode_put(&t42, raw_data, total_image_len);
1109     t42_decode_put(&t42, NULL, 0);
1110 
1111     t42_decode_release(&t42);
1112     span_free(raw_data);
1113     return s->tiff.image_size;
1114 }
1115 /*- End of function --------------------------------------------------------*/
1116 
read_tiff_decompressed_image(t4_tx_state_t * s)1117 static int read_tiff_decompressed_image(t4_tx_state_t *s)
1118 {
1119     int total_len;
1120     int len;
1121     int num_strips;
1122     int i;
1123     uint8_t *t;
1124 
1125     /* Decode the whole image into a buffer */
1126     /* Let libtiff handle the decompression */
1127     s->tiff.image_size = s->tiff.image_length*TIFFScanlineSize(s->tiff.tiff_file);
1128     if (s->tiff.image_size >= s->tiff.image_buffer_size)
1129     {
1130         if ((t = span_realloc(s->tiff.image_buffer, s->tiff.image_size)) == NULL)
1131             return -1;
1132         s->tiff.image_buffer_size = s->tiff.image_size;
1133         s->tiff.image_buffer = t;
1134     }
1135 
1136     /* Allow for the image being stored in multiple strips. */
1137     num_strips = TIFFNumberOfStrips(s->tiff.tiff_file);
1138     for (i = 0, total_len = 0;  i < num_strips;  i++, total_len += len)
1139     {
1140         if ((len = TIFFReadEncodedStrip(s->tiff.tiff_file, i, &s->tiff.image_buffer[total_len], s->tiff.image_size - total_len)) < 0)
1141         {
1142             span_log(&s->logging, SPAN_LOG_WARNING, "%s: TIFFReadEncodedStrip error.\n", s->tiff.file);
1143             return -1;
1144         }
1145     }
1146     /* We might need to flip all the bits, so 1 = black and 0 = white. */
1147     if (s->tiff.image_type == T4_IMAGE_TYPE_BILEVEL  &&  s->tiff.photo_metric != PHOTOMETRIC_MINISWHITE)
1148     {
1149         span_log(&s->logging, SPAN_LOG_FLOW, "%s: Photometric needs swapping.\n", s->tiff.file);
1150         for (i = 0;  i < s->tiff.image_size;  i++)
1151             s->tiff.image_buffer[i] = ~s->tiff.image_buffer[i];
1152         s->tiff.photo_metric = PHOTOMETRIC_MINISWHITE;
1153     }
1154     /* We might need to bit reverse each of the bytes of the image. */
1155     if (s->tiff.fill_order != FILLORDER_LSB2MSB)
1156         bit_reverse(s->tiff.image_buffer, s->tiff.image_buffer, s->tiff.image_size);
1157     return 0;
1158 }
1159 /*- End of function --------------------------------------------------------*/
1160 
read_tiff_image(t4_tx_state_t * s)1161 static int read_tiff_image(t4_tx_state_t *s)
1162 {
1163     int total_len;
1164     int i;
1165     int alter_image;
1166     uint8_t *t;
1167 
1168     if (s->metadata.image_type != s->tiff.image_type  ||  s->metadata.image_width != s->tiff.image_width)
1169     {
1170         /* We need to rework the image, so it can't pass directly through */
1171         alter_image = true;
1172         image_translate_restart(&s->translator, s->tiff.image_length);
1173         s->metadata.image_length = image_translate_get_output_length(&s->translator);
1174         image_translate_set_row_read_handler(&s->translator, translate_row_read2, s);
1175     }
1176     else
1177     {
1178         alter_image = false;
1179         s->metadata.image_length = s->tiff.image_length;
1180     }
1181     s->pack_buf = NULL;
1182     s->pack_ptr = 0;
1183     s->pack_row = 0;
1184 
1185     s->apply_lab = false;
1186     if (s->tiff.image_type != T4_IMAGE_TYPE_BILEVEL)
1187     {
1188         /* If colour/gray scale is supported we may be able to send the image as it is, perhaps after
1189            a resizing. Otherwise we need to resize it, and squash it to a bilevel image. */
1190         if (s->tiff.compression == COMPRESSION_JPEG  &&  s->tiff.photo_metric == PHOTOMETRIC_ITULAB)
1191         {
1192             if (alter_image)
1193             {
1194                 if (read_tiff_t42_t81_image(s) < 0)
1195                     return -1;
1196                 s->pack_buf = s->tiff.image_buffer;
1197             }
1198             else
1199             {
1200                 /* Read the raw image, and send it as is */
1201                 if (read_tiff_raw_image(s) < 0)
1202                     return -1;
1203             }
1204         }
1205 #if defined(SPANDSP_SUPPORT_T43)
1206         else if (s->tiff.compression == COMPRESSION_T43)
1207         {
1208             if (alter_image)
1209             {
1210                 if ( read_tiff_t43_image(s) < 0)
1211                     return -1;
1212                 s->pack_buf = s->tiff.image_buffer;
1213             }
1214             else
1215             {
1216                 /* Read the raw image, and send it as is */
1217                 if (read_tiff_raw_image(s) < 0)
1218                     return -1;
1219             }
1220         }
1221 #endif
1222 #if defined(SPANDSP_SUPPORT_T45)
1223         else if (s->tiff.compression == COMPRESSION_T45)
1224         {
1225             if (alter_image)
1226             {
1227                 if (read_tiff_t45_image(s) < 0)
1228                     return -1;
1229                 s->pack_buf = s->tiff.image_buffer;
1230             }
1231             else
1232             {
1233                 /* Read the raw image, and send it as is */
1234                 if (read_tiff_raw_image(s) < 0)
1235                     return -1;
1236             }
1237         }
1238 #endif
1239         else
1240         {
1241             /* Let libtiff handle the decompression */
1242             TIFFSetField(s->tiff.tiff_file, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB);
1243             if (alter_image)
1244             {
1245                 image_translate_set_row_read_handler(&s->translator, translate_row_read, s);
1246             }
1247             else
1248             {
1249                 if (read_tiff_decompressed_image(s) < 0)
1250                     return -1;
1251             }
1252         }
1253 
1254         set_image_width(s, s->metadata.image_width);
1255         set_image_length(s, s->metadata.image_length);
1256         t4_tx_set_image_type(s, s->metadata.image_type);
1257         if (s->metadata.image_type == T4_IMAGE_TYPE_BILEVEL)
1258         {
1259             /* We need to dither this image down to pure black and white, possibly resizing it
1260                along the way. */
1261             s->tiff.image_size = (s->metadata.image_width*s->metadata.image_length + 7)/8;
1262             if (s->tiff.image_size >= s->tiff.image_buffer_size)
1263             {
1264                 if ((t = span_realloc(s->tiff.image_buffer, s->tiff.image_size)) == NULL)
1265                     return -1;
1266                 s->tiff.image_buffer_size = s->tiff.image_size;
1267                 s->tiff.image_buffer = t;
1268             }
1269             s->tiff.raw_row = 0;
1270             switch (s->tiff.photo_metric)
1271             {
1272             case PHOTOMETRIC_CIELAB:
1273                 /* The default luminant is D50 */
1274                 set_lab_illuminant(&s->lab_params, 96.422f, 100.000f,  82.521f);
1275                 set_lab_gamut(&s->lab_params, 0, 100, -128, 127, -128, 127, true);
1276                 s->apply_lab = true;
1277                 break;
1278             case PHOTOMETRIC_ITULAB:
1279                 /* The default luminant is D50 */
1280                 set_lab_illuminant(&s->lab_params, 96.422f, 100.000f,  82.521f);
1281                 set_lab_gamut(&s->lab_params, 0, 100, -85, 85, -75, 125, false);
1282                 s->apply_lab = true;
1283                 break;
1284             }
1285             total_len = 0;
1286             for (i = 0;  i < s->metadata.image_length;  i++)
1287                 total_len += image_translate_row(&s->translator, &s->tiff.image_buffer[total_len], s->metadata.image_width/8);
1288             image_translate_release(&s->translator);
1289             s->row_handler = metadata_row_read_handler;
1290             s->row_handler_user_data = (void *) s;
1291         }
1292         else
1293         {
1294             if (alter_image)
1295             {
1296                 total_len = 0;
1297                 s->tiff.image_buffer = span_realloc(s->tiff.image_buffer, s->metadata.image_width*s->metadata.image_length*3);
1298                 for (i = 0;  i < s->metadata.image_length;  i++)
1299                     total_len += image_translate_row(&s->translator, &s->tiff.image_buffer[total_len], s->metadata.image_width);
1300                 image_translate_release(&s->translator);
1301                 s->row_handler = metadata_row_read_handler;
1302                 s->row_handler_user_data = (void *) s;
1303             }
1304             else
1305             {
1306                 s->row_handler = tiff_row_read_handler;
1307                 s->row_handler_user_data = (void *) s;
1308             }
1309         }
1310     }
1311     else
1312     {
1313         /* The original image is a bi-level one. We can't really rescale it, as that works out
1314            really poorly for a bi-level image. It has to be used in its original form. The only
1315            practical exception is to conver a superfine resolution image to a fine resolution one,
1316            or a fine image to a standard resolution one. We could pad slightly short rows or crop
1317            slightly long one, but lets not bother. */
1318         switch (s->tiff.compression)
1319         {
1320 #if defined(SPANDSP_SUPPORT_T88)
1321         case COMPRESSION_T88:
1322             switch (s->metadata.compression)
1323             {
1324             case T4_COMPRESSION_T88:
1325                 /* Read the raw image, and send it as is */
1326                 if (read_tiff_raw_image(s) < 0)
1327                     return -1;
1328                 break;
1329             default:
1330                 /* libtiff probably cannot decompress T.88, so we must handle it ourselves */
1331                 /* Decode the whole image into a buffer */
1332                 if (read_tiff_t88_image(s) < 0)
1333                     return -1;
1334                 break;
1335             }
1336             break;
1337 #endif
1338         case COMPRESSION_T85:
1339             switch (s->metadata.compression)
1340             {
1341             case T4_COMPRESSION_T85:
1342             case T4_COMPRESSION_T85_L0:
1343                 /* Read the raw image, and send it as is */
1344                 if (read_tiff_raw_image(s) < 0)
1345                     return -1;
1346                 break;
1347             default:
1348                 /* libtiff probably cannot decompress T.85, so we must handle it ourselves */
1349                 /* Decode the whole image into a buffer */
1350                 if (read_tiff_t85_image(s) < 0)
1351                     return -1;
1352                 break;
1353             }
1354             break;
1355 #if 0
1356         case COMPRESSION_CCITT_T6:
1357             switch (s->metadata.compression)
1358             {
1359             case T4_COMPRESSION_T6:
1360                 /* Read the raw image, and send it as is */
1361                 if (read_tiff_raw_image(s) < 0)
1362                     return -1;
1363                 break;
1364             default:
1365                 /* Decode the whole image into a buffer */
1366                 /* Let libtiff handle the decompression */
1367                 if (read_tiff_decompressed_image(s) < 0)
1368                     return -1;
1369                 break;
1370             }
1371             break;
1372 #endif
1373         default:
1374             /* Decode the whole image into a buffer */
1375             /* Let libtiff handle the decompression */
1376             if (read_tiff_decompressed_image(s) < 0)
1377                 return -1;
1378             break;
1379         }
1380     }
1381     s->tiff.row = 0;
1382     return s->metadata.image_length;
1383 }
1384 /*- End of function --------------------------------------------------------*/
1385 
tiff_tx_release(t4_tx_state_t * s)1386 static void tiff_tx_release(t4_tx_state_t *s)
1387 {
1388     if (s->tiff.tiff_file)
1389     {
1390         TIFFClose(s->tiff.tiff_file);
1391         s->tiff.tiff_file = NULL;
1392         if (s->tiff.file)
1393             span_free((char *) s->tiff.file);
1394         s->tiff.file = NULL;
1395     }
1396     if (s->tiff.image_buffer)
1397     {
1398         span_free(s->tiff.image_buffer);
1399         s->tiff.image_buffer = NULL;
1400         s->tiff.image_size = 0;
1401         s->tiff.image_buffer_size = 0;
1402     }
1403 }
1404 /*- End of function --------------------------------------------------------*/
1405 
set_row_read_handler(t4_tx_state_t * s,t4_row_read_handler_t handler,void * user_data)1406 static int set_row_read_handler(t4_tx_state_t *s, t4_row_read_handler_t handler, void *user_data)
1407 {
1408     switch (s->metadata.compression)
1409     {
1410     case T4_COMPRESSION_T4_1D:
1411     case T4_COMPRESSION_T4_2D:
1412     case T4_COMPRESSION_T6:
1413         return t4_t6_encode_set_row_read_handler(&s->encoder.t4_t6, handler, user_data);
1414     case T4_COMPRESSION_T85:
1415     case T4_COMPRESSION_T85_L0:
1416         return t85_encode_set_row_read_handler(&s->encoder.t85, handler, user_data);
1417 #if defined(SPANDSP_SUPPORT_T88)
1418     case T4_COMPRESSION_T88:
1419         return t88_encode_set_row_read_handler(&s->encoder.t88, handler, user_data);
1420 #endif
1421     case T4_COMPRESSION_T42_T81:
1422     case T4_COMPRESSION_SYCC_T81:
1423         return t42_encode_set_row_read_handler(&s->encoder.t42, handler, user_data);
1424     case T4_COMPRESSION_T43:
1425         return t43_encode_set_row_read_handler(&s->encoder.t43, handler, user_data);
1426 #if defined(SPANDSP_SUPPORT_T45)
1427     case T4_COMPRESSION_T45:
1428         return t45_encode_set_row_read_handler(&s->encoder.t45, handler, user_data);
1429 #endif
1430     }
1431     return -1;
1432 }
1433 /*- End of function --------------------------------------------------------*/
1434 
make_header(t4_tx_state_t * s)1435 static int make_header(t4_tx_state_t *s)
1436 {
1437     time_t now;
1438     struct tm tm;
1439     static const char *months[] =
1440     {
1441         "Jan", "Feb", "Mar", "Apr", "May", "Jun",
1442         "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
1443     };
1444 
1445     if (s->header_text == NULL)
1446     {
1447         if ((s->header_text = span_alloc(132 + 1)) == NULL)
1448             return -1;
1449     }
1450     /* This is very English oriented, but then most FAX machines are, too. Some
1451        measure of i18n in the time and date, and even the header_info string, is
1452        entirely possible, although the font area would need some serious work to
1453        properly deal with East Asian script. There is no spec for what the header
1454        should contain, or how much of the page it might occupy. The present format
1455        follows the common practice of a few FAX machines. Nothing more. */
1456     time(&now);
1457     if (s->tz)
1458         tz_localtime(s->tz, &tm, now);
1459     else
1460         tm = *localtime(&now);
1461 
1462     snprintf(s->header_text,
1463              132,
1464              "  %2d-%s-%d  %02d:%02d    %-50s %-21s   p.%d",
1465              tm.tm_mday,
1466              months[tm.tm_mon],
1467              tm.tm_year + 1900,
1468              tm.tm_hour,
1469              tm.tm_min,
1470              (s->header_info)  ?  s->header_info  :  "",
1471              (s->local_ident)  ?  s->local_ident  :  "",
1472              s->current_page + 1);
1473     return 0;
1474 }
1475 /*- End of function --------------------------------------------------------*/
1476 
header_row_read_handler(void * user_data,uint8_t buf[],size_t len)1477 static int header_row_read_handler(void *user_data, uint8_t buf[], size_t len)
1478 {
1479     int y_repeats;
1480     int pattern;
1481     int pos;
1482     int row;
1483     int i;
1484     char *t;
1485     t4_tx_state_t *s;
1486 
1487     s = (t4_tx_state_t *) user_data;
1488     switch (s->metadata.resolution_code)
1489     {
1490     default:
1491     case T4_RESOLUTION_100_100:
1492         y_repeats = 1;
1493         break;
1494     case T4_RESOLUTION_R8_STANDARD:
1495     case T4_RESOLUTION_200_100:
1496         y_repeats = 1;
1497         break;
1498     case T4_RESOLUTION_R8_FINE:
1499     case T4_RESOLUTION_200_200:
1500         y_repeats = 2;
1501         break;
1502     case T4_RESOLUTION_300_300:
1503         y_repeats = 3;
1504         break;
1505     case T4_RESOLUTION_R8_SUPERFINE:
1506     case T4_RESOLUTION_200_400:
1507         y_repeats = 4;
1508         break;
1509     case T4_RESOLUTION_R16_SUPERFINE:
1510     case T4_RESOLUTION_400_400:
1511         y_repeats = 4;
1512         break;
1513     case T4_RESOLUTION_400_800:
1514         y_repeats = 8;
1515         break;
1516     case T4_RESOLUTION_300_600:
1517         y_repeats = 6;
1518         break;
1519     case T4_RESOLUTION_600_600:
1520         y_repeats = 6;
1521         break;
1522     case T4_RESOLUTION_600_1200:
1523         y_repeats = 12;
1524         break;
1525     case T4_RESOLUTION_1200_1200:
1526         y_repeats = 12;
1527         break;
1528     }
1529     switch (s->metadata.width_code)
1530     {
1531     case T4_SUPPORT_WIDTH_215MM:
1532         break;
1533     case T4_SUPPORT_WIDTH_255MM:
1534         break;
1535     case T4_SUPPORT_WIDTH_303MM:
1536         break;
1537     }
1538     if (s->header_overlays_image)
1539     {
1540         /* Read and dump a row of the real image, allowing for the possibility
1541            that the real image might end within the header itself */
1542         if (len != s->row_handler(s->row_handler_user_data, buf, len))
1543         {
1544             set_row_read_handler(s, s->row_handler, s->row_handler_user_data);
1545             return len;
1546         }
1547     }
1548     t = s->header_text;
1549     row = s->header_row/y_repeats;
1550     pos = 0;
1551     switch (s->metadata.image_type)
1552     {
1553     case T4_IMAGE_TYPE_BILEVEL:
1554         for (  ;  *t  &&  pos <= len - 2;  t++)
1555         {
1556             pattern = header_font[(uint8_t) *t][row];
1557             buf[pos++] = (uint8_t) (pattern >> 8);
1558             buf[pos++] = (uint8_t) (pattern & 0xFF);
1559         }
1560         if (pos < len)
1561             memset(&buf[pos], 0, len - pos);
1562         break;
1563     case T4_IMAGE_TYPE_GRAY_8BIT:
1564         for (  ;  *t  &&  pos <= len - 2;  t++)
1565         {
1566             pattern = header_font[(uint8_t) *t][row];
1567             for (i = 0;  i < 16;  i++)
1568             {
1569                 buf[pos + i] = (pattern & 0x8000)  ?  0  :  0xFF;
1570                 pattern <<= 1;
1571             }
1572             pos += 16;
1573         }
1574         if (pos < len)
1575             memset(&buf[pos], 0xFF, len - pos);
1576         break;
1577     case T4_IMAGE_TYPE_COLOUR_8BIT:
1578         for (  ;  *t  &&  pos <= len - 2;  t++)
1579         {
1580             pattern = header_font[(uint8_t) *t][row];
1581             for (i = 0;  i < 16;  i++)
1582             {
1583                 buf[pos + 3*i + 0] =
1584                 buf[pos + 3*i + 1] =
1585                 buf[pos + 3*i + 2] = (pattern & 0x8000)  ?  0  :  0xFF;
1586                 pattern <<= 1;
1587             }
1588             pos += 3*16;
1589         }
1590         if (pos < len)
1591             memset(&buf[pos], 0xFF, len - pos);
1592         break;
1593     case T4_IMAGE_TYPE_COLOUR_BILEVEL:
1594     case T4_IMAGE_TYPE_4COLOUR_BILEVEL:
1595     case T4_IMAGE_TYPE_GRAY_12BIT:
1596     case T4_IMAGE_TYPE_4COLOUR_8BIT:
1597     case T4_IMAGE_TYPE_COLOUR_12BIT:
1598     case T4_IMAGE_TYPE_4COLOUR_12BIT:
1599     default:
1600         memset(buf, 0xFF, len);
1601     }
1602     s->header_row++;
1603     if (s->header_row >= 16*y_repeats)
1604     {
1605         /* End of header. Change to normal image row data. */
1606         set_row_read_handler(s, s->row_handler, s->row_handler_user_data);
1607     }
1608     return len;
1609 }
1610 /*- End of function --------------------------------------------------------*/
1611 
t4_tx_next_page_has_different_format(t4_tx_state_t * s)1612 SPAN_DECLARE(int) t4_tx_next_page_has_different_format(t4_tx_state_t *s)
1613 {
1614     span_log(&s->logging, SPAN_LOG_FLOW, "Checking for the existence of page %d\n", s->current_page + 1);
1615     if (s->current_page >= s->stop_page)
1616         return -1;
1617     if (s->tiff.file)
1618     {
1619         if (!TIFFSetDirectory(s->tiff.tiff_file, (tdir_t) s->current_page + 1))
1620             return -1;
1621         return test_tiff_directory_info(s);
1622     }
1623     return -1;
1624 }
1625 /*- End of function --------------------------------------------------------*/
1626 
t4_tx_set_row_read_handler(t4_tx_state_t * s,t4_row_read_handler_t handler,void * user_data)1627 SPAN_DECLARE(int) t4_tx_set_row_read_handler(t4_tx_state_t *s, t4_row_read_handler_t handler, void *user_data)
1628 {
1629     s->row_handler = handler;
1630     s->row_handler_user_data = user_data;
1631     return set_row_read_handler(s, handler, user_data);
1632 }
1633 /*- End of function --------------------------------------------------------*/
1634 
release_encoder(t4_tx_state_t * s)1635 static int release_encoder(t4_tx_state_t *s)
1636 {
1637     switch (s->metadata.compression)
1638     {
1639     case T4_COMPRESSION_T4_1D:
1640     case T4_COMPRESSION_T4_2D:
1641     case T4_COMPRESSION_T6:
1642         return t4_t6_encode_release(&s->encoder.t4_t6);
1643     case T4_COMPRESSION_T85:
1644     case T4_COMPRESSION_T85_L0:
1645         return t85_encode_release(&s->encoder.t85);
1646 #if defined(SPANDSP_SUPPORT_T88)
1647     case T4_COMPRESSION_T88:
1648         return t88_encode_release(&s->encoder.t88);
1649 #endif
1650     case T4_COMPRESSION_T42_T81:
1651     case T4_COMPRESSION_SYCC_T81:
1652         return t42_encode_release(&s->encoder.t42);
1653     case T4_COMPRESSION_T43:
1654         return t43_encode_release(&s->encoder.t43);
1655 #if defined(SPANDSP_SUPPORT_T45)
1656     case T4_COMPRESSION_T45:
1657         return t45_encode_release(&s->encoder.t45);
1658 #endif
1659     }
1660     return -1;
1661 }
1662 /*- End of function --------------------------------------------------------*/
1663 
t4_tx_set_tx_image_format(t4_tx_state_t * s,int supported_compressions,int supported_image_sizes,int supported_bilevel_resolutions,int supported_colour_resolutions)1664 SPAN_DECLARE(int) t4_tx_set_tx_image_format(t4_tx_state_t *s,
1665                                             int supported_compressions,
1666                                             int supported_image_sizes,
1667                                             int supported_bilevel_resolutions,
1668                                             int supported_colour_resolutions)
1669 {
1670     static const struct
1671     {
1672         int width;
1673         int width_code;
1674         int res_code;           /* Correct resolution code */
1675         int alt_res_code;       /* Fallback resolution code, where a metric/inch swap is possible */
1676     } width_and_res_info[] =
1677     {
1678         { T4_WIDTH_100_A4, T4_SUPPORT_WIDTH_215MM,       T4_RESOLUTION_100_100,                           0},
1679         { T4_WIDTH_100_B4, T4_SUPPORT_WIDTH_255MM,       T4_RESOLUTION_100_100,                           0},
1680         { T4_WIDTH_100_A3, T4_SUPPORT_WIDTH_303MM,       T4_RESOLUTION_100_100,                           0},
1681         { T4_WIDTH_200_A4, T4_SUPPORT_WIDTH_215MM,       T4_RESOLUTION_200_100,   T4_RESOLUTION_R8_STANDARD},
1682         { T4_WIDTH_200_A4, T4_SUPPORT_WIDTH_215MM,       T4_RESOLUTION_200_200,       T4_RESOLUTION_R8_FINE},
1683         { T4_WIDTH_200_A4, T4_SUPPORT_WIDTH_215MM,       T4_RESOLUTION_200_400,  T4_RESOLUTION_R8_SUPERFINE},
1684         { T4_WIDTH_200_A4, T4_SUPPORT_WIDTH_215MM,   T4_RESOLUTION_R8_STANDARD,       T4_RESOLUTION_200_100},
1685         { T4_WIDTH_200_A4, T4_SUPPORT_WIDTH_215MM,       T4_RESOLUTION_R8_FINE,       T4_RESOLUTION_200_200},
1686         { T4_WIDTH_200_A4, T4_SUPPORT_WIDTH_215MM,  T4_RESOLUTION_R8_SUPERFINE,       T4_RESOLUTION_200_400},
1687         { T4_WIDTH_200_B4, T4_SUPPORT_WIDTH_255MM,       T4_RESOLUTION_200_100,   T4_RESOLUTION_R8_STANDARD},
1688         { T4_WIDTH_200_B4, T4_SUPPORT_WIDTH_255MM,       T4_RESOLUTION_200_200,       T4_RESOLUTION_R8_FINE},
1689         { T4_WIDTH_200_B4, T4_SUPPORT_WIDTH_255MM,       T4_RESOLUTION_200_400,  T4_RESOLUTION_R8_SUPERFINE},
1690         { T4_WIDTH_200_B4, T4_SUPPORT_WIDTH_255MM,   T4_RESOLUTION_R8_STANDARD,       T4_RESOLUTION_200_100},
1691         { T4_WIDTH_200_B4, T4_SUPPORT_WIDTH_255MM,       T4_RESOLUTION_R8_FINE,       T4_RESOLUTION_200_200},
1692         { T4_WIDTH_200_B4, T4_SUPPORT_WIDTH_255MM,  T4_RESOLUTION_R8_SUPERFINE,       T4_RESOLUTION_200_400},
1693         { T4_WIDTH_200_A3, T4_SUPPORT_WIDTH_303MM,       T4_RESOLUTION_200_100,   T4_RESOLUTION_R8_STANDARD},
1694         { T4_WIDTH_200_A3, T4_SUPPORT_WIDTH_303MM,       T4_RESOLUTION_200_200,       T4_RESOLUTION_R8_FINE},
1695         { T4_WIDTH_200_A3, T4_SUPPORT_WIDTH_303MM,       T4_RESOLUTION_200_400,  T4_RESOLUTION_R8_SUPERFINE},
1696         { T4_WIDTH_200_A3, T4_SUPPORT_WIDTH_303MM,   T4_RESOLUTION_R8_STANDARD,       T4_RESOLUTION_200_100},
1697         { T4_WIDTH_200_A3, T4_SUPPORT_WIDTH_303MM,       T4_RESOLUTION_R8_FINE,       T4_RESOLUTION_200_200},
1698         { T4_WIDTH_200_A3, T4_SUPPORT_WIDTH_303MM,  T4_RESOLUTION_R8_SUPERFINE,       T4_RESOLUTION_200_400},
1699         { T4_WIDTH_300_A4, T4_SUPPORT_WIDTH_215MM,       T4_RESOLUTION_300_300,                           0},
1700         { T4_WIDTH_300_A4, T4_SUPPORT_WIDTH_215MM,       T4_RESOLUTION_300_600,                           0},
1701         { T4_WIDTH_300_B4, T4_SUPPORT_WIDTH_255MM,       T4_RESOLUTION_300_300,                           0},
1702         { T4_WIDTH_300_B4, T4_SUPPORT_WIDTH_255MM,       T4_RESOLUTION_300_600,                           0},
1703         { T4_WIDTH_400_A4, T4_SUPPORT_WIDTH_215MM,       T4_RESOLUTION_400_400, T4_RESOLUTION_R16_SUPERFINE},
1704         { T4_WIDTH_400_A4, T4_SUPPORT_WIDTH_215MM,       T4_RESOLUTION_400_800,                           0},
1705         { T4_WIDTH_400_A4, T4_SUPPORT_WIDTH_215MM, T4_RESOLUTION_R16_SUPERFINE,       T4_RESOLUTION_400_400},
1706         { T4_WIDTH_300_A3, T4_SUPPORT_WIDTH_303MM,       T4_RESOLUTION_300_300,                           0},
1707         { T4_WIDTH_300_A3, T4_SUPPORT_WIDTH_303MM,       T4_RESOLUTION_300_600,                           0},
1708         { T4_WIDTH_400_B4, T4_SUPPORT_WIDTH_255MM,       T4_RESOLUTION_400_400, T4_RESOLUTION_R16_SUPERFINE},
1709         { T4_WIDTH_400_B4, T4_SUPPORT_WIDTH_255MM,       T4_RESOLUTION_400_800,                           0},
1710         { T4_WIDTH_400_B4, T4_SUPPORT_WIDTH_255MM, T4_RESOLUTION_R16_SUPERFINE,       T4_RESOLUTION_400_400},
1711         { T4_WIDTH_400_A3, T4_SUPPORT_WIDTH_303MM,       T4_RESOLUTION_400_400, T4_RESOLUTION_R16_SUPERFINE},
1712         { T4_WIDTH_400_A3, T4_SUPPORT_WIDTH_303MM,       T4_RESOLUTION_400_800,                           0},
1713         { T4_WIDTH_400_A3, T4_SUPPORT_WIDTH_303MM, T4_RESOLUTION_R16_SUPERFINE,       T4_RESOLUTION_400_400},
1714         { T4_WIDTH_600_A4, T4_SUPPORT_WIDTH_215MM,       T4_RESOLUTION_600_600,                           0},
1715         { T4_WIDTH_600_A4, T4_SUPPORT_WIDTH_215MM,      T4_RESOLUTION_600_1200,                           0},
1716         { T4_WIDTH_600_B4, T4_SUPPORT_WIDTH_255MM,       T4_RESOLUTION_600_600,                           0},
1717         { T4_WIDTH_600_B4, T4_SUPPORT_WIDTH_255MM,      T4_RESOLUTION_600_1200,                           0},
1718         { T4_WIDTH_600_A3, T4_SUPPORT_WIDTH_303MM,       T4_RESOLUTION_600_600,                           0},
1719         { T4_WIDTH_600_A3, T4_SUPPORT_WIDTH_303MM,      T4_RESOLUTION_600_1200,                           0},
1720         {T4_WIDTH_1200_A4, T4_SUPPORT_WIDTH_215MM,     T4_RESOLUTION_1200_1200,                           0},
1721         {T4_WIDTH_1200_B4, T4_SUPPORT_WIDTH_255MM,     T4_RESOLUTION_1200_1200,                           0},
1722         {T4_WIDTH_1200_A3, T4_SUPPORT_WIDTH_303MM,     T4_RESOLUTION_1200_1200,                           0},
1723         {0x7FFFFFFF, -1, -1, -1}
1724     };
1725 
1726     static const struct
1727     {
1728         int resolution;
1729         struct
1730         {
1731             int resolution;
1732             int squashing_factor;
1733         } fallback[4];
1734     } squashable[4] =
1735     {
1736         {
1737             T4_RESOLUTION_200_400,
1738             {
1739                 {T4_RESOLUTION_200_200,     2},
1740                 {T4_RESOLUTION_R8_FINE,     2},
1741                 {T4_RESOLUTION_200_100,     4},
1742                 {T4_RESOLUTION_R8_STANDARD, 4}
1743             }
1744         },
1745         {
1746             T4_RESOLUTION_200_200,
1747             {
1748                 {T4_RESOLUTION_200_100,     2},
1749                 {T4_RESOLUTION_R8_STANDARD, 2},
1750                 {0,                         0},
1751                 {0,                         0}
1752             }
1753         },
1754         {
1755             T4_RESOLUTION_R8_SUPERFINE,
1756             {
1757                 {T4_RESOLUTION_R8_FINE,     2},
1758                 {T4_RESOLUTION_200_200,     2},
1759                 {T4_RESOLUTION_R8_STANDARD, 4},
1760                 {T4_RESOLUTION_200_100,     4}
1761             }
1762         },
1763         {
1764             T4_RESOLUTION_R8_FINE,
1765             {
1766                 {T4_RESOLUTION_R8_STANDARD, 2},
1767                 {T4_RESOLUTION_200_100,     2},
1768                 {0,                         0},
1769                 {0,                         0}
1770             }
1771         }
1772     };
1773 
1774     int i;
1775     int j;
1776     int entry;
1777     int compression;
1778     int res;
1779     int supported_colour_compressions;
1780 
1781     supported_colour_compressions = supported_compressions & (T4_COMPRESSION_T42_T81 | T4_COMPRESSION_T43 | T4_COMPRESSION_T45 | T4_COMPRESSION_SYCC_T81);
1782     compression = -1;
1783     s->metadata.image_type = s->tiff.image_type;
1784     if (s->tiff.image_type != T4_IMAGE_TYPE_BILEVEL)
1785     {
1786         span_log(&s->logging, SPAN_LOG_FLOW, "Non-bi-level image\n");
1787         /* Can we send this page as it is? */
1788         if (supported_colour_resolutions
1789             &&
1790             supported_colour_compressions
1791             &&
1792                   (((s->tiff.image_type == T4_IMAGE_TYPE_COLOUR_BILEVEL  ||  s->tiff.image_type == T4_IMAGE_TYPE_COLOUR_8BIT  ||  s->tiff.image_type == T4_IMAGE_TYPE_COLOUR_12BIT)
1793                     &&
1794                     (supported_compressions & T4_COMPRESSION_COLOUR))
1795                 ||
1796                    ((s->tiff.image_type == T4_IMAGE_TYPE_GRAY_8BIT  ||  s->tiff.image_type == T4_IMAGE_TYPE_GRAY_12BIT)
1797                     &&
1798                     (supported_compressions & T4_COMPRESSION_GRAYSCALE))))
1799         {
1800             /* Gray-scale/colour is possible */
1801             span_log(&s->logging, SPAN_LOG_FLOW, "Gray-scale/colour is allowed\n");
1802             /* Choose the best gray-scale/colour encoding available to us */
1803             if (s->tiff.image_type == T4_IMAGE_TYPE_COLOUR_BILEVEL  &&  (supported_compressions & T4_COMPRESSION_T43))
1804                 compression = T4_COMPRESSION_T43;
1805             else if ((supported_compressions & T4_COMPRESSION_T42_T81))
1806                 compression = T4_COMPRESSION_T42_T81;
1807             else if ((supported_compressions & T4_COMPRESSION_T43))
1808                 compression = T4_COMPRESSION_T43;
1809             else if ((supported_compressions & T4_COMPRESSION_T45))
1810                 compression = T4_COMPRESSION_T45;
1811             else if ((supported_compressions & T4_COMPRESSION_SYCC_T81))
1812                 compression = T4_COMPRESSION_SYCC_T81;
1813 
1814             //best_colour_resolution(s->tiff.x_resolution, supported_colour_resolutions);
1815         }
1816         else
1817         {
1818             /* Gray-scale/colour is not possible. Can we flatten the image to send it? */
1819             span_log(&s->logging, SPAN_LOG_FLOW, "Gray-scale/colour is not allowed\n");
1820             switch (s->tiff.image_type)
1821             {
1822             case T4_IMAGE_TYPE_COLOUR_BILEVEL:
1823             case T4_IMAGE_TYPE_COLOUR_8BIT:
1824             case T4_IMAGE_TYPE_COLOUR_12BIT:
1825                 if (!(supported_compressions & T4_COMPRESSION_COLOUR_TO_BILEVEL))
1826                 {
1827                     span_log(&s->logging, SPAN_LOG_FLOW, "Flattening is not allowed\n");
1828                     return T4_IMAGE_FORMAT_INCOMPATIBLE;
1829                 }
1830                 break;
1831             case T4_IMAGE_TYPE_GRAY_8BIT:
1832             case T4_IMAGE_TYPE_GRAY_12BIT:
1833                 if (!(supported_compressions & T4_COMPRESSION_GRAY_TO_BILEVEL))
1834                 {
1835                     span_log(&s->logging, SPAN_LOG_FLOW, "Flattening is not allowed\n");
1836                     return T4_IMAGE_FORMAT_INCOMPATIBLE;
1837                 }
1838                 break;
1839             }
1840             /* Squashing to a bi-level image is possible */
1841             s->metadata.image_type = T4_IMAGE_TYPE_BILEVEL;
1842             span_log(&s->logging, SPAN_LOG_FLOW, "The image will be flattened to %s\n", t4_image_type_to_str(s->metadata.image_type));
1843         }
1844     }
1845 
1846     if (s->metadata.image_type == T4_IMAGE_TYPE_BILEVEL)
1847     {
1848         /* Choose the best bi-level encoding available to us */
1849         if ((supported_compressions & T4_COMPRESSION_T85_L0))
1850             compression = T4_COMPRESSION_T85_L0;
1851         else if ((supported_compressions & T4_COMPRESSION_T85))
1852             compression = T4_COMPRESSION_T85;
1853         else if ((supported_compressions & T4_COMPRESSION_T6))
1854             compression = T4_COMPRESSION_T6;
1855         else if ((supported_compressions & T4_COMPRESSION_T4_2D))
1856             compression = T4_COMPRESSION_T4_2D;
1857         else
1858             compression = T4_COMPRESSION_T4_1D;
1859     }
1860 
1861     /* Deal with the image width/resolution combination. */
1862     /* Look for a pattern that matches the image */
1863     s->metadata.width_code = -1;
1864     for (entry = 0;  s->tiff.image_width >= width_and_res_info[entry].width;  entry++)
1865     {
1866         if (s->tiff.image_width == width_and_res_info[entry].width  &&  s->tiff.resolution_code == width_and_res_info[entry].res_code)
1867         {
1868             s->metadata.width_code = width_and_res_info[entry].width_code;
1869             break;
1870         }
1871     }
1872     s->row_squashing_ratio = 1;
1873     if (s->metadata.width_code >= 0  &&  (supported_image_sizes & s->metadata.width_code))
1874     {
1875         /* We have a valid and supported width/resolution combination */
1876 
1877         /* No resize necessary */
1878         s->metadata.image_width = s->tiff.image_width;
1879         s->metadata.image_length = s->tiff.image_length;
1880 
1881         res = T4_IMAGE_FORMAT_NORESSUPPORT;
1882         if (s->metadata.image_type == T4_IMAGE_TYPE_BILEVEL)
1883         {
1884             if ((width_and_res_info[entry].res_code & supported_bilevel_resolutions))
1885             {
1886                 /* We can use the resolution of the original image */
1887                 s->metadata.resolution_code = s->tiff.resolution_code;
1888                 s->metadata.x_resolution = code_to_x_resolution(s->metadata.resolution_code);
1889                 s->metadata.y_resolution = code_to_y_resolution(s->metadata.resolution_code);
1890                 res = T4_IMAGE_FORMAT_OK;
1891             }
1892             else if ((width_and_res_info[entry].alt_res_code & supported_bilevel_resolutions))
1893             {
1894                 /* We can do a metric/imperial swap, and have a usable resolution */
1895                 span_log(&s->logging,
1896                          SPAN_LOG_FLOW,
1897                          "Image resolution %s falls back to %s\n",
1898                          t4_image_resolution_to_str(s->tiff.resolution_code),
1899                          t4_image_resolution_to_str(width_and_res_info[entry].alt_res_code));
1900                 s->metadata.resolution_code = width_and_res_info[entry].alt_res_code;
1901                 s->metadata.x_resolution = code_to_x_resolution(s->metadata.resolution_code);
1902                 s->metadata.y_resolution = code_to_y_resolution(s->metadata.resolution_code);
1903                 res = T4_IMAGE_FORMAT_OK;
1904             }
1905             else
1906             {
1907                 if (s->tiff.image_type == T4_IMAGE_TYPE_BILEVEL)
1908                 {
1909                     if ((s->tiff.resolution_code & (T4_RESOLUTION_200_400 | T4_RESOLUTION_200_200 | T4_RESOLUTION_R8_SUPERFINE | T4_RESOLUTION_R8_FINE)))
1910                     {
1911                         /* This might be a resolution we can squash down to something which is supported */
1912                         for (i = 0;  i < 4;  i++)
1913                         {
1914                             if ((s->tiff.resolution_code & squashable[i].resolution))
1915                                 break;
1916                         }
1917                         if (i < 4)
1918                         {
1919                             /* This is a squashable resolution, so let's see if there is a valid
1920                                fallback we can squash the image to, scanning through the entries
1921                                in their order of preference. */
1922                             for (j = 0;  j < 4;  j++)
1923                             {
1924                                 if ((supported_bilevel_resolutions & squashable[i].fallback[j].resolution))
1925                                 {
1926                                     span_log(&s->logging,
1927                                              SPAN_LOG_FLOW,
1928                                              "Image resolution %s falls back to %s\n",
1929                                              t4_image_resolution_to_str(s->tiff.resolution_code),
1930                                              t4_image_resolution_to_str(squashable[i].fallback[j].resolution));
1931                                     s->row_squashing_ratio = squashable[i].fallback[j].squashing_factor;
1932                                     s->metadata.resolution_code = squashable[i].fallback[j].resolution;
1933                                     s->metadata.x_resolution = code_to_x_resolution(s->metadata.resolution_code);
1934                                     s->metadata.y_resolution = code_to_y_resolution(s->metadata.resolution_code);
1935                                     res = T4_IMAGE_FORMAT_OK;
1936                                     break;
1937                                 }
1938                             }
1939                         }
1940                     }
1941                 }
1942             }
1943             /* If we have not succeeded in matching up the size and resolution, the next step will
1944                depend on whether the original was a bi-level image. If it was, we are stuck, as you can't
1945                really resize those. If it was not, a resize might be possible */
1946             if (res != T4_IMAGE_FORMAT_OK)
1947             {
1948                 if (s->tiff.image_type == T4_IMAGE_TYPE_BILEVEL)
1949                     return T4_IMAGE_FORMAT_NORESSUPPORT;
1950                 if (!(supported_compressions & T4_COMPRESSION_RESCALING))
1951                     return T4_IMAGE_FORMAT_NOSIZESUPPORT;
1952             }
1953             /* TODO */
1954         }
1955         else
1956         {
1957             if ((width_and_res_info[entry].res_code & supported_bilevel_resolutions))
1958             {
1959                 if ((s->tiff.resolution_code & supported_colour_resolutions))
1960                 {
1961                     /* We can use the resolution of the original image */
1962                     s->metadata.resolution_code = width_and_res_info[entry].res_code;
1963                     s->metadata.x_resolution = code_to_x_resolution(s->metadata.resolution_code);
1964                     s->metadata.y_resolution = code_to_y_resolution(s->metadata.resolution_code);
1965                     res = T4_IMAGE_FORMAT_OK;
1966                 }
1967             }
1968         }
1969     }
1970     else
1971     {
1972         /* Can we rework the image to fit? */
1973         /* We can't rework a bilevel image that fits none of the patterns */
1974         if (s->tiff.image_type == T4_IMAGE_TYPE_BILEVEL  ||  s->tiff.image_type == T4_IMAGE_TYPE_COLOUR_BILEVEL)
1975             return T4_IMAGE_FORMAT_NORESSUPPORT;
1976         if (!(supported_compressions & T4_COMPRESSION_RESCALING))
1977             return T4_IMAGE_FORMAT_NOSIZESUPPORT;
1978         /* Any other kind of image might be resizable */
1979         res = T4_IMAGE_FORMAT_OK;
1980         /* TODO: use more sophisticated resizing */
1981         s->metadata.image_width = T4_WIDTH_200_A4;
1982         s->metadata.resolution_code = T4_RESOLUTION_200_200;
1983         s->metadata.x_resolution = code_to_x_resolution(s->metadata.resolution_code);
1984         s->metadata.y_resolution = code_to_y_resolution(s->metadata.resolution_code);
1985     }
1986 
1987     if (res != T4_IMAGE_FORMAT_OK)
1988         return res;
1989 
1990     if (s->metadata.image_type != s->tiff.image_type  ||  s->metadata.image_width != s->tiff.image_width)
1991     {
1992         if (image_translate_init(&s->translator,
1993                                  s->metadata.image_type,
1994                                  s->metadata.image_width,
1995                                  -1,
1996                                  s->tiff.image_type,
1997                                  s->tiff.image_width,
1998                                  s->tiff.image_length,
1999                                  translate_row_read2,
2000                                  s) == NULL)
2001         {
2002             return T4_IMAGE_FORMAT_INCOMPATIBLE;
2003         }
2004         s->metadata.image_length = image_translate_get_output_length(&s->translator);
2005     }
2006 
2007     if (compression != s->metadata.compression)
2008     {
2009         switch (compression)
2010         {
2011         case T4_COMPRESSION_T4_1D:
2012         case T4_COMPRESSION_T4_2D:
2013         case T4_COMPRESSION_T6:
2014             switch (s->metadata.compression)
2015             {
2016             case T4_COMPRESSION_T4_1D:
2017             case T4_COMPRESSION_T4_2D:
2018             case T4_COMPRESSION_T6:
2019                 break;
2020             default:
2021                 release_encoder(s);
2022                 t4_t6_encode_init(&s->encoder.t4_t6, compression, s->metadata.image_width, s->metadata.image_length, s->row_handler, s->row_handler_user_data);
2023                 break;
2024             }
2025             s->metadata.compression = compression;
2026             res = T4_IMAGE_FORMAT_OK;
2027             if (t4_t6_encode_set_encoding(&s->encoder.t4_t6, compression))
2028                 res = -1;
2029             break;
2030         case T4_COMPRESSION_T85:
2031         case T4_COMPRESSION_T85_L0:
2032             switch (s->metadata.compression)
2033             {
2034             case T4_COMPRESSION_T85:
2035             case T4_COMPRESSION_T85_L0:
2036                 break;
2037             default:
2038                 release_encoder(s);
2039                 t85_encode_init(&s->encoder.t85, s->metadata.image_width, s->metadata.image_length, s->row_handler, s->row_handler_user_data);
2040                 break;
2041             }
2042             s->metadata.compression = compression;
2043             res = T4_IMAGE_FORMAT_OK;
2044             break;
2045 #if defined(SPANDSP_SUPPORT_T88)
2046         case T4_COMPRESSION_T88:
2047             switch (s->metadata.compression)
2048             {
2049             case T4_COMPRESSION_T88:
2050                 break;
2051             default:
2052                 t88_encode_init(&s->encoder.t88, s->metadata.image_width, s->metadata.image_length, s->row_handler, s->row_handler_user_data);
2053                 break;
2054             }
2055             s->metadata.compression = compression;
2056             res = T4_IMAGE_FORMAT_OK;
2057             break;
2058 #endif
2059         case T4_COMPRESSION_T42_T81:
2060         case T4_COMPRESSION_SYCC_T81:
2061             switch (s->metadata.compression)
2062             {
2063             case T4_COMPRESSION_T42_T81:
2064             case T4_COMPRESSION_SYCC_T81:
2065                 break;
2066             default:
2067                 release_encoder(s);
2068                 t42_encode_init(&s->encoder.t42, s->metadata.image_width, s->metadata.image_length, s->row_handler, s->row_handler_user_data);
2069                 break;
2070             }
2071             s->metadata.compression = compression;
2072             res = T4_IMAGE_FORMAT_OK;
2073             break;
2074         case T4_COMPRESSION_T43:
2075             switch (s->metadata.compression)
2076             {
2077             case T4_COMPRESSION_T43:
2078                 break;
2079             default:
2080                 release_encoder(s);
2081                 t43_encode_init(&s->encoder.t43, s->metadata.image_width, s->metadata.image_length, s->row_handler, s->row_handler_user_data);
2082                 break;
2083             }
2084             s->metadata.compression = compression;
2085             res = T4_IMAGE_FORMAT_OK;
2086             break;
2087 #if defined(SPANDSP_SUPPORT_T45)
2088         case T4_COMPRESSION_T45:
2089             switch (s->metadata.compression)
2090             {
2091             case T4_COMPRESSION_T45:
2092                 break;
2093             default:
2094                 release_encoder(s);
2095                 t45_encode_init(&s->encoder.t45, s->metadata.image_width, s->metadata.image_length, s->row_handler, s->row_handler_user_data);
2096                 break;
2097             }
2098             s->metadata.compression = compression;
2099             res = T4_IMAGE_FORMAT_OK;
2100             break;
2101 #endif
2102         }
2103     }
2104 
2105     switch (s->metadata.compression)
2106     {
2107     case T4_COMPRESSION_T4_1D:
2108     case T4_COMPRESSION_T4_2D:
2109     case T4_COMPRESSION_T6:
2110         t4_t6_encode_set_max_2d_rows_per_1d_row(&s->encoder.t4_t6, -s->metadata.y_resolution);
2111         break;
2112     }
2113 
2114     set_image_width(s, s->metadata.image_width);
2115     set_image_length(s, s->metadata.image_length);
2116     t4_tx_set_image_type(s, s->metadata.image_type);
2117     return res;
2118 }
2119 /*- End of function --------------------------------------------------------*/
2120 
t4_tx_get_tx_compression(t4_tx_state_t * s)2121 SPAN_DECLARE(int) t4_tx_get_tx_compression(t4_tx_state_t *s)
2122 {
2123     return s->metadata.compression;
2124 }
2125 /*- End of function --------------------------------------------------------*/
2126 
t4_tx_get_tx_image_type(t4_tx_state_t * s)2127 SPAN_DECLARE(int) t4_tx_get_tx_image_type(t4_tx_state_t *s)
2128 {
2129     return s->metadata.image_type;
2130 }
2131 /*- End of function --------------------------------------------------------*/
2132 
t4_tx_get_tx_resolution(t4_tx_state_t * s)2133 SPAN_DECLARE(int) t4_tx_get_tx_resolution(t4_tx_state_t *s)
2134 {
2135     return s->metadata.resolution_code;
2136 }
2137 /*- End of function --------------------------------------------------------*/
2138 
t4_tx_get_tx_x_resolution(t4_tx_state_t * s)2139 SPAN_DECLARE(int) t4_tx_get_tx_x_resolution(t4_tx_state_t *s)
2140 {
2141     return s->metadata.x_resolution;
2142 }
2143 /*- End of function --------------------------------------------------------*/
2144 
t4_tx_get_tx_y_resolution(t4_tx_state_t * s)2145 SPAN_DECLARE(int) t4_tx_get_tx_y_resolution(t4_tx_state_t *s)
2146 {
2147     return s->metadata.y_resolution;
2148 }
2149 /*- End of function --------------------------------------------------------*/
2150 
t4_tx_get_tx_image_width(t4_tx_state_t * s)2151 SPAN_DECLARE(int) t4_tx_get_tx_image_width(t4_tx_state_t *s)
2152 {
2153     return s->metadata.image_width;
2154 }
2155 /*- End of function --------------------------------------------------------*/
2156 
t4_tx_get_tx_image_width_code(t4_tx_state_t * s)2157 SPAN_DECLARE(int) t4_tx_get_tx_image_width_code(t4_tx_state_t *s)
2158 {
2159     return s->metadata.width_code;
2160 }
2161 /*- End of function --------------------------------------------------------*/
2162 
set_image_width(t4_tx_state_t * s,uint32_t image_width)2163 static void set_image_width(t4_tx_state_t *s, uint32_t image_width)
2164 {
2165     s->metadata.image_width = image_width;
2166     switch (s->metadata.compression)
2167     {
2168     case T4_COMPRESSION_T4_1D:
2169     case T4_COMPRESSION_T4_2D:
2170     case T4_COMPRESSION_T6:
2171         t4_t6_encode_set_image_width(&s->encoder.t4_t6, image_width);
2172         break;
2173     case T4_COMPRESSION_T85:
2174     case T4_COMPRESSION_T85_L0:
2175         t85_encode_set_image_width(&s->encoder.t85, image_width);
2176         break;
2177 #if defined(SPANDSP_SUPPORT_T88)
2178     case T4_COMPRESSION_T88:
2179         t88_encode_set_image_width(&s->encoder.t88, image_width);
2180         break;
2181 #endif
2182     case T4_COMPRESSION_T42_T81:
2183     case T4_COMPRESSION_SYCC_T81:
2184         t42_encode_set_image_width(&s->encoder.t42, image_width);
2185         break;
2186     case T4_COMPRESSION_T43:
2187         t43_encode_set_image_width(&s->encoder.t43, image_width);
2188         break;
2189 #if defined(SPANDSP_SUPPORT_T45)
2190     case T4_COMPRESSION_T45:
2191         t45_encode_set_image_width(&s->encoder.t45, image_width);
2192         break;
2193 #endif
2194     }
2195 }
2196 /*- End of function --------------------------------------------------------*/
2197 
set_image_length(t4_tx_state_t * s,uint32_t image_length)2198 static void set_image_length(t4_tx_state_t *s, uint32_t image_length)
2199 {
2200     s->metadata.image_length = image_length;
2201     switch (s->metadata.compression)
2202     {
2203     case T4_COMPRESSION_T4_1D:
2204     case T4_COMPRESSION_T4_2D:
2205     case T4_COMPRESSION_T6:
2206         t4_t6_encode_set_image_length(&s->encoder.t4_t6, image_length);
2207         break;
2208     case T4_COMPRESSION_T85:
2209     case T4_COMPRESSION_T85_L0:
2210         t85_encode_set_image_length(&s->encoder.t85, image_length);
2211         break;
2212 #if defined(SPANDSP_SUPPORT_T88)
2213     case T4_COMPRESSION_T88:
2214         t88_encode_set_image_length(&s->encoder.t88, image_length);
2215         break;
2216 #endif
2217     case T4_COMPRESSION_T42_T81:
2218     case T4_COMPRESSION_SYCC_T81:
2219         t42_encode_set_image_length(&s->encoder.t42, image_length);
2220         break;
2221     case T4_COMPRESSION_T43:
2222         t43_encode_set_image_length(&s->encoder.t43, image_length);
2223         break;
2224 #if defined(SPANDSP_SUPPORT_T45)
2225     case T4_COMPRESSION_T45:
2226         t45_encode_set_image_length(&s->encoder.t45, image_length);
2227         break;
2228 #endif
2229     }
2230 }
2231 /*- End of function --------------------------------------------------------*/
2232 
t4_tx_set_image_type(t4_tx_state_t * s,int image_type)2233 static void t4_tx_set_image_type(t4_tx_state_t *s, int image_type)
2234 {
2235     s->metadata.image_type = image_type;
2236     switch (s->metadata.compression)
2237     {
2238 #if defined(SPANDSP_SUPPORT_T88)
2239     case T4_COMPRESSION_T88:
2240         t88_encode_set_image_type(&s->encoder.t88, image_type);
2241         break;
2242 #endif
2243     case T4_COMPRESSION_T42_T81:
2244     case T4_COMPRESSION_SYCC_T81:
2245         t42_encode_set_image_type(&s->encoder.t42, image_type);
2246         break;
2247     case T4_COMPRESSION_T43:
2248         t43_encode_set_image_type(&s->encoder.t43, image_type);
2249         break;
2250 #if defined(SPANDSP_SUPPORT_T45)
2251     case T4_COMPRESSION_T45:
2252         t45_encode_set_image_type(&s->encoder.t45, image_type);
2253         break;
2254 #endif
2255     }
2256 }
2257 /*- End of function --------------------------------------------------------*/
2258 
t4_tx_set_min_bits_per_row(t4_tx_state_t * s,int bits)2259 SPAN_DECLARE(void) t4_tx_set_min_bits_per_row(t4_tx_state_t *s, int bits)
2260 {
2261     switch (s->metadata.compression)
2262     {
2263     case T4_COMPRESSION_T4_1D:
2264     case T4_COMPRESSION_T4_2D:
2265     case T4_COMPRESSION_T6:
2266         t4_t6_encode_set_min_bits_per_row(&s->encoder.t4_t6, bits);
2267         break;
2268     }
2269 }
2270 /*- End of function --------------------------------------------------------*/
2271 
t4_tx_set_max_2d_rows_per_1d_row(t4_tx_state_t * s,int max)2272 SPAN_DECLARE(void) t4_tx_set_max_2d_rows_per_1d_row(t4_tx_state_t *s, int max)
2273 {
2274     switch (s->metadata.compression)
2275     {
2276     case T4_COMPRESSION_T4_1D:
2277     case T4_COMPRESSION_T4_2D:
2278     case T4_COMPRESSION_T6:
2279         t4_t6_encode_set_max_2d_rows_per_1d_row(&s->encoder.t4_t6, max);
2280         break;
2281     }
2282 }
2283 /*- End of function --------------------------------------------------------*/
2284 
t4_tx_set_header_overlays_image(t4_tx_state_t * s,bool header_overlays_image)2285 SPAN_DECLARE(void) t4_tx_set_header_overlays_image(t4_tx_state_t *s, bool header_overlays_image)
2286 {
2287     s->header_overlays_image = header_overlays_image;
2288 }
2289 /*- End of function --------------------------------------------------------*/
2290 
t4_tx_set_local_ident(t4_tx_state_t * s,const char * ident)2291 SPAN_DECLARE(void) t4_tx_set_local_ident(t4_tx_state_t *s, const char *ident)
2292 {
2293     s->local_ident = (ident  &&  ident[0])  ?  ident  :  NULL;
2294 }
2295 /*- End of function --------------------------------------------------------*/
2296 
t4_tx_set_header_info(t4_tx_state_t * s,const char * info)2297 SPAN_DECLARE(void) t4_tx_set_header_info(t4_tx_state_t *s, const char *info)
2298 {
2299     s->header_info = (info  &&  info[0])  ?  info  :  NULL;
2300 }
2301 /*- End of function --------------------------------------------------------*/
2302 
t4_tx_set_header_tz(t4_tx_state_t * s,struct tz_s * tz)2303 SPAN_DECLARE(void) t4_tx_set_header_tz(t4_tx_state_t *s, struct tz_s *tz)
2304 {
2305     s->tz = tz;
2306 }
2307 /*- End of function --------------------------------------------------------*/
2308 
t4_tx_get_pages_in_file(t4_tx_state_t * s)2309 SPAN_DECLARE(int) t4_tx_get_pages_in_file(t4_tx_state_t *s)
2310 {
2311     int max;
2312 
2313     if (s->tiff.file)
2314         max = get_tiff_total_pages(s);
2315     else
2316         max = 1;
2317     if (max >= 0)
2318         s->tiff.pages_in_file = max;
2319     return max;
2320 }
2321 /*- End of function --------------------------------------------------------*/
2322 
t4_tx_get_current_page_in_file(t4_tx_state_t * s)2323 SPAN_DECLARE(int) t4_tx_get_current_page_in_file(t4_tx_state_t *s)
2324 {
2325     return s->current_page;
2326 }
2327 /*- End of function --------------------------------------------------------*/
2328 
t4_tx_get_transfer_statistics(t4_tx_state_t * s,t4_stats_t * t)2329 SPAN_DECLARE(void) t4_tx_get_transfer_statistics(t4_tx_state_t *s, t4_stats_t *t)
2330 {
2331     memset(t, 0, sizeof(*t));
2332     t->pages_transferred = s->current_page - s->start_page;
2333     t->pages_in_file = s->tiff.pages_in_file;
2334 
2335     t->image_type = s->tiff.image_type;
2336     t->image_width = s->tiff.image_width;
2337     t->image_length = s->tiff.image_length;
2338 
2339     t->image_x_resolution = s->tiff.x_resolution;
2340     t->image_y_resolution = s->tiff.y_resolution;
2341     t->x_resolution = s->metadata.x_resolution;
2342     t->y_resolution = s->metadata.y_resolution;
2343 
2344     t->type = s->metadata.image_type;
2345     t->compression = s->metadata.compression;
2346 
2347     switch (s->metadata.compression)
2348     {
2349     case T4_COMPRESSION_T4_1D:
2350     case T4_COMPRESSION_T4_2D:
2351     case T4_COMPRESSION_T6:
2352         t->width = t4_t6_encode_get_image_width(&s->encoder.t4_t6);
2353         t->length = t4_t6_encode_get_image_length(&s->encoder.t4_t6);
2354         t->line_image_size = t4_t6_encode_get_compressed_image_size(&s->encoder.t4_t6)/8;
2355         break;
2356     case T4_COMPRESSION_T85:
2357     case T4_COMPRESSION_T85_L0:
2358         t->width = t85_encode_get_image_width(&s->encoder.t85);
2359         t->length = t85_encode_get_image_length(&s->encoder.t85);
2360         t->line_image_size = t85_encode_get_compressed_image_size(&s->encoder.t85)/8;
2361         break;
2362 #if defined(SPANDSP_SUPPORT_T88)
2363     case T4_COMPRESSION_T88:
2364         t->width = t88_encode_get_image_width(&s->encoder.t88);
2365         t->length = t88_encode_get_image_length(&s->encoder.t88);
2366         t->line_image_size = t88_encode_get_compressed_image_size(&s->encoder.t88)/8;
2367         break;
2368 #endif
2369     case T4_COMPRESSION_T42_T81:
2370     case T4_COMPRESSION_SYCC_T81:
2371         t->width = t42_encode_get_image_width(&s->encoder.t42);
2372         t->length = t42_encode_get_image_length(&s->encoder.t42);
2373         t->line_image_size = t42_encode_get_compressed_image_size(&s->encoder.t42)/8;
2374         break;
2375     case T4_COMPRESSION_T43:
2376         t->width = t43_encode_get_image_width(&s->encoder.t43);
2377         t->length = t43_encode_get_image_length(&s->encoder.t43);
2378         t->line_image_size = t43_encode_get_compressed_image_size(&s->encoder.t43)/8;
2379         break;
2380 #if defined(SPANDSP_SUPPORT_T45)
2381     case T4_COMPRESSION_T45:
2382         t->width = t45_encode_get_image_width(&s->encoder.t45);
2383         t->length = t45_encode_get_image_length(&s->encoder.t45);
2384         t->line_image_size = t45_encode_get_compressed_image_size(&s->encoder.t45)/8;
2385         break;
2386 #endif
2387     }
2388 }
2389 /*- End of function --------------------------------------------------------*/
2390 
t4_tx_image_complete(t4_tx_state_t * s)2391 SPAN_DECLARE(int) t4_tx_image_complete(t4_tx_state_t *s)
2392 {
2393     if (s->no_encoder.buf_len > 0)
2394     {
2395         if (s->no_encoder.buf_ptr >= s->no_encoder.buf_len)
2396             return SIG_STATUS_END_OF_DATA;
2397         return 0;
2398     }
2399 
2400     switch (s->metadata.compression)
2401     {
2402     case T4_COMPRESSION_T4_1D:
2403     case T4_COMPRESSION_T4_2D:
2404     case T4_COMPRESSION_T6:
2405         return t4_t6_encode_image_complete(&s->encoder.t4_t6);
2406     case T4_COMPRESSION_T85:
2407     case T4_COMPRESSION_T85_L0:
2408         return t85_encode_image_complete(&s->encoder.t85);
2409 #if defined(SPANDSP_SUPPORT_T88)
2410     case T4_COMPRESSION_T88:
2411         return t88_encode_image_complete(&s->encoder.t88);
2412 #endif
2413     case T4_COMPRESSION_T42_T81:
2414     case T4_COMPRESSION_SYCC_T81:
2415         return t42_encode_image_complete(&s->encoder.t42);
2416     case T4_COMPRESSION_T43:
2417         return t43_encode_image_complete(&s->encoder.t43);
2418 #if defined(SPANDSP_SUPPORT_T45)
2419     case T4_COMPRESSION_T45:
2420         return t45_encode_image_complete(&s->encoder.t45);
2421 #endif
2422     }
2423     return SIG_STATUS_END_OF_DATA;
2424 }
2425 /*- End of function --------------------------------------------------------*/
2426 
t4_tx_get_bit(t4_tx_state_t * s)2427 SPAN_DECLARE(int) t4_tx_get_bit(t4_tx_state_t *s)
2428 {
2429     int bit;
2430 
2431     /* We only get bit by bit for T.4 1D and T.4 2-D. */
2432     if (s->no_encoder.buf_len > 0)
2433     {
2434         if (s->no_encoder.buf_ptr >= s->no_encoder.buf_len)
2435             return SIG_STATUS_END_OF_DATA;
2436         bit = (s->no_encoder.buf[s->no_encoder.buf_ptr] >> s->no_encoder.bit) & 1;
2437         if (++s->no_encoder.bit >= 8)
2438         {
2439             s->no_encoder.bit = 0;
2440             s->no_encoder.buf_ptr++;
2441         }
2442         return bit;
2443     }
2444     return t4_t6_encode_get_bit(&s->encoder.t4_t6);
2445 }
2446 /*- End of function --------------------------------------------------------*/
2447 
t4_tx_get(t4_tx_state_t * s,uint8_t buf[],size_t max_len)2448 SPAN_DECLARE(int) t4_tx_get(t4_tx_state_t *s, uint8_t buf[], size_t max_len)
2449 {
2450     if (s->no_encoder.buf_len > 0)
2451     {
2452         if (max_len > (s->no_encoder.buf_len - s->no_encoder.buf_ptr))
2453             max_len = s->no_encoder.buf_len - s->no_encoder.buf_ptr;
2454         memcpy(buf, &s->no_encoder.buf[s->no_encoder.buf_ptr], max_len);
2455         s->no_encoder.buf_ptr += max_len;
2456         return max_len;
2457     }
2458 
2459     if (s->image_get_handler)
2460         return s->image_get_handler((void *) &s->encoder, buf, max_len);
2461 
2462     return 0;
2463 }
2464 /*- End of function --------------------------------------------------------*/
2465 
t4_tx_start_page(t4_tx_state_t * s)2466 SPAN_DECLARE(int) t4_tx_start_page(t4_tx_state_t *s)
2467 {
2468     span_log(&s->logging, SPAN_LOG_FLOW, "Start tx page %d - compression %s\n", s->current_page, t4_compression_to_str(s->metadata.compression));
2469     if (s->current_page > s->stop_page)
2470         return -1;
2471     if (s->tiff.file)
2472     {
2473         if (!TIFFSetDirectory(s->tiff.tiff_file, (tdir_t) s->current_page))
2474             return -1;
2475         get_tiff_directory_info(s);
2476         if (read_tiff_image(s) < 0)
2477             return -1;
2478     }
2479     else
2480     {
2481         s->metadata.image_length = UINT32_MAX;
2482     }
2483 
2484     switch (s->metadata.compression)
2485     {
2486     case T4_COMPRESSION_T4_1D:
2487     case T4_COMPRESSION_T4_2D:
2488     case T4_COMPRESSION_T6:
2489         t4_t6_encode_restart(&s->encoder.t4_t6, s->metadata.image_width, s->metadata.image_length);
2490         s->image_get_handler = (t4_image_get_handler_t) t4_t6_encode_get;
2491         break;
2492     case T4_COMPRESSION_T85:
2493     case T4_COMPRESSION_T85_L0:
2494         t85_encode_restart(&s->encoder.t85, s->metadata.image_width, s->metadata.image_length);
2495         s->image_get_handler = (t4_image_get_handler_t) t85_encode_get;
2496         break;
2497 #if defined(SPANDSP_SUPPORT_T88)
2498     case T4_COMPRESSION_T88:
2499         t88_encode_restart(&s->encoder.t88, s->metadata.image_width, s->metadata.image_length);
2500         s->image_get_handler = (t4_image_get_handler_t) t88_encode_get;
2501         break;
2502 #endif
2503     case T4_COMPRESSION_T42_T81:
2504     case T4_COMPRESSION_SYCC_T81:
2505         t42_encode_restart(&s->encoder.t42, s->metadata.image_width, s->metadata.image_length);
2506         s->image_get_handler = (t4_image_get_handler_t) t42_encode_get;
2507         break;
2508     case T4_COMPRESSION_T43:
2509         t43_encode_restart(&s->encoder.t43, s->metadata.image_width, s->metadata.image_length);
2510         s->image_get_handler = (t4_image_get_handler_t) t43_encode_get;
2511         break;
2512 #if defined(SPANDSP_SUPPORT_T45)
2513     case T4_COMPRESSION_T45:
2514         t45_encode_restart(&s->encoder.t45, s->metadata.image_width, s->metadata.image_length);
2515         s->image_get_handler = (t4_image_get_handler_t) t45_encode_get;
2516         break;
2517 #endif
2518     default:
2519         s->image_get_handler = NULL;
2520         break;
2521     }
2522 
2523     /* If there is a page header, create that first */
2524     //if (s->metadata.image_type == T4_IMAGE_TYPE_BILEVEL  &&  s->header_info  &&  s->header_info[0]  &&  make_header(s) == 0)
2525     if (s->header_info  &&  s->header_info[0]  &&  make_header(s) == 0)
2526     {
2527         s->header_row = 0;
2528         set_row_read_handler(s, header_row_read_handler, (void *) s);
2529     }
2530     else
2531     {
2532         set_row_read_handler(s, s->row_handler, s->row_handler_user_data);
2533     }
2534     return 0;
2535 }
2536 /*- End of function --------------------------------------------------------*/
2537 
t4_tx_restart_page(t4_tx_state_t * s)2538 SPAN_DECLARE(int) t4_tx_restart_page(t4_tx_state_t *s)
2539 {
2540     /* This is currently the same as starting a page, but keep it a separate call,
2541        as the two things might diverge a little in the future. */
2542     return t4_tx_start_page(s);
2543 }
2544 /*- End of function --------------------------------------------------------*/
2545 
t4_tx_end_page(t4_tx_state_t * s)2546 SPAN_DECLARE(int) t4_tx_end_page(t4_tx_state_t *s)
2547 {
2548     s->current_page++;
2549     return 0;
2550 }
2551 /*- End of function --------------------------------------------------------*/
2552 
t4_tx_get_logging_state(t4_tx_state_t * s)2553 SPAN_DECLARE(logging_state_t *) t4_tx_get_logging_state(t4_tx_state_t *s)
2554 {
2555     return &s->logging;
2556 }
2557 /*- End of function --------------------------------------------------------*/
2558 
t4_tx_init(t4_tx_state_t * s,const char * file,int start_page,int stop_page)2559 SPAN_DECLARE(t4_tx_state_t *) t4_tx_init(t4_tx_state_t *s, const char *file, int start_page, int stop_page)
2560 {
2561     int allocated;
2562 
2563     allocated = false;
2564     if (s == NULL)
2565     {
2566         if ((s = (t4_tx_state_t *) span_alloc(sizeof(*s))) == NULL)
2567             return NULL;
2568         allocated = true;
2569     }
2570     memset(s, 0, sizeof(*s));
2571 #if defined(SPANDSP_SUPPORT_TIFF_FX)
2572     TIFF_FX_init();
2573 #endif
2574     span_log_init(&s->logging, SPAN_LOG_NONE, NULL);
2575     span_log_set_protocol(&s->logging, "T.4");
2576 
2577     span_log(&s->logging, SPAN_LOG_FLOW, "Start tx document\n");
2578 
2579     s->current_page =
2580     s->start_page = (start_page >= 0)  ?  start_page  :  0;
2581     s->stop_page = (stop_page >= 0)  ?  stop_page  :  INT_MAX;
2582     s->metadata.compression = T4_COMPRESSION_NONE;
2583 
2584     s->row_handler = tiff_row_read_handler;
2585     s->row_handler_user_data = (void *) s;
2586 
2587     s->row_squashing_ratio = 1;
2588 
2589     if (file)
2590     {
2591         if (open_tiff_input_file(s, file) < 0)
2592         {
2593             if (allocated)
2594                 span_free(s);
2595             return NULL;
2596         }
2597         s->tiff.file = strdup(file);
2598         s->tiff.pages_in_file = -1;
2599         if (!TIFFSetDirectory(s->tiff.tiff_file, (tdir_t) s->current_page)
2600             ||
2601             get_tiff_directory_info(s))
2602         {
2603             tiff_tx_release(s);
2604             if (allocated)
2605                 span_free(s);
2606             return NULL;
2607         }
2608     }
2609     return s;
2610 }
2611 /*- End of function --------------------------------------------------------*/
2612 
t4_tx_release(t4_tx_state_t * s)2613 SPAN_DECLARE(int) t4_tx_release(t4_tx_state_t *s)
2614 {
2615     if (s->tiff.file)
2616         tiff_tx_release(s);
2617     if (s->header_text)
2618     {
2619         span_free(s->header_text);
2620         s->header_text = NULL;
2621     }
2622     if (s->colour_map)
2623     {
2624         span_free(s->colour_map);
2625         s->colour_map = NULL;
2626     }
2627     return release_encoder(s);
2628 }
2629 /*- End of function --------------------------------------------------------*/
2630 
t4_tx_free(t4_tx_state_t * s)2631 SPAN_DECLARE(int) t4_tx_free(t4_tx_state_t *s)
2632 {
2633     int ret;
2634 
2635     ret = t4_tx_release(s);
2636     span_free(s);
2637     return ret;
2638 }
2639 /*- End of function --------------------------------------------------------*/
2640 /*- End of file ------------------------------------------------------------*/
2641