Bug Summary

File:t4_tx.c
Warning:line 1780, column 9
Value stored to 'bytes_per_character' is never read

Annotated Source Code

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