Bug Summary

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