comparison spandsp-0.0.6pre17/src/t4_tx.c @ 4:26cd8f1ef0b1

import spandsp-0.0.6pre17
author Peter Meerwald <pmeerw@cosy.sbg.ac.at>
date Fri, 25 Jun 2010 15:50:58 +0200
parents
children
comparison
equal deleted inserted replaced
3:c6c5a16ce2f2 4:26cd8f1ef0b1
1 //#define T4_STATE_DEBUGGING
2 /*
3 * SpanDSP - a series of DSP components for telephony
4 *
5 * t4_tx.c - ITU T.4 FAX transmit processing
6 *
7 * Written by Steve Underwood <steveu@coppice.org>
8 *
9 * Copyright (C) 2003, 2007 Steve Underwood
10 *
11 * All rights reserved.
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU Lesser General Public License version 2.1,
15 * as published by the Free Software Foundation.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU Lesser General Public License for more details.
21 *
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *
26 * $Id: t4_tx.c,v 1.13.2.9 2009/12/21 17:18:40 steveu Exp $
27 */
28
29 /*
30 * Much of this file is based on the T.4 and T.6 support in libtiff, which requires
31 * the following notice in any derived source code:
32 *
33 * Copyright (c) 1990-1997 Sam Leffler
34 * Copyright (c) 1991-1997 Silicon Graphics, Inc.
35 *
36 * Permission to use, copy, modify, distribute, and sell this software and
37 * its documentation for any purpose is hereby granted without fee, provided
38 * that (i) the above copyright notices and this permission notice appear in
39 * all copies of the software and related documentation, and (ii) the names of
40 * Sam Leffler and Silicon Graphics may not be used in any advertising or
41 * publicity relating to the software without the specific, prior written
42 * permission of Sam Leffler and Silicon Graphics.
43 *
44 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
45 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
46 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
47 *
48 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
49 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
50 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
51 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
52 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
53 * OF THIS SOFTWARE.
54 */
55
56 /*! \file */
57
58 #if defined(HAVE_CONFIG_H)
59 #include "config.h"
60 #endif
61
62 #include <stdlib.h>
63 #include <inttypes.h>
64 #include <limits.h>
65 #include <stdio.h>
66 #include <fcntl.h>
67 #include <unistd.h>
68 #include <time.h>
69 #include <memory.h>
70 #include <string.h>
71 #if defined(HAVE_TGMATH_H)
72 #include <tgmath.h>
73 #endif
74 #if defined(HAVE_MATH_H)
75 #include <math.h>
76 #endif
77 #include "floating_fudge.h"
78 #include <tiffio.h>
79
80 #include "spandsp/telephony.h"
81 #include "spandsp/logging.h"
82 #include "spandsp/bit_operations.h"
83 #include "spandsp/async.h"
84 #include "spandsp/t4_rx.h"
85 #include "spandsp/t4_tx.h"
86 #include "spandsp/version.h"
87
88 #include "spandsp/private/logging.h"
89 #include "spandsp/private/t4_rx.h"
90 #include "spandsp/private/t4_tx.h"
91
92 /*! The number of centimetres in one inch */
93 #define CM_PER_INCH 2.54f
94
95 /*! The number of EOLs to be sent at the end of a T.4 page */
96 #define EOLS_TO_END_T4_TX_PAGE 6
97 /*! The number of EOLs to be sent at the end of a T.6 page */
98 #define EOLS_TO_END_T6_TX_PAGE 2
99
100 #if defined(T4_STATE_DEBUGGING)
101 static void STATE_TRACE(const char *format, ...)
102 {
103 va_list arg_ptr;
104
105 va_start(arg_ptr, format);
106 vprintf(format, arg_ptr);
107 va_end(arg_ptr);
108 }
109 /*- End of function --------------------------------------------------------*/
110 #else
111 #define STATE_TRACE(...) /**/
112 #endif
113
114 /*! T.4 run length table entry */
115 typedef struct
116 {
117 /*! Length of T.4 code, in bits */
118 uint16_t length;
119 /*! T.4 code */
120 uint16_t code;
121 /*! Run length, in bits */
122 int16_t run_length;
123 } t4_run_table_entry_t;
124
125 #include "faxfont.h"
126
127 /* Legitimate runs of zero bits which are the tail end of one code
128 plus the start of the next code do not exceed 10 bits. */
129
130 /*
131 * Note that these tables are ordered such that the index into the table
132 * is known to be either the run length, or (run length / 64) + a fixed
133 * offset.
134 */
135 static const t4_run_table_entry_t t4_white_codes[] =
136 {
137 { 8, 0x00AC, 0}, /* 0011 0101 */
138 { 6, 0x0038, 1}, /* 0001 11 */
139 { 4, 0x000E, 2}, /* 0111 */
140 { 4, 0x0001, 3}, /* 1000 */
141 { 4, 0x000D, 4}, /* 1011 */
142 { 4, 0x0003, 5}, /* 1100 */
143 { 4, 0x0007, 6}, /* 1110 */
144 { 4, 0x000F, 7}, /* 1111 */
145 { 5, 0x0019, 8}, /* 1001 1 */
146 { 5, 0x0005, 9}, /* 1010 0 */
147 { 5, 0x001C, 10}, /* 0011 1 */
148 { 5, 0x0002, 11}, /* 0100 0 */
149 { 6, 0x0004, 12}, /* 0010 00 */
150 { 6, 0x0030, 13}, /* 0000 11 */
151 { 6, 0x000B, 14}, /* 1101 00 */
152 { 6, 0x002B, 15}, /* 1101 01 */
153 { 6, 0x0015, 16}, /* 1010 10 */
154 { 6, 0x0035, 17}, /* 1010 11 */
155 { 7, 0x0072, 18}, /* 0100 111 */
156 { 7, 0x0018, 19}, /* 0001 100 */
157 { 7, 0x0008, 20}, /* 0001 000 */
158 { 7, 0x0074, 21}, /* 0010 111 */
159 { 7, 0x0060, 22}, /* 0000 011 */
160 { 7, 0x0010, 23}, /* 0000 100 */
161 { 7, 0x000A, 24}, /* 0101 000 */
162 { 7, 0x006A, 25}, /* 0101 011 */
163 { 7, 0x0064, 26}, /* 0010 011 */
164 { 7, 0x0012, 27}, /* 0100 100 */
165 { 7, 0x000C, 28}, /* 0011 000 */
166 { 8, 0x0040, 29}, /* 0000 0010 */
167 { 8, 0x00C0, 30}, /* 0000 0011 */
168 { 8, 0x0058, 31}, /* 0001 1010 */
169 { 8, 0x00D8, 32}, /* 0001 1011 */
170 { 8, 0x0048, 33}, /* 0001 0010 */
171 { 8, 0x00C8, 34}, /* 0001 0011 */
172 { 8, 0x0028, 35}, /* 0001 0100 */
173 { 8, 0x00A8, 36}, /* 0001 0101 */
174 { 8, 0x0068, 37}, /* 0001 0110 */
175 { 8, 0x00E8, 38}, /* 0001 0111 */
176 { 8, 0x0014, 39}, /* 0010 1000 */
177 { 8, 0x0094, 40}, /* 0010 1001 */
178 { 8, 0x0054, 41}, /* 0010 1010 */
179 { 8, 0x00D4, 42}, /* 0010 1011 */
180 { 8, 0x0034, 43}, /* 0010 1100 */
181 { 8, 0x00B4, 44}, /* 0010 1101 */
182 { 8, 0x0020, 45}, /* 0000 0100 */
183 { 8, 0x00A0, 46}, /* 0000 0101 */
184 { 8, 0x0050, 47}, /* 0000 1010 */
185 { 8, 0x00D0, 48}, /* 0000 1011 */
186 { 8, 0x004A, 49}, /* 0101 0010 */
187 { 8, 0x00CA, 50}, /* 0101 0011 */
188 { 8, 0x002A, 51}, /* 0101 0100 */
189 { 8, 0x00AA, 52}, /* 0101 0101 */
190 { 8, 0x0024, 53}, /* 0010 0100 */
191 { 8, 0x00A4, 54}, /* 0010 0101 */
192 { 8, 0x001A, 55}, /* 0101 1000 */
193 { 8, 0x009A, 56}, /* 0101 1001 */
194 { 8, 0x005A, 57}, /* 0101 1010 */
195 { 8, 0x00DA, 58}, /* 0101 1011 */
196 { 8, 0x0052, 59}, /* 0100 1010 */
197 { 8, 0x00D2, 60}, /* 0100 1011 */
198 { 8, 0x004C, 61}, /* 0011 0010 */
199 { 8, 0x00CC, 62}, /* 0011 0011 */
200 { 8, 0x002C, 63}, /* 0011 0100 */
201 { 5, 0x001B, 64}, /* 1101 1 */
202 { 5, 0x0009, 128}, /* 1001 0 */
203 { 6, 0x003A, 192}, /* 0101 11 */
204 { 7, 0x0076, 256}, /* 0110 111 */
205 { 8, 0x006C, 320}, /* 0011 0110 */
206 { 8, 0x00EC, 384}, /* 0011 0111 */
207 { 8, 0x0026, 448}, /* 0110 0100 */
208 { 8, 0x00A6, 512}, /* 0110 0101 */
209 { 8, 0x0016, 576}, /* 0110 1000 */
210 { 8, 0x00E6, 640}, /* 0110 0111 */
211 { 9, 0x0066, 704}, /* 0110 0110 0 */
212 { 9, 0x0166, 768}, /* 0110 0110 1 */
213 { 9, 0x0096, 832}, /* 0110 1001 0 */
214 { 9, 0x0196, 896}, /* 0110 1001 1 */
215 { 9, 0x0056, 960}, /* 0110 1010 0 */
216 { 9, 0x0156, 1024}, /* 0110 1010 1 */
217 { 9, 0x00D6, 1088}, /* 0110 1011 0 */
218 { 9, 0x01D6, 1152}, /* 0110 1011 1 */
219 { 9, 0x0036, 1216}, /* 0110 1100 0 */
220 { 9, 0x0136, 1280}, /* 0110 1100 1 */
221 { 9, 0x00B6, 1344}, /* 0110 1101 0 */
222 { 9, 0x01B6, 1408}, /* 0110 1101 1 */
223 { 9, 0x0032, 1472}, /* 0100 1100 0 */
224 { 9, 0x0132, 1536}, /* 0100 1100 1 */
225 { 9, 0x00B2, 1600}, /* 0100 1101 0 */
226 { 6, 0x0006, 1664}, /* 0110 00 */
227 { 9, 0x01B2, 1728}, /* 0100 1101 1 */
228 {11, 0x0080, 1792}, /* 0000 0001 000 */
229 {11, 0x0180, 1856}, /* 0000 0001 100 */
230 {11, 0x0580, 1920}, /* 0000 0001 101 */
231 {12, 0x0480, 1984}, /* 0000 0001 0010 */
232 {12, 0x0C80, 2048}, /* 0000 0001 0011 */
233 {12, 0x0280, 2112}, /* 0000 0001 0100 */
234 {12, 0x0A80, 2176}, /* 0000 0001 0101 */
235 {12, 0x0680, 2240}, /* 0000 0001 0110 */
236 {12, 0x0E80, 2304}, /* 0000 0001 0111 */
237 {12, 0x0380, 2368}, /* 0000 0001 1100 */
238 {12, 0x0B80, 2432}, /* 0000 0001 1101 */
239 {12, 0x0780, 2496}, /* 0000 0001 1110 */
240 {12, 0x0F80, 2560}, /* 0000 0001 1111 */
241 };
242
243 static const t4_run_table_entry_t t4_black_codes[] =
244 {
245 {10, 0x03B0, 0}, /* 0000 1101 11 */
246 { 3, 0x0002, 1}, /* 010 */
247 { 2, 0x0003, 2}, /* 11 */
248 { 2, 0x0001, 3}, /* 10 */
249 { 3, 0x0006, 4}, /* 011 */
250 { 4, 0x000C, 5}, /* 0011 */
251 { 4, 0x0004, 6}, /* 0010 */
252 { 5, 0x0018, 7}, /* 0001 1 */
253 { 6, 0x0028, 8}, /* 0001 01 */
254 { 6, 0x0008, 9}, /* 0001 00 */
255 { 7, 0x0010, 10}, /* 0000 100 */
256 { 7, 0x0050, 11}, /* 0000 101 */
257 { 7, 0x0070, 12}, /* 0000 111 */
258 { 8, 0x0020, 13}, /* 0000 0100 */
259 { 8, 0x00E0, 14}, /* 0000 0111 */
260 { 9, 0x0030, 15}, /* 0000 1100 0 */
261 {10, 0x03A0, 16}, /* 0000 0101 11 */
262 {10, 0x0060, 17}, /* 0000 0110 00 */
263 {10, 0x0040, 18}, /* 0000 0010 00 */
264 {11, 0x0730, 19}, /* 0000 1100 111 */
265 {11, 0x00B0, 20}, /* 0000 1101 000 */
266 {11, 0x01B0, 21}, /* 0000 1101 100 */
267 {11, 0x0760, 22}, /* 0000 0110 111 */
268 {11, 0x00A0, 23}, /* 0000 0101 000 */
269 {11, 0x0740, 24}, /* 0000 0010 111 */
270 {11, 0x00C0, 25}, /* 0000 0011 000 */
271 {12, 0x0530, 26}, /* 0000 1100 1010 */
272 {12, 0x0D30, 27}, /* 0000 1100 1011 */
273 {12, 0x0330, 28}, /* 0000 1100 1100 */
274 {12, 0x0B30, 29}, /* 0000 1100 1101 */
275 {12, 0x0160, 30}, /* 0000 0110 1000 */
276 {12, 0x0960, 31}, /* 0000 0110 1001 */
277 {12, 0x0560, 32}, /* 0000 0110 1010 */
278 {12, 0x0D60, 33}, /* 0000 0110 1011 */
279 {12, 0x04B0, 34}, /* 0000 1101 0010 */
280 {12, 0x0CB0, 35}, /* 0000 1101 0011 */
281 {12, 0x02B0, 36}, /* 0000 1101 0100 */
282 {12, 0x0AB0, 37}, /* 0000 1101 0101 */
283 {12, 0x06B0, 38}, /* 0000 1101 0110 */
284 {12, 0x0EB0, 39}, /* 0000 1101 0111 */
285 {12, 0x0360, 40}, /* 0000 0110 1100 */
286 {12, 0x0B60, 41}, /* 0000 0110 1101 */
287 {12, 0x05B0, 42}, /* 0000 1101 1010 */
288 {12, 0x0DB0, 43}, /* 0000 1101 1011 */
289 {12, 0x02A0, 44}, /* 0000 0101 0100 */
290 {12, 0x0AA0, 45}, /* 0000 0101 0101 */
291 {12, 0x06A0, 46}, /* 0000 0101 0110 */
292 {12, 0x0EA0, 47}, /* 0000 0101 0111 */
293 {12, 0x0260, 48}, /* 0000 0110 0100 */
294 {12, 0x0A60, 49}, /* 0000 0110 0101 */
295 {12, 0x04A0, 50}, /* 0000 0101 0010 */
296 {12, 0x0CA0, 51}, /* 0000 0101 0011 */
297 {12, 0x0240, 52}, /* 0000 0010 0100 */
298 {12, 0x0EC0, 53}, /* 0000 0011 0111 */
299 {12, 0x01C0, 54}, /* 0000 0011 1000 */
300 {12, 0x0E40, 55}, /* 0000 0010 0111 */
301 {12, 0x0140, 56}, /* 0000 0010 1000 */
302 {12, 0x01A0, 57}, /* 0000 0101 1000 */
303 {12, 0x09A0, 58}, /* 0000 0101 1001 */
304 {12, 0x0D40, 59}, /* 0000 0010 1011 */
305 {12, 0x0340, 60}, /* 0000 0010 1100 */
306 {12, 0x05A0, 61}, /* 0000 0101 1010 */
307 {12, 0x0660, 62}, /* 0000 0110 0110 */
308 {12, 0x0E60, 63}, /* 0000 0110 0111 */
309 {10, 0x03C0, 64}, /* 0000 0011 11 */
310 {12, 0x0130, 128}, /* 0000 1100 1000 */
311 {12, 0x0930, 192}, /* 0000 1100 1001 */
312 {12, 0x0DA0, 256}, /* 0000 0101 1011 */
313 {12, 0x0CC0, 320}, /* 0000 0011 0011 */
314 {12, 0x02C0, 384}, /* 0000 0011 0100 */
315 {12, 0x0AC0, 448}, /* 0000 0011 0101 */
316 {13, 0x06C0, 512}, /* 0000 0011 0110 0 */
317 {13, 0x16C0, 576}, /* 0000 0011 0110 1 */
318 {13, 0x0A40, 640}, /* 0000 0010 0101 0 */
319 {13, 0x1A40, 704}, /* 0000 0010 0101 1 */
320 {13, 0x0640, 768}, /* 0000 0010 0110 0 */
321 {13, 0x1640, 832}, /* 0000 0010 0110 1 */
322 {13, 0x09C0, 896}, /* 0000 0011 1001 0 */
323 {13, 0x19C0, 960}, /* 0000 0011 1001 1 */
324 {13, 0x05C0, 1024}, /* 0000 0011 1010 0 */
325 {13, 0x15C0, 1088}, /* 0000 0011 1010 1 */
326 {13, 0x0DC0, 1152}, /* 0000 0011 1011 0 */
327 {13, 0x1DC0, 1216}, /* 0000 0011 1011 1 */
328 {13, 0x0940, 1280}, /* 0000 0010 1001 0 */
329 {13, 0x1940, 1344}, /* 0000 0010 1001 1 */
330 {13, 0x0540, 1408}, /* 0000 0010 1010 0 */
331 {13, 0x1540, 1472}, /* 0000 0010 1010 1 */
332 {13, 0x0B40, 1536}, /* 0000 0010 1101 0 */
333 {13, 0x1B40, 1600}, /* 0000 0010 1101 1 */
334 {13, 0x04C0, 1664}, /* 0000 0011 0010 0 */
335 {13, 0x14C0, 1728}, /* 0000 0011 0010 1 */
336 {11, 0x0080, 1792}, /* 0000 0001 000 */
337 {11, 0x0180, 1856}, /* 0000 0001 100 */
338 {11, 0x0580, 1920}, /* 0000 0001 101 */
339 {12, 0x0480, 1984}, /* 0000 0001 0010 */
340 {12, 0x0C80, 2048}, /* 0000 0001 0011 */
341 {12, 0x0280, 2112}, /* 0000 0001 0100 */
342 {12, 0x0A80, 2176}, /* 0000 0001 0101 */
343 {12, 0x0680, 2240}, /* 0000 0001 0110 */
344 {12, 0x0E80, 2304}, /* 0000 0001 0111 */
345 {12, 0x0380, 2368}, /* 0000 0001 1100 */
346 {12, 0x0B80, 2432}, /* 0000 0001 1101 */
347 {12, 0x0780, 2496}, /* 0000 0001 1110 */
348 {12, 0x0F80, 2560}, /* 0000 0001 1111 */
349 };
350
351 static int encode_row(t4_state_t *s);
352
353 static void make_header(t4_state_t *s, char *header)
354 {
355 time_t now;
356 struct tm tm;
357 static const char *months[] =
358 {
359 "Jan",
360 "Feb",
361 "Mar",
362 "Apr",
363 "May",
364 "Jun",
365 "Jul",
366 "Aug",
367 "Sep",
368 "Oct",
369 "Nov",
370 "Dec"
371 };
372
373 time(&now);
374 tm = *localtime(&now);
375 snprintf(header,
376 132,
377 " %2d-%s-%d %02d:%02d %-50s %-21s p.%d",
378 tm.tm_mday,
379 months[tm.tm_mon],
380 tm.tm_year + 1900,
381 tm.tm_hour,
382 tm.tm_min,
383 s->t4_t6_tx.header_info,
384 s->tiff.local_ident,
385 s->current_page + 1);
386 }
387 /*- End of function --------------------------------------------------------*/
388
389 static int t4_tx_put_fax_header(t4_state_t *s)
390 {
391 int row;
392 int i;
393 int repeats;
394 int pattern;
395 int row_bufptr;
396 char *t;
397 char header[132 + 1];
398
399 /* Modify the resulting image to include a header line, typical of hardware FAX machines */
400 make_header(s, header);
401 switch (s->y_resolution)
402 {
403 case T4_Y_RESOLUTION_1200:
404 repeats = 12;
405 break;
406 case T4_Y_RESOLUTION_800:
407 repeats = 8;
408 break;
409 case T4_Y_RESOLUTION_600:
410 repeats = 6;
411 break;
412 case T4_Y_RESOLUTION_SUPERFINE:
413 repeats = 4;
414 break;
415 case T4_Y_RESOLUTION_300:
416 repeats = 3;
417 break;
418 case T4_Y_RESOLUTION_FINE:
419 repeats = 2;
420 break;
421 default:
422 repeats = 1;
423 break;
424 }
425 for (row = 0; row < 16; row++)
426 {
427 t = header;
428 row_bufptr = 0;
429 for (t = header; *t && row_bufptr <= s->bytes_per_row - 2; t++)
430 {
431 pattern = header_font[(uint8_t) *t][row];
432 s->row_buf[row_bufptr++] = (uint8_t) (pattern >> 8);
433 s->row_buf[row_bufptr++] = (uint8_t) (pattern & 0xFF);
434 }
435 for ( ; row_bufptr < s->bytes_per_row; )
436 s->row_buf[row_bufptr++] = 0;
437 for (i = 0; i < repeats; i++)
438 {
439 if (encode_row(s))
440 return -1;
441 }
442 }
443 return 0;
444 }
445 /*- End of function --------------------------------------------------------*/
446
447 static int test_resolution(int res_unit, float actual, float expected)
448 {
449 if (res_unit == RESUNIT_INCH)
450 actual *= 1.0f/CM_PER_INCH;
451 return (expected*0.95f <= actual && actual <= expected*1.05f);
452 }
453 /*- End of function --------------------------------------------------------*/
454
455 static int get_tiff_directory_info(t4_state_t *s)
456 {
457 static const struct
458 {
459 float resolution;
460 int code;
461 } x_res_table[] =
462 {
463 { 102.0f/CM_PER_INCH, T4_X_RESOLUTION_R4},
464 { 204.0f/CM_PER_INCH, T4_X_RESOLUTION_R8},
465 { 300.0f/CM_PER_INCH, T4_X_RESOLUTION_300},
466 { 408.0f/CM_PER_INCH, T4_X_RESOLUTION_R16},
467 { 600.0f/CM_PER_INCH, T4_X_RESOLUTION_600},
468 { 800.0f/CM_PER_INCH, T4_X_RESOLUTION_800},
469 {1200.0f/CM_PER_INCH, T4_X_RESOLUTION_1200},
470 { -1.00f, -1}
471 };
472 static const struct
473 {
474 float resolution;
475 int code;
476 int max_rows_to_next_1d_row;
477 } y_res_table[] =
478 {
479 { 38.50f, T4_Y_RESOLUTION_STANDARD, 2},
480 { 77.00f, T4_Y_RESOLUTION_FINE, 4},
481 { 300.0f/CM_PER_INCH, T4_Y_RESOLUTION_300, 6},
482 { 154.00f, T4_Y_RESOLUTION_SUPERFINE, 8},
483 { 600.0f/CM_PER_INCH, T4_Y_RESOLUTION_600, 12},
484 { 800.0f/CM_PER_INCH, T4_Y_RESOLUTION_800, 16},
485 {1200.0f/CM_PER_INCH, T4_Y_RESOLUTION_1200, 24},
486 { -1.00f, -1, -1}
487 };
488 uint16_t res_unit;
489 uint16_t parm16;
490 uint32_t parm32;
491 float x_resolution;
492 float y_resolution;
493 int i;
494 t4_tiff_state_t *t;
495
496 t = &s->tiff;
497 parm16 = 0;
498 TIFFGetField(t->tiff_file, TIFFTAG_BITSPERSAMPLE, &parm16);
499 if (parm16 != 1)
500 return -1;
501 TIFFGetField(t->tiff_file, TIFFTAG_SAMPLESPERPIXEL, &parm16);
502 if (parm16 != 1)
503 return -1;
504 parm32 = 0;
505 TIFFGetField(t->tiff_file, TIFFTAG_IMAGEWIDTH, &parm32);
506 s->image_width = parm32;
507 s->bytes_per_row = (s->image_width + 7)/8;
508 parm32 = 0;
509 TIFFGetField(t->tiff_file, TIFFTAG_IMAGELENGTH, &parm32);
510 s->image_length = parm32;
511 x_resolution = 0.0f;
512 TIFFGetField(t->tiff_file, TIFFTAG_XRESOLUTION, &x_resolution);
513 y_resolution = 0.0f;
514 TIFFGetField(t->tiff_file, TIFFTAG_YRESOLUTION, &y_resolution);
515 res_unit = RESUNIT_INCH;
516 TIFFGetField(t->tiff_file, TIFFTAG_RESOLUTIONUNIT, &res_unit);
517 t->photo_metric = PHOTOMETRIC_MINISWHITE;
518 TIFFGetField(t->tiff_file, TIFFTAG_PHOTOMETRIC, &t->photo_metric);
519 if (t->photo_metric != PHOTOMETRIC_MINISWHITE)
520 span_log(&s->logging, SPAN_LOG_FLOW, "%s: Photometric needs swapping.\n", t->file);
521 t->fill_order = FILLORDER_LSB2MSB;
522 #if 0
523 TIFFGetField(t->tiff_file, TIFFTAG_FILLORDER, &t->fill_order);
524 if (t->fill_order != FILLORDER_LSB2MSB)
525 span_log(&s->logging, SPAN_LOG_FLOW, "%s: Fill order needs swapping.\n", t->file);
526 #endif
527
528 /* Allow a little range for the X resolution in centimeters. The spec doesn't pin down the
529 precise value. The other value should be exact. */
530 /* Treat everything we can't match as R8. Most FAXes are this resolution anyway. */
531 s->x_resolution = T4_X_RESOLUTION_R8;
532 for (i = 0; x_res_table[i].code > 0; i++)
533 {
534 if (test_resolution(res_unit, x_resolution, x_res_table[i].resolution))
535 {
536 s->x_resolution = x_res_table[i].code;
537 break;
538 }
539 }
540
541 s->y_resolution = T4_Y_RESOLUTION_STANDARD;
542 s->t4_t6_tx.max_rows_to_next_1d_row = 2;
543 for (i = 0; y_res_table[i].code > 0; i++)
544 {
545 if (test_resolution(res_unit, y_resolution, y_res_table[i].resolution))
546 {
547 s->y_resolution = y_res_table[i].code;
548 s->t4_t6_tx.max_rows_to_next_1d_row = y_res_table[i].max_rows_to_next_1d_row;
549 break;
550 }
551 }
552
553 return 0;
554 }
555 /*- End of function --------------------------------------------------------*/
556
557 static int test_tiff_directory_info(t4_state_t *s)
558 {
559 static const struct
560 {
561 float resolution;
562 int code;
563 } x_res_table[] =
564 {
565 { 102.0f/CM_PER_INCH, T4_X_RESOLUTION_R4},
566 { 204.0f/CM_PER_INCH, T4_X_RESOLUTION_R8},
567 { 300.0f/CM_PER_INCH, T4_X_RESOLUTION_300},
568 { 408.0f/CM_PER_INCH, T4_X_RESOLUTION_R16},
569 { 600.0f/CM_PER_INCH, T4_X_RESOLUTION_600},
570 { 800.0f/CM_PER_INCH, T4_X_RESOLUTION_800},
571 {1200.0f/CM_PER_INCH, T4_X_RESOLUTION_1200},
572 { -1.00f, -1}
573 };
574 static const struct
575 {
576 float resolution;
577 int code;
578 int max_rows_to_next_1d_row;
579 } y_res_table[] =
580 {
581 { 38.50f, T4_Y_RESOLUTION_STANDARD, 2},
582 { 77.00f, T4_Y_RESOLUTION_FINE, 4},
583 { 300.0f/CM_PER_INCH, T4_Y_RESOLUTION_300, 6},
584 { 154.00f, T4_Y_RESOLUTION_SUPERFINE, 8},
585 { 600.0f/CM_PER_INCH, T4_Y_RESOLUTION_600, 12},
586 { 800.0f/CM_PER_INCH, T4_Y_RESOLUTION_800, 16},
587 {1200.0f/CM_PER_INCH, T4_Y_RESOLUTION_1200, 24},
588 { -1.00f, -1, -1}
589 };
590 uint16_t res_unit;
591 uint16_t parm16;
592 uint32_t parm32;
593 float x_resolution;
594 float y_resolution;
595 int i;
596 t4_tiff_state_t *t;
597
598 t = &s->tiff;
599 parm16 = 0;
600 TIFFGetField(t->tiff_file, TIFFTAG_BITSPERSAMPLE, &parm16);
601 if (parm16 != 1)
602 return -1;
603 parm32 = 0;
604 TIFFGetField(t->tiff_file, TIFFTAG_IMAGEWIDTH, &parm32);
605 if (s->image_width != (int) parm32)
606 return 1;
607 x_resolution = 0.0f;
608 TIFFGetField(t->tiff_file, TIFFTAG_XRESOLUTION, &x_resolution);
609 y_resolution = 0.0f;
610 TIFFGetField(t->tiff_file, TIFFTAG_YRESOLUTION, &y_resolution);
611 res_unit = RESUNIT_INCH;
612 TIFFGetField(t->tiff_file, TIFFTAG_RESOLUTIONUNIT, &res_unit);
613
614 /* Allow a little range for the X resolution in centimeters. The spec doesn't pin down the
615 precise value. The other value should be exact. */
616 /* Treat everything we can't match as R8. Most FAXes are this resolution anyway. */
617 for (i = 0; x_res_table[i].code > 0; i++)
618 {
619 if (test_resolution(res_unit, x_resolution, x_res_table[i].resolution))
620 break;
621 }
622 if (s->x_resolution != x_res_table[i].code)
623 return 1;
624 for (i = 0; y_res_table[i].code > 0; i++)
625 {
626 if (test_resolution(res_unit, y_resolution, y_res_table[i].resolution))
627 break;
628 }
629 if (s->y_resolution != y_res_table[i].code)
630 return 1;
631 return 0;
632 }
633 /*- End of function --------------------------------------------------------*/
634
635 static int get_tiff_total_pages(t4_state_t *s)
636 {
637 int max;
638
639 /* Each page *should* contain the total number of pages, but can this be
640 trusted? Some files say 0. Actually searching for the last page is
641 more reliable. */
642 max = 0;
643 while (TIFFSetDirectory(s->tiff.tiff_file, (tdir_t) max))
644 max++;
645 /* Back to the previous page */
646 if (!TIFFSetDirectory(s->tiff.tiff_file, (tdir_t) s->current_page))
647 return -1;
648 return max;
649 }
650 /*- End of function --------------------------------------------------------*/
651
652 static int open_tiff_input_file(t4_state_t *s, const char *file)
653 {
654 if ((s->tiff.tiff_file = TIFFOpen(file, "r")) == NULL)
655 return -1;
656 return 0;
657 }
658 /*- End of function --------------------------------------------------------*/
659
660 static int read_tiff_image(t4_state_t *s)
661 {
662 int row;
663 int image_length;
664 int i;
665
666 image_length = 0;
667 TIFFGetField(s->tiff.tiff_file, TIFFTAG_IMAGELENGTH, &image_length);
668 for (row = 0; row < image_length; row++)
669 {
670 if (TIFFReadScanline(s->tiff.tiff_file, s->row_buf, row, 0) <= 0)
671 {
672 span_log(&s->logging, SPAN_LOG_WARNING, "%s: Read error at row %d.\n", s->tiff.file, row);
673 break;
674 }
675 if (s->tiff.photo_metric != PHOTOMETRIC_MINISWHITE)
676 {
677 for (i = 0; i < s->bytes_per_row; i++)
678 s->row_buf[i] = ~s->row_buf[i];
679 }
680 if (s->tiff.fill_order != FILLORDER_LSB2MSB)
681 bit_reverse(s->row_buf, s->row_buf, s->bytes_per_row);
682 if (encode_row(s))
683 return -1;
684 }
685 return image_length;
686 }
687 /*- End of function --------------------------------------------------------*/
688
689 static int close_tiff_input_file(t4_state_t *s)
690 {
691 TIFFClose(s->tiff.tiff_file);
692 s->tiff.tiff_file = NULL;
693 if (s->tiff.file)
694 free((char *) s->tiff.file);
695 s->tiff.file = NULL;
696 return 0;
697 }
698 /*- End of function --------------------------------------------------------*/
699
700 static void update_row_bit_info(t4_state_t *s)
701 {
702 if (s->row_bits > s->max_row_bits)
703 s->max_row_bits = s->row_bits;
704 if (s->row_bits < s->min_row_bits)
705 s->min_row_bits = s->row_bits;
706 s->row_bits = 0;
707 }
708 /*- End of function --------------------------------------------------------*/
709
710 static int free_buffers(t4_state_t *s)
711 {
712 if (s->image_buffer)
713 {
714 free(s->image_buffer);
715 s->image_buffer = NULL;
716 s->image_buffer_size = 0;
717 }
718 if (s->cur_runs)
719 {
720 free(s->cur_runs);
721 s->cur_runs = NULL;
722 }
723 if (s->ref_runs)
724 {
725 free(s->ref_runs);
726 s->ref_runs = NULL;
727 }
728 if (s->row_buf)
729 {
730 free(s->row_buf);
731 s->row_buf = NULL;
732 }
733 return 0;
734 }
735 /*- End of function --------------------------------------------------------*/
736
737 static int row_to_run_lengths(uint32_t list[], const uint8_t row[], int width)
738 {
739 uint32_t flip;
740 uint32_t x;
741 int span;
742 int entry;
743 int frag;
744 int rem;
745 int limit;
746 int i;
747 int pos;
748
749 /* Deal with whole words first. We know we are starting on a word boundary. */
750 entry = 0;
751 flip = 0;
752 limit = (width >> 3) & ~3;
753 span = 0;
754 pos = 0;
755 for (i = 0; i < limit; i += sizeof(uint32_t))
756 {
757 x = *((uint32_t *) &row[i]);
758 if (x != flip)
759 {
760 x = ((uint32_t) row[i] << 24) | ((uint32_t) row[i + 1] << 16) | ((uint32_t) row[i + 2] << 8) | ((uint32_t) row[i + 3]);
761 /* We know we are going to find at least one transition. */
762 frag = 31 - top_bit(x ^ flip);
763 pos += ((i << 3) - span + frag);
764 list[entry++] = pos;
765 x <<= frag;
766 flip ^= 0xFFFFFFFF;
767 rem = 32 - frag;
768 /* Now see if there are any more */
769 while ((frag = 31 - top_bit(x ^ flip)) < rem)
770 {
771 pos += frag;
772 list[entry++] = pos;
773 x <<= frag;
774 flip ^= 0xFFFFFFFF;
775 rem -= frag;
776 }
777 /* Save the remainder of the word */
778 span = (i << 3) + 32 - rem;
779 }
780 }
781 /* Now deal with some whole bytes, if there are any left. */
782 limit = width >> 3;
783 flip &= 0xFF000000;
784 if (i < limit)
785 {
786 for ( ; i < limit; i++)
787 {
788 x = (uint32_t) row[i] << 24;
789 if (x != flip)
790 {
791 /* We know we are going to find at least one transition. */
792 frag = 31 - top_bit(x ^ flip);
793 pos += ((i << 3) - span + frag);
794 list[entry++] = pos;
795 x <<= frag;
796 flip ^= 0xFF000000;
797 rem = 8 - frag;
798 /* Now see if there are any more */
799 while ((frag = 31 - top_bit(x ^ flip)) < rem)
800 {
801 pos += frag;
802 list[entry++] = pos;
803 x <<= frag;
804 flip ^= 0xFF000000;
805 rem -= frag;
806 }
807 /* Save the remainder of the word */
808 span = (i << 3) + 8 - rem;
809 }
810 }
811 }
812 /* Deal with any left over fractional byte. */
813 span = (i << 3) - span;
814 if ((rem = width & 7))
815 {
816 x = row[i];
817 x <<= 24;
818 do
819 {
820 frag = 31 - top_bit(x ^ flip);
821 if (frag > rem)
822 frag = rem;
823 pos += (span + frag);
824 list[entry++] = pos;
825 x <<= frag;
826 span = 0;
827 flip ^= 0xFF000000;
828 rem -= frag;
829 }
830 while (rem > 0);
831 }
832 else
833 {
834 if (span)
835 {
836 pos += span;
837 list[entry++] = pos;
838 }
839 }
840 return entry;
841 }
842 /*- End of function --------------------------------------------------------*/
843
844 static __inline__ int put_encoded_bits(t4_state_t *s, uint32_t bits, int length)
845 {
846 uint8_t *t;
847
848 /* We might be called with a large length value, to spew out a mass of zero bits for
849 minimum row length padding. */
850 s->tx_bitstream |= (bits << s->tx_bits);
851 s->tx_bits += length;
852 s->row_bits += length;
853 if ((s->image_size + (s->tx_bits + 7)/8) >= s->image_buffer_size)
854 {
855 if ((t = realloc(s->image_buffer, s->image_buffer_size + 100*s->bytes_per_row)) == NULL)
856 return -1;
857 s->image_buffer = t;
858 s->image_buffer_size += 100*s->bytes_per_row;
859 }
860 while (s->tx_bits >= 8)
861 {
862 s->image_buffer[s->image_size++] = (uint8_t) (s->tx_bitstream & 0xFF);
863 s->tx_bitstream >>= 8;
864 s->tx_bits -= 8;
865 }
866 return 0;
867 }
868 /*- End of function --------------------------------------------------------*/
869
870 /*
871 * Write the sequence of codes that describes
872 * the specified span of zero's or one's. The
873 * appropriate table that holds the make-up and
874 * terminating codes is supplied.
875 */
876 static __inline__ int put_1d_span(t4_state_t *s, int32_t span, const t4_run_table_entry_t *tab)
877 {
878 const t4_run_table_entry_t *te;
879
880 te = &tab[63 + (2560 >> 6)];
881 while (span >= 2560 + 64)
882 {
883 if (put_encoded_bits(s, te->code, te->length))
884 return -1;
885 span -= te->run_length;
886 }
887 te = &tab[63 + (span >> 6)];
888 if (span >= 64)
889 {
890 if (put_encoded_bits(s, te->code, te->length))
891 return -1;
892 span -= te->run_length;
893 }
894 if (put_encoded_bits(s, tab[span].code, tab[span].length))
895 return -1;
896 return 0;
897 }
898 /*- End of function --------------------------------------------------------*/
899
900 #define pixel_is_black(x,bit) (((x)[(bit) >> 3] << ((bit) & 7)) & 0x80)
901
902 /*
903 * Write an EOL code to the output stream. We also handle writing the tag
904 * bit for the next scanline when doing 2D encoding.
905 */
906 static void encode_eol(t4_state_t *s)
907 {
908 uint32_t code;
909 int length;
910
911 if (s->line_encoding == T4_COMPRESSION_ITU_T4_2D)
912 {
913 code = 0x0800 | ((!s->row_is_2d) << 12);
914 length = 13;
915 }
916 else
917 {
918 /* T.4 1D EOL, or T.6 EOFB */
919 code = 0x800;
920 length = 12;
921 }
922 if (s->row_bits)
923 {
924 /* We may need to pad the row to a minimum length, unless we are in T.6 mode.
925 In T.6 we only come here at the end of the page to add the EOFB marker, which
926 is like two 1D EOLs. */
927 if (s->line_encoding != T4_COMPRESSION_ITU_T6)
928 {
929 if (s->row_bits + length < s->t4_t6_tx.min_bits_per_row)
930 put_encoded_bits(s, 0, s->t4_t6_tx.min_bits_per_row - (s->row_bits + length));
931 }
932 put_encoded_bits(s, code, length);
933 update_row_bit_info(s);
934 }
935 else
936 {
937 /* We don't pad zero length rows. They are the consecutive EOLs which end a page. */
938 put_encoded_bits(s, code, length);
939 /* Don't do the full update row bit info, or the minimum suddenly drops to the
940 length of an EOL. Just clear the row bits, so we treat the next EOL as an
941 end of page EOL, with no padding. */
942 s->row_bits = 0;
943 }
944 }
945 /*- End of function --------------------------------------------------------*/
946
947 /*
948 * 2D-encode a row of pixels. Consult ITU specification T.4 for the algorithm.
949 */
950 static void encode_2d_row(t4_state_t *s)
951 {
952 static const t4_run_table_entry_t codes[] =
953 {
954 { 7, 0x60, 0 }, /* VR3 0000 011 */
955 { 6, 0x30, 0 }, /* VR2 0000 11 */
956 { 3, 0x06, 0 }, /* VR1 011 */
957 { 1, 0x01, 0 }, /* V0 1 */
958 { 3, 0x02, 0 }, /* VL1 010 */
959 { 6, 0x10, 0 }, /* VL2 0000 10 */
960 { 7, 0x20, 0 }, /* VL3 0000 010 */
961 { 3, 0x04, 0 }, /* horizontal 001 */
962 { 4, 0x08, 0 } /* pass 0001 */
963 };
964
965 /* The reference or starting changing element on the coding line. At the start of the coding
966 line, a0 is set on an imaginary white changing element situated just before the first element
967 on the line. During the coding of the coding line, the position of a0 is defined by the
968 previous coding mode. (See T.4/4.2.1.3.2.) */
969 int a0;
970 /* The next changing element to the right of a0 on the coding line. */
971 int a1;
972 /* The next changing element to the right of a1 on the coding line. */
973 int a2;
974 /* The first changing element on the reference line to the right of a0 and of opposite colour to a0. */
975 int b1;
976 /* The next changing element to the right of b1 on the reference line. */
977 int b2;
978 int diff;
979 int a_cursor;
980 int b_cursor;
981 int cur_steps;
982 uint32_t *p;
983
984 /*
985 b1 b2
986 XX XX XX XX XX -- -- -- -- -- XX XX XX -- -- -- -- --
987 XX XX XX -- -- -- -- -- XX XX XX XX XX XX -- -- -- --
988 a0 a1 a2
989
990
991 a) Pass mode
992 This mode is identified when the position of b2 lies to the left of a1. When this mode
993 has been coded, a0 is set on the element of the coding line below b2 in preparation for
994 the next coding (i.e. on a0').
995
996 b1 b2
997 XX XX XX XX -- -- XX XX XX -- -- -- -- --
998 XX XX -- -- -- -- -- -- -- -- -- -- XX XX
999 a0 a0' a1
1000 Pass mode
1001
1002
1003 However, the state where b2 occurs just above a1, as shown in the figure below, is not
1004 considered as a pass mode.
1005
1006 b1 b2
1007 XX XX XX XX -- -- XX XX XX -- -- -- -- --
1008 XX XX -- -- -- -- -- -- -- XX XX XX XX XX
1009 a0 a1
1010 Not pass mode
1011
1012
1013 b) Vertical mode
1014 When this mode is identified, the position of a1 is coded relative to the position of b1.
1015 The relative distance a1b1 can take on one of seven values V(0), VR(1), VR(2), VR(3),
1016 VL(1), VL(2) and VL(3), each of which is represented by a separate code word. The
1017 subscripts R and L indicate that a1 is to the right or left respectively of b1, and the
1018 number in brackets indicates the value of the distance a1b1. After vertical mode coding
1019 has occurred, the position of a0 is set on a1 (see figure below).
1020
1021 c) Horizontal mode
1022 When this mode is identified, both the run-lengths a0a1 and a1a2 are coded using the code
1023 words H + M(a0a1) + M(a1a2). H is the flag code word 001 taken from the two-dimensional
1024 code table. M(a0a1) and M(a1a2) are code words which represent the length and "colour"
1025 of the runs a0a1 and a1a2 respectively and are taken from the appropriate white or black
1026 one-dimensional code tables. After a horizontal mode coding, the position of a0 is set on
1027 a2 (see figure below).
1028
1029 Vertical
1030 <a1 b1>
1031 b1 b2
1032 -- XX XX XX XX XX -- -- -- -- -- -- -- -- XX XX XX XX -- -- --
1033 -- -- -- -- -- -- -- -- -- -- -- -- XX XX XX XX XX XX XX -- --
1034 a0 a1 a2
1035 <-------- a0a1 --------><-------- a1a2 ------------>
1036 Horizontal mode
1037 Vertical and horizontal modes
1038 */
1039 /* The following implements the 2-D encoding section of the flow chart in Figure7/T.4 */
1040 cur_steps = row_to_run_lengths(s->cur_runs, s->row_buf, s->image_width);
1041 /* Stretch the row a little, so when we step by 2 we are guaranteed to
1042 hit an entry showing the row length */
1043 s->cur_runs[cur_steps] =
1044 s->cur_runs[cur_steps + 1] =
1045 s->cur_runs[cur_steps + 2] = s->cur_runs[cur_steps - 1];
1046
1047 a0 = 0;
1048 a1 = s->cur_runs[0];
1049 b1 = s->ref_runs[0];
1050 a_cursor = 0;
1051 b_cursor = 0;
1052 for (;;)
1053 {
1054 b2 = s->ref_runs[b_cursor + 1];
1055 if (b2 >= a1)
1056 {
1057 diff = b1 - a1;
1058 if (abs(diff) <= 3)
1059 {
1060 /* Vertical mode coding */
1061 put_encoded_bits(s, codes[diff + 3].code, codes[diff + 3].length);
1062 a0 = a1;
1063 a_cursor++;
1064 }
1065 else
1066 {
1067 /* Horizontal mode coding */
1068 a2 = s->cur_runs[a_cursor + 1];
1069 put_encoded_bits(s, codes[7].code, codes[7].length);
1070 if (a0 + a1 == 0 || pixel_is_black(s->row_buf, a0) == 0)
1071 {
1072 put_1d_span(s, a1 - a0, t4_white_codes);
1073 put_1d_span(s, a2 - a1, t4_black_codes);
1074 }
1075 else
1076 {
1077 put_1d_span(s, a1 - a0, t4_black_codes);
1078 put_1d_span(s, a2 - a1, t4_white_codes);
1079 }
1080 a0 = a2;
1081 a_cursor += 2;
1082 }
1083 if (a0 >= s->image_width)
1084 break;
1085 if (a_cursor >= cur_steps)
1086 a_cursor = cur_steps - 1;
1087 a1 = s->cur_runs[a_cursor];
1088 }
1089 else
1090 {
1091 /* Pass mode coding */
1092 put_encoded_bits(s, codes[8].code, codes[8].length);
1093 /* We now set a0 to somewhere in the middle of its current run,
1094 but we know are aren't moving beyond that run. */
1095 a0 = b2;
1096 if (a0 >= s->image_width)
1097 break;
1098 }
1099 /* We need to hunt for the correct position in the reference row, as the
1100 runs there have no particular alignment with the runs in the current
1101 row. */
1102 if (pixel_is_black(s->row_buf, a0))
1103 b_cursor |= 1;
1104 else
1105 b_cursor &= ~1;
1106 if (a0 < (int) s->ref_runs[b_cursor])
1107 {
1108 for ( ; b_cursor >= 0; b_cursor -= 2)
1109 {
1110 if (a0 >= (int) s->ref_runs[b_cursor])
1111 break;
1112 }
1113 b_cursor += 2;
1114 }
1115 else
1116 {
1117 for ( ; b_cursor < s->t4_t6_tx.ref_steps; b_cursor += 2)
1118 {
1119 if (a0 < (int) s->ref_runs[b_cursor])
1120 break;
1121 }
1122 if (b_cursor >= s->t4_t6_tx.ref_steps)
1123 b_cursor = s->t4_t6_tx.ref_steps - 1;
1124 }
1125 b1 = s->ref_runs[b_cursor];
1126 }
1127 /* Swap the buffers */
1128 s->t4_t6_tx.ref_steps = cur_steps;
1129 p = s->cur_runs;
1130 s->cur_runs = s->ref_runs;
1131 s->ref_runs = p;
1132 }
1133 /*- End of function --------------------------------------------------------*/
1134
1135 /*
1136 * 1D-encode a row of pixels. The encoding is a sequence of all-white or
1137 * all-black spans of pixels encoded with Huffman codes.
1138 */
1139 static void encode_1d_row(t4_state_t *s)
1140 {
1141 int i;
1142
1143 /* Do our work in the reference row buffer, and it is already in place if
1144 we need a reference row for a following 2D encoded row. */
1145 s->t4_t6_tx.ref_steps = row_to_run_lengths(s->ref_runs, s->row_buf, s->image_width);
1146 put_1d_span(s, s->ref_runs[0], t4_white_codes);
1147 for (i = 1; i < s->t4_t6_tx.ref_steps; i++)
1148 put_1d_span(s, s->ref_runs[i] - s->ref_runs[i - 1], (i & 1) ? t4_black_codes : t4_white_codes);
1149 /* Stretch the row a little, so when we step by 2 we are guaranteed to
1150 hit an entry showing the row length */
1151 s->ref_runs[s->t4_t6_tx.ref_steps] =
1152 s->ref_runs[s->t4_t6_tx.ref_steps + 1] =
1153 s->ref_runs[s->t4_t6_tx.ref_steps + 2] = s->ref_runs[s->t4_t6_tx.ref_steps - 1];
1154 }
1155 /*- End of function --------------------------------------------------------*/
1156
1157 static int encode_row(t4_state_t *s)
1158 {
1159 switch (s->line_encoding)
1160 {
1161 case T4_COMPRESSION_ITU_T6:
1162 /* T.6 compression is a trivial step up from T.4 2D, so we just
1163 throw it in here. T.6 is only used with error correction,
1164 so it does not need independantly compressed (i.e. 1D) lines
1165 to recover from data errors. It doesn't need EOLs, either. */
1166 if (s->row_bits)
1167 update_row_bit_info(s);
1168 encode_2d_row(s);
1169 break;
1170 case T4_COMPRESSION_ITU_T4_2D:
1171 encode_eol(s);
1172 if (s->row_is_2d)
1173 {
1174 encode_2d_row(s);
1175 s->t4_t6_tx.rows_to_next_1d_row--;
1176 }
1177 else
1178 {
1179 encode_1d_row(s);
1180 s->row_is_2d = TRUE;
1181 }
1182 if (s->t4_t6_tx.rows_to_next_1d_row <= 0)
1183 {
1184 /* Insert a row of 1D encoding */
1185 s->row_is_2d = FALSE;
1186 s->t4_t6_tx.rows_to_next_1d_row = s->t4_t6_tx.max_rows_to_next_1d_row - 1;
1187 }
1188 break;
1189 default:
1190 case T4_COMPRESSION_ITU_T4_1D:
1191 encode_eol(s);
1192 encode_1d_row(s);
1193 break;
1194 }
1195 s->row++;
1196 return 0;
1197 }
1198 /*- End of function --------------------------------------------------------*/
1199
1200 SPAN_DECLARE(int) t4_tx_set_row_read_handler(t4_state_t *s, t4_row_read_handler_t handler, void *user_data)
1201 {
1202 s->t4_t6_tx.row_read_handler = handler;
1203 s->t4_t6_tx.row_read_user_data = user_data;
1204 return 0;
1205 }
1206 /*- End of function --------------------------------------------------------*/
1207
1208 SPAN_DECLARE(t4_state_t *) t4_tx_init(t4_state_t *s, const char *file, int start_page, int stop_page)
1209 {
1210 int run_space;
1211
1212 if (s == NULL)
1213 {
1214 if ((s = (t4_state_t *) malloc(sizeof(*s))) == NULL)
1215 return NULL;
1216 }
1217 memset(s, 0, sizeof(*s));
1218 span_log_init(&s->logging, SPAN_LOG_NONE, NULL);
1219 span_log_set_protocol(&s->logging, "T.4");
1220 s->rx = FALSE;
1221
1222 span_log(&s->logging, SPAN_LOG_FLOW, "Start tx document\n");
1223
1224 if (open_tiff_input_file(s, file) < 0)
1225 return NULL;
1226 s->tiff.file = strdup(file);
1227 s->current_page =
1228 s->tiff.start_page = (start_page >= 0) ? start_page : 0;
1229 s->tiff.stop_page = (stop_page >= 0) ? stop_page : INT_MAX;
1230
1231 if (!TIFFSetDirectory(s->tiff.tiff_file, (tdir_t) s->current_page))
1232 return NULL;
1233 if (get_tiff_directory_info(s))
1234 {
1235 close_tiff_input_file(s);
1236 return NULL;
1237 }
1238
1239 s->t4_t6_tx.rows_to_next_1d_row = s->t4_t6_tx.max_rows_to_next_1d_row - 1;
1240
1241 s->tiff.pages_in_file = -1;
1242
1243 run_space = (s->image_width + 4)*sizeof(uint32_t);
1244 if ((s->cur_runs = (uint32_t *) malloc(run_space)) == NULL)
1245 return NULL;
1246 if ((s->ref_runs = (uint32_t *) malloc(run_space)) == NULL)
1247 {
1248 free_buffers(s);
1249 close_tiff_input_file(s);
1250 return NULL;
1251 }
1252 if ((s->row_buf = malloc(s->bytes_per_row)) == NULL)
1253 {
1254 free_buffers(s);
1255 close_tiff_input_file(s);
1256 return NULL;
1257 }
1258 s->ref_runs[0] =
1259 s->ref_runs[1] =
1260 s->ref_runs[2] =
1261 s->ref_runs[3] = s->image_width;
1262 s->t4_t6_tx.ref_steps = 1;
1263 s->image_buffer_size = 0;
1264 return s;
1265 }
1266 /*- End of function --------------------------------------------------------*/
1267
1268 SPAN_DECLARE(int) t4_tx_start_page(t4_state_t *s)
1269 {
1270 int row;
1271 int i;
1272 int run_space;
1273 int len;
1274 int old_image_width;
1275 uint8_t *bufptr8;
1276 uint32_t *bufptr;
1277
1278 span_log(&s->logging, SPAN_LOG_FLOW, "Start tx page %d\n", s->current_page);
1279 if (s->current_page > s->tiff.stop_page)
1280 return -1;
1281 if (s->tiff.tiff_file == NULL)
1282 return -1;
1283 old_image_width = s->image_width;
1284 if (s->t4_t6_tx.row_read_handler == NULL)
1285 {
1286 #if defined(HAVE_LIBTIFF)
1287 if (!TIFFSetDirectory(s->tiff.tiff_file, (tdir_t) s->current_page))
1288 return -1;
1289 get_tiff_directory_info(s);
1290 #endif
1291 }
1292 s->image_size = 0;
1293 s->tx_bitstream = 0;
1294 s->tx_bits = 0;
1295 s->row_is_2d = (s->line_encoding == T4_COMPRESSION_ITU_T6);
1296 s->t4_t6_tx.rows_to_next_1d_row = s->t4_t6_tx.max_rows_to_next_1d_row - 1;
1297
1298 /* Allow for pages being of different width. */
1299 run_space = (s->image_width + 4)*sizeof(uint32_t);
1300 if (old_image_width != s->image_width)
1301 {
1302 s->bytes_per_row = (s->image_width + 7)/8;
1303
1304 if ((bufptr = (uint32_t *) realloc(s->cur_runs, run_space)) == NULL)
1305 return -1;
1306 s->cur_runs = bufptr;
1307 if ((bufptr = (uint32_t *) realloc(s->ref_runs, run_space)) == NULL)
1308 return -1;
1309 s->ref_runs = bufptr;
1310 if ((bufptr8 = realloc(s->row_buf, s->bytes_per_row)) == NULL)
1311 return -1;
1312 s->row_buf = bufptr8;
1313 }
1314 s->ref_runs[0] =
1315 s->ref_runs[1] =
1316 s->ref_runs[2] =
1317 s->ref_runs[3] = s->image_width;
1318 s->t4_t6_tx.ref_steps = 1;
1319
1320 s->row_bits = 0;
1321 s->min_row_bits = INT_MAX;
1322 s->max_row_bits = 0;
1323
1324 if (s->t4_t6_tx.header_info && s->t4_t6_tx.header_info[0])
1325 {
1326 if (t4_tx_put_fax_header(s))
1327 return -1;
1328 }
1329 if (s->t4_t6_tx.row_read_handler)
1330 {
1331 for (row = 0; ; row++)
1332 {
1333 if ((len = s->t4_t6_tx.row_read_handler(s->t4_t6_tx.row_read_user_data, s->row_buf, s->bytes_per_row)) < 0)
1334 {
1335 span_log(&s->logging, SPAN_LOG_WARNING, "%s: Read error at row %d.\n", s->tiff.file, row);
1336 break;
1337 }
1338 if (len == 0)
1339 break;
1340 if (encode_row(s))
1341 return -1;
1342 }
1343 s->image_length = row;
1344 }
1345 else
1346 {
1347 if ((s->image_length = read_tiff_image(s)) < 0)
1348 return -1;
1349 }
1350 if (s->line_encoding == T4_COMPRESSION_ITU_T6)
1351 {
1352 /* Attach an EOFB (end of facsimile block == 2 x EOLs) to the end of the page */
1353 for (i = 0; i < EOLS_TO_END_T6_TX_PAGE; i++)
1354 encode_eol(s);
1355 }
1356 else
1357 {
1358 /* Attach an RTC (return to control == 6 x EOLs) to the end of the page */
1359 s->row_is_2d = FALSE;
1360 for (i = 0; i < EOLS_TO_END_T4_TX_PAGE; i++)
1361 encode_eol(s);
1362 }
1363
1364 /* Force any partial byte in progress to flush using ones. Any post EOL padding when
1365 sending is normally ones, so this is consistent. */
1366 put_encoded_bits(s, 0xFF, 7);
1367 s->t4_t6_tx.bit_pos = 7;
1368 s->t4_t6_tx.bit_ptr = 0;
1369 s->line_image_size = s->image_size*8;
1370
1371 return 0;
1372 }
1373 /*- End of function --------------------------------------------------------*/
1374
1375 SPAN_DECLARE(int) t4_tx_next_page_has_different_format(t4_state_t *s)
1376 {
1377 span_log(&s->logging, SPAN_LOG_FLOW, "Checking for the existance of page %d\n", s->current_page + 1);
1378 if (s->current_page >= s->tiff.stop_page)
1379 return -1;
1380 if (s->t4_t6_tx.row_read_handler == NULL)
1381 {
1382 #if defined(HAVE_LIBTIFF)
1383 if (s->tiff.tiff_file == NULL)
1384 return -1;
1385 if (!TIFFSetDirectory(s->tiff.tiff_file, (tdir_t) s->current_page + 1))
1386 return -1;
1387 return test_tiff_directory_info(s);
1388 #endif
1389 }
1390 return 0;
1391 }
1392 /*- End of function --------------------------------------------------------*/
1393
1394 SPAN_DECLARE(int) t4_tx_restart_page(t4_state_t *s)
1395 {
1396 s->t4_t6_tx.bit_pos = 7;
1397 s->t4_t6_tx.bit_ptr = 0;
1398 return 0;
1399 }
1400 /*- End of function --------------------------------------------------------*/
1401
1402 SPAN_DECLARE(int) t4_tx_end_page(t4_state_t *s)
1403 {
1404 s->current_page++;
1405 return 0;
1406 }
1407 /*- End of function --------------------------------------------------------*/
1408
1409 SPAN_DECLARE(int) t4_tx_get_bit(t4_state_t *s)
1410 {
1411 int bit;
1412
1413 if (s->t4_t6_tx.bit_ptr >= s->image_size)
1414 return SIG_STATUS_END_OF_DATA;
1415 bit = (s->image_buffer[s->t4_t6_tx.bit_ptr] >> (7 - s->t4_t6_tx.bit_pos)) & 1;
1416 if (--s->t4_t6_tx.bit_pos < 0)
1417 {
1418 s->t4_t6_tx.bit_pos = 7;
1419 s->t4_t6_tx.bit_ptr++;
1420 }
1421 return bit;
1422 }
1423 /*- End of function --------------------------------------------------------*/
1424
1425 SPAN_DECLARE(int) t4_tx_get_byte(t4_state_t *s)
1426 {
1427 if (s->t4_t6_tx.bit_ptr >= s->image_size)
1428 return 0x100;
1429 return s->image_buffer[s->t4_t6_tx.bit_ptr++];
1430 }
1431 /*- End of function --------------------------------------------------------*/
1432
1433 SPAN_DECLARE(int) t4_tx_get_chunk(t4_state_t *s, uint8_t buf[], int max_len)
1434 {
1435 if (s->t4_t6_tx.bit_ptr >= s->image_size)
1436 return 0;
1437 if (s->t4_t6_tx.bit_ptr + max_len > s->image_size)
1438 max_len = s->image_size - s->t4_t6_tx.bit_ptr;
1439 memcpy(buf, &s->image_buffer[s->t4_t6_tx.bit_ptr], max_len);
1440 s->t4_t6_tx.bit_ptr += max_len;
1441 return max_len;
1442 }
1443 /*- End of function --------------------------------------------------------*/
1444
1445 SPAN_DECLARE(int) t4_tx_check_bit(t4_state_t *s)
1446 {
1447 int bit;
1448
1449 if (s->t4_t6_tx.bit_ptr >= s->image_size)
1450 return SIG_STATUS_END_OF_DATA;
1451 bit = (s->image_buffer[s->t4_t6_tx.bit_ptr] >> s->t4_t6_tx.bit_pos) & 1;
1452 return bit;
1453 }
1454 /*- End of function --------------------------------------------------------*/
1455
1456 SPAN_DECLARE(int) t4_tx_release(t4_state_t *s)
1457 {
1458 if (s->rx)
1459 return -1;
1460 if (s->tiff.tiff_file)
1461 close_tiff_input_file(s);
1462 free_buffers(s);
1463 return 0;
1464 }
1465 /*- End of function --------------------------------------------------------*/
1466
1467 SPAN_DECLARE(int) t4_tx_free(t4_state_t *s)
1468 {
1469 int ret;
1470
1471 ret = t4_tx_release(s);
1472 free(s);
1473 return ret;
1474 }
1475 /*- End of function --------------------------------------------------------*/
1476
1477 SPAN_DECLARE(void) t4_tx_set_tx_encoding(t4_state_t *s, int encoding)
1478 {
1479 s->line_encoding = encoding;
1480 s->t4_t6_tx.rows_to_next_1d_row = s->t4_t6_tx.max_rows_to_next_1d_row - 1;
1481 s->row_is_2d = FALSE;
1482 }
1483 /*- End of function --------------------------------------------------------*/
1484
1485 SPAN_DECLARE(void) t4_tx_set_min_row_bits(t4_state_t *s, int bits)
1486 {
1487 s->t4_t6_tx.min_bits_per_row = bits;
1488 }
1489 /*- End of function --------------------------------------------------------*/
1490
1491 SPAN_DECLARE(void) t4_tx_set_local_ident(t4_state_t *s, const char *ident)
1492 {
1493 s->tiff.local_ident = (ident && ident[0]) ? ident : NULL;
1494 }
1495 /*- End of function --------------------------------------------------------*/
1496
1497 SPAN_DECLARE(void) t4_tx_set_header_info(t4_state_t *s, const char *info)
1498 {
1499 s->t4_t6_tx.header_info = (info && info[0]) ? info : NULL;
1500 }
1501 /*- End of function --------------------------------------------------------*/
1502
1503 SPAN_DECLARE(int) t4_tx_get_y_resolution(t4_state_t *s)
1504 {
1505 return s->y_resolution;
1506 }
1507 /*- End of function --------------------------------------------------------*/
1508
1509 SPAN_DECLARE(int) t4_tx_get_x_resolution(t4_state_t *s)
1510 {
1511 return s->x_resolution;
1512 }
1513 /*- End of function --------------------------------------------------------*/
1514
1515 SPAN_DECLARE(int) t4_tx_get_image_width(t4_state_t *s)
1516 {
1517 return s->image_width;
1518 }
1519 /*- End of function --------------------------------------------------------*/
1520
1521 SPAN_DECLARE(int) t4_tx_get_pages_in_file(t4_state_t *s)
1522 {
1523 int max;
1524
1525 max = 0;
1526 if (s->t4_t6_tx.row_read_handler == NULL)
1527 max = get_tiff_total_pages(s);
1528 if (max >= 0)
1529 s->tiff.pages_in_file = max;
1530 return max;
1531 }
1532 /*- End of function --------------------------------------------------------*/
1533
1534 SPAN_DECLARE(int) t4_tx_get_current_page_in_file(t4_state_t *s)
1535 {
1536 return s->current_page;
1537 }
1538 /*- End of function --------------------------------------------------------*/
1539 /*- End of file ------------------------------------------------------------*/

Repositories maintained by Peter Meerwald, pmeerw@pmeerw.net.