Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4680 right-hear 1
#include "fitz.h"
2
 
3
/* Fax G3/G4 decoder */
4
 
5
/* TODO: uncompressed */
6
 
7
/*
8
 the first 2^(initialbits) entries map bit patterns to decodes
9
 let's say initial_bits is 8 for the sake of example
10
 and that the code is 1001
11
 that means that entries 0x90 .. 0x9f have the entry { val, 4 }
12
 because those are all the bytes that start with the code
13
 and the 4 is the length of the code
14
... if (n_bits > initial_bits) ...
15
 anyway, in that case, it basically points to a mini table
16
 the n_bits is the maximum length of all codes beginning with that byte
17
 so 2^(n_bits - initial_bits) is the size of the mini-table
18
 peter came up with this, and it makes sense
19
*/
20
 
21
typedef struct cfd_node_s cfd_node;
22
 
23
struct cfd_node_s
24
{
25
	short val;
26
	short nbits;
27
};
28
 
29
enum
30
{
31
	cfd_white_initial_bits = 8,
32
	cfd_black_initial_bits = 7,
33
	cfd_2d_initial_bits = 7,
34
	cfd_uncompressed_initial_bits = 6	/* must be 6 */
35
};
36
 
37
/* non-run codes in tables */
38
enum
39
{
40
	ERROR = -1,
41
	ZEROS = -2, /* EOL follows, possibly with more padding first */
42
	UNCOMPRESSED = -3
43
};
44
 
45
/* semantic codes for cf_2d_decode */
46
enum
47
{
48
	P = -4,
49
	H = -5,
50
	VR3 = 0,
51
	VR2 = 1,
52
	VR1 = 2,
53
	V0 = 3,
54
	VL1 = 4,
55
	VL2 = 5,
56
	VL3 = 6
57
};
58
 
59
/* White decoding table. */
60
const cfd_node cf_white_decode[] = {
61
	{256,12},{272,12},{29,8},{30,8},{45,8},{46,8},{22,7},{22,7},
62
	{23,7},{23,7},{47,8},{48,8},{13,6},{13,6},{13,6},{13,6},{20,7},
63
	{20,7},{33,8},{34,8},{35,8},{36,8},{37,8},{38,8},{19,7},{19,7},
64
	{31,8},{32,8},{1,6},{1,6},{1,6},{1,6},{12,6},{12,6},{12,6},{12,6},
65
	{53,8},{54,8},{26,7},{26,7},{39,8},{40,8},{41,8},{42,8},{43,8},
66
	{44,8},{21,7},{21,7},{28,7},{28,7},{61,8},{62,8},{63,8},{0,8},
67
	{320,8},{384,8},{10,5},{10,5},{10,5},{10,5},{10,5},{10,5},{10,5},
68
	{10,5},{11,5},{11,5},{11,5},{11,5},{11,5},{11,5},{11,5},{11,5},
69
	{27,7},{27,7},{59,8},{60,8},{288,9},{290,9},{18,7},{18,7},{24,7},
70
	{24,7},{49,8},{50,8},{51,8},{52,8},{25,7},{25,7},{55,8},{56,8},
71
	{57,8},{58,8},{192,6},{192,6},{192,6},{192,6},{1664,6},{1664,6},
72
	{1664,6},{1664,6},{448,8},{512,8},{292,9},{640,8},{576,8},{294,9},
73
	{296,9},{298,9},{300,9},{302,9},{256,7},{256,7},{2,4},{2,4},{2,4},
74
	{2,4},{2,4},{2,4},{2,4},{2,4},{2,4},{2,4},{2,4},{2,4},{2,4},{2,4},
75
	{2,4},{2,4},{3,4},{3,4},{3,4},{3,4},{3,4},{3,4},{3,4},{3,4},{3,4},
76
	{3,4},{3,4},{3,4},{3,4},{3,4},{3,4},{3,4},{128,5},{128,5},{128,5},
77
	{128,5},{128,5},{128,5},{128,5},{128,5},{8,5},{8,5},{8,5},{8,5},
78
	{8,5},{8,5},{8,5},{8,5},{9,5},{9,5},{9,5},{9,5},{9,5},{9,5},{9,5},
79
	{9,5},{16,6},{16,6},{16,6},{16,6},{17,6},{17,6},{17,6},{17,6},
80
	{4,4},{4,4},{4,4},{4,4},{4,4},{4,4},{4,4},{4,4},{4,4},{4,4},{4,4},
81
	{4,4},{4,4},{4,4},{4,4},{4,4},{5,4},{5,4},{5,4},{5,4},{5,4},{5,4},
82
	{5,4},{5,4},{5,4},{5,4},{5,4},{5,4},{5,4},{5,4},{5,4},{5,4},
83
	{14,6},{14,6},{14,6},{14,6},{15,6},{15,6},{15,6},{15,6},{64,5},
84
	{64,5},{64,5},{64,5},{64,5},{64,5},{64,5},{64,5},{6,4},{6,4},
85
	{6,4},{6,4},{6,4},{6,4},{6,4},{6,4},{6,4},{6,4},{6,4},{6,4},{6,4},
86
	{6,4},{6,4},{6,4},{7,4},{7,4},{7,4},{7,4},{7,4},{7,4},{7,4},{7,4},
87
	{7,4},{7,4},{7,4},{7,4},{7,4},{7,4},{7,4},{7,4},{-2,3},{-2,3},
88
	{-1,0},{-1,0},{-1,0},{-1,0},{-1,0},{-1,0},{-1,0},{-1,0},{-1,0},
89
	{-1,0},{-1,0},{-1,0},{-1,0},{-3,4},{1792,3},{1792,3},{1984,4},
90
	{2048,4},{2112,4},{2176,4},{2240,4},{2304,4},{1856,3},{1856,3},
91
	{1920,3},{1920,3},{2368,4},{2432,4},{2496,4},{2560,4},{1472,1},
92
	{1536,1},{1600,1},{1728,1},{704,1},{768,1},{832,1},{896,1},
93
	{960,1},{1024,1},{1088,1},{1152,1},{1216,1},{1280,1},{1344,1},
94
	{1408,1}
95
};
96
 
97
/* Black decoding table. */
98
const cfd_node cf_black_decode[] = {
99
	{128,12},{160,13},{224,12},{256,12},{10,7},{11,7},{288,12},{12,7},
100
	{9,6},{9,6},{8,6},{8,6},{7,5},{7,5},{7,5},{7,5},{6,4},{6,4},{6,4},
101
	{6,4},{6,4},{6,4},{6,4},{6,4},{5,4},{5,4},{5,4},{5,4},{5,4},{5,4},
102
	{5,4},{5,4},{1,3},{1,3},{1,3},{1,3},{1,3},{1,3},{1,3},{1,3},{1,3},
103
	{1,3},{1,3},{1,3},{1,3},{1,3},{1,3},{1,3},{4,3},{4,3},{4,3},{4,3},
104
	{4,3},{4,3},{4,3},{4,3},{4,3},{4,3},{4,3},{4,3},{4,3},{4,3},{4,3},
105
	{4,3},{3,2},{3,2},{3,2},{3,2},{3,2},{3,2},{3,2},{3,2},{3,2},{3,2},
106
	{3,2},{3,2},{3,2},{3,2},{3,2},{3,2},{3,2},{3,2},{3,2},{3,2},{3,2},
107
	{3,2},{3,2},{3,2},{3,2},{3,2},{3,2},{3,2},{3,2},{3,2},{3,2},{3,2},
108
	{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},
109
	{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},
110
	{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},{2,2},
111
	{-2,4},{-2,4},{-1,0},{-1,0},{-1,0},{-1,0},{-1,0},{-1,0},{-1,0},
112
	{-1,0},{-1,0},{-1,0},{-1,0},{-1,0},{-1,0},{-3,5},{1792,4},
113
	{1792,4},{1984,5},{2048,5},{2112,5},{2176,5},{2240,5},{2304,5},
114
	{1856,4},{1856,4},{1920,4},{1920,4},{2368,5},{2432,5},{2496,5},
115
	{2560,5},{18,3},{18,3},{18,3},{18,3},{18,3},{18,3},{18,3},{18,3},
116
	{52,5},{52,5},{640,6},{704,6},{768,6},{832,6},{55,5},{55,5},
117
	{56,5},{56,5},{1280,6},{1344,6},{1408,6},{1472,6},{59,5},{59,5},
118
	{60,5},{60,5},{1536,6},{1600,6},{24,4},{24,4},{24,4},{24,4},
119
	{25,4},{25,4},{25,4},{25,4},{1664,6},{1728,6},{320,5},{320,5},
120
	{384,5},{384,5},{448,5},{448,5},{512,6},{576,6},{53,5},{53,5},
121
	{54,5},{54,5},{896,6},{960,6},{1024,6},{1088,6},{1152,6},{1216,6},
122
	{64,3},{64,3},{64,3},{64,3},{64,3},{64,3},{64,3},{64,3},{13,1},
123
	{13,1},{13,1},{13,1},{13,1},{13,1},{13,1},{13,1},{13,1},{13,1},
124
	{13,1},{13,1},{13,1},{13,1},{13,1},{13,1},{23,4},{23,4},{50,5},
125
	{51,5},{44,5},{45,5},{46,5},{47,5},{57,5},{58,5},{61,5},{256,5},
126
	{16,3},{16,3},{16,3},{16,3},{17,3},{17,3},{17,3},{17,3},{48,5},
127
	{49,5},{62,5},{63,5},{30,5},{31,5},{32,5},{33,5},{40,5},{41,5},
128
	{22,4},{22,4},{14,1},{14,1},{14,1},{14,1},{14,1},{14,1},{14,1},
129
	{14,1},{14,1},{14,1},{14,1},{14,1},{14,1},{14,1},{14,1},{14,1},
130
	{15,2},{15,2},{15,2},{15,2},{15,2},{15,2},{15,2},{15,2},{128,5},
131
	{192,5},{26,5},{27,5},{28,5},{29,5},{19,4},{19,4},{20,4},{20,4},
132
	{34,5},{35,5},{36,5},{37,5},{38,5},{39,5},{21,4},{21,4},{42,5},
133
	{43,5},{0,3},{0,3},{0,3},{0,3}
134
};
135
 
136
/* 2-D decoding table. */
137
const cfd_node cf_2d_decode[] = {
138
	{128,11},{144,10},{6,7},{0,7},{5,6},{5,6},{1,6},{1,6},{-4,4},
139
	{-4,4},{-4,4},{-4,4},{-4,4},{-4,4},{-4,4},{-4,4},{-5,3},{-5,3},
140
	{-5,3},{-5,3},{-5,3},{-5,3},{-5,3},{-5,3},{-5,3},{-5,3},{-5,3},
141
	{-5,3},{-5,3},{-5,3},{-5,3},{-5,3},{4,3},{4,3},{4,3},{4,3},{4,3},
142
	{4,3},{4,3},{4,3},{4,3},{4,3},{4,3},{4,3},{4,3},{4,3},{4,3},{4,3},
143
	{2,3},{2,3},{2,3},{2,3},{2,3},{2,3},{2,3},{2,3},{2,3},{2,3},{2,3},
144
	{2,3},{2,3},{2,3},{2,3},{2,3},{3,1},{3,1},{3,1},{3,1},{3,1},{3,1},
145
	{3,1},{3,1},{3,1},{3,1},{3,1},{3,1},{3,1},{3,1},{3,1},{3,1},{3,1},
146
	{3,1},{3,1},{3,1},{3,1},{3,1},{3,1},{3,1},{3,1},{3,1},{3,1},{3,1},
147
	{3,1},{3,1},{3,1},{3,1},{3,1},{3,1},{3,1},{3,1},{3,1},{3,1},{3,1},
148
	{3,1},{3,1},{3,1},{3,1},{3,1},{3,1},{3,1},{3,1},{3,1},{3,1},{3,1},
149
	{3,1},{3,1},{3,1},{3,1},{3,1},{3,1},{3,1},{3,1},{3,1},{3,1},{3,1},
150
	{3,1},{3,1},{3,1},{-2,4},{-1,0},{-1,0},{-1,0},{-1,0},{-1,0},
151
	{-1,0},{-1,0},{-1,0},{-1,0},{-1,0},{-1,0},{-1,0},{-1,0},{-1,0},
152
	{-1,0},{-1,0},{-1,0},{-1,0},{-1,0},{-1,0},{-1,0},{-1,0},{-3,3}
153
};
154
 
155
/* Uncompresssed decoding table. */
156
const cfd_node cf_uncompressed_decode[] = {
157
	{64,12},{5,6},{4,5},{4,5},{3,4},{3,4},{3,4},{3,4},{2,3},{2,3},
158
	{2,3},{2,3},{2,3},{2,3},{2,3},{2,3},{1,2},{1,2},{1,2},{1,2},{1,2},
159
	{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},
160
	{0,1},{0,1},{0,1},{0,1},{0,1},{0,1},{0,1},{0,1},{0,1},{0,1},{0,1},
161
	{0,1},{0,1},{0,1},{0,1},{0,1},{0,1},{0,1},{0,1},{0,1},{0,1},{0,1},
162
	{0,1},{0,1},{0,1},{0,1},{0,1},{0,1},{0,1},{0,1},{0,1},{0,1},
163
	{-1,0},{-1,0},{8,6},{9,6},{6,5},{6,5},{7,5},{7,5},{4,4},{4,4},
164
	{4,4},{4,4},{5,4},{5,4},{5,4},{5,4},{2,3},{2,3},{2,3},{2,3},{2,3},
165
	{2,3},{2,3},{2,3},{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},
166
	{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},{0,2},
167
	{0,2},{0,2},{0,2},{0,2},{0,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},
168
	{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2},{1,2}
169
};
170
 
171
/* bit magic */
172
 
173
static inline int getbit(const unsigned char *buf, int x)
174
{
175
	return ( buf[x >> 3] >> ( 7 - (x & 7) ) ) & 1;
176
}
177
 
178
static int
179
find_changing(const unsigned char *line, int x, int w)
180
{
181
	int a, b;
182
 
183
	if (!line)
184
		return w;
185
 
186
	if (x == -1)
187
	{
188
		a = 0;
189
		x = 0;
190
	}
191
	else
192
	{
193
		a = getbit(line, x);
194
		x++;
195
	}
196
 
197
	while (x < w)
198
	{
199
		b = getbit(line, x);
200
		if (a != b)
201
			break;
202
		x++;
203
	}
204
 
205
	return x;
206
}
207
 
208
static int
209
find_changing_color(const unsigned char *line, int x, int w, int color)
210
{
211
	if (!line)
212
		return w;
213
 
214
	x = find_changing(line, x, w);
215
 
216
	if (x < w && getbit(line, x) != color)
217
		x = find_changing(line, x, w);
218
 
219
	return x;
220
}
221
 
222
static const unsigned char lm[8] = {
223
	0xFF, 0x7F, 0x3F, 0x1F, 0x0F, 0x07, 0x03, 0x01
224
};
225
 
226
static const unsigned char rm[8] = {
227
	0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE
228
};
229
 
230
static inline void setbits(unsigned char *line, int x0, int x1)
231
{
232
	int a0, a1, b0, b1, a;
233
 
234
	a0 = x0 >> 3;
235
	a1 = x1 >> 3;
236
 
237
	b0 = x0 & 7;
238
	b1 = x1 & 7;
239
 
240
	if (a0 == a1)
241
	{
242
		if (b1)
243
			line[a0] |= lm[b0] & rm[b1];
244
	}
245
	else
246
	{
247
		line[a0] |= lm[b0];
248
		for (a = a0 + 1; a < a1; a++)
249
			line[a] = 0xFF;
250
		if (b1)
251
			line[a1] |= rm[b1];
252
	}
253
}
254
 
255
typedef struct fz_faxd_s fz_faxd;
256
 
257
enum
258
{
259
	STATE_NORMAL,	/* neutral state, waiting for any code */
260
	STATE_MAKEUP,	/* got a 1d makeup code, waiting for terminating code */
261
	STATE_EOL,		/* at eol, needs output buffer space */
262
	STATE_H1, STATE_H2,	/* in H part 1 and 2 (both makeup and terminating codes) */
263
	STATE_DONE		/* all done */
264
};
265
 
266
struct fz_faxd_s
267
{
268
	fz_stream *chain;
269
 
270
	int k;
271
	int end_of_line;
272
	int encoded_byte_align;
273
	int columns;
274
	int rows;
275
	int end_of_block;
276
	int black_is_1;
277
 
278
	int stride;
279
	int ridx;
280
 
281
	int bidx;
282
	unsigned int word;
283
 
284
	int stage;
285
 
286
	int a, c, dim, eolc;
287
	unsigned char *ref;
288
	unsigned char *dst;
289
	unsigned char *rp, *wp;
290
};
291
 
292
static inline void eat_bits(fz_faxd *fax, int nbits)
293
{
294
	fax->word <<= nbits;
295
	fax->bidx += nbits;
296
}
297
 
298
static int
299
fill_bits(fz_faxd *fax)
300
{
301
	while (fax->bidx >= 8)
302
	{
303
		int c = fz_read_byte(fax->chain);
304
		if (c == EOF)
305
			return EOF;
306
		fax->bidx -= 8;
307
		fax->word |= c << fax->bidx;
308
	}
309
	return 0;
310
}
311
 
312
static int
313
get_code(fz_faxd *fax, const cfd_node *table, int initialbits)
314
{
315
	unsigned int word = fax->word;
316
	int tidx = word >> (32 - initialbits);
317
	int val = table[tidx].val;
318
	int nbits = table[tidx].nbits;
319
 
320
	if (nbits > initialbits)
321
	{
322
		int mask = (1 << (32 - initialbits)) - 1;
323
		tidx = val + ((word & mask) >> (32 - nbits));
324
		val = table[tidx].val;
325
		nbits = initialbits + table[tidx].nbits;
326
	}
327
 
328
	eat_bits(fax, nbits);
329
 
330
	return val;
331
}
332
 
333
/* decode one 1d code */
334
static fz_error
335
dec1d(fz_faxd *fax)
336
{
337
	int code;
338
 
339
	if (fax->a == -1)
340
		fax->a = 0;
341
 
342
	if (fax->c)
343
		code = get_code(fax, cf_black_decode, cfd_black_initial_bits);
344
	else
345
		code = get_code(fax, cf_white_decode, cfd_white_initial_bits);
346
 
347
	if (code == UNCOMPRESSED)
348
		return fz_throw("uncompressed data in faxd");
349
 
350
	if (code < 0)
351
		return fz_throw("negative code in 1d faxd");
352
 
353
	if (fax->a + code > fax->columns)
354
		return fz_throw("overflow in 1d faxd");
355
 
356
	if (fax->c)
357
		setbits(fax->dst, fax->a, fax->a + code);
358
 
359
	fax->a += code;
360
 
361
	if (code < 64)
362
	{
363
		fax->c = !fax->c;
364
		fax->stage = STATE_NORMAL;
365
	}
366
	else
367
		fax->stage = STATE_MAKEUP;
368
 
369
	return fz_okay;
370
}
371
 
372
/* decode one 2d code */
373
static fz_error
374
dec2d(fz_faxd *fax)
375
{
376
	int code, b1, b2;
377
 
378
	if (fax->stage == STATE_H1 || fax->stage == STATE_H2)
379
	{
380
		if (fax->a == -1)
381
			fax->a = 0;
382
 
383
		if (fax->c)
384
			code = get_code(fax, cf_black_decode, cfd_black_initial_bits);
385
		else
386
			code = get_code(fax, cf_white_decode, cfd_white_initial_bits);
387
 
388
		if (code == UNCOMPRESSED)
389
			return fz_throw("uncompressed data in faxd");
390
 
391
		if (code < 0)
392
			return fz_throw("negative code in 2d faxd");
393
 
394
		if (fax->a + code > fax->columns)
395
			return fz_throw("overflow in 2d faxd");
396
 
397
		if (fax->c)
398
			setbits(fax->dst, fax->a, fax->a + code);
399
 
400
		fax->a += code;
401
 
402
		if (code < 64)
403
		{
404
			fax->c = !fax->c;
405
			if (fax->stage == STATE_H1)
406
				fax->stage = STATE_H2;
407
			else if (fax->stage == STATE_H2)
408
				fax->stage = STATE_NORMAL;
409
		}
410
 
411
		return fz_okay;
412
	}
413
 
414
	code = get_code(fax, cf_2d_decode, cfd_2d_initial_bits);
415
 
416
	switch (code)
417
	{
418
	case H:
419
		fax->stage = STATE_H1;
420
		break;
421
 
422
	case P:
423
		b1 = find_changing_color(fax->ref, fax->a, fax->columns, !fax->c);
424
		if (b1 >= fax->columns)
425
			b2 = fax->columns;
426
		else
427
			b2 = find_changing(fax->ref, b1, fax->columns);
428
		if (fax->c) setbits(fax->dst, fax->a, b2);
429
		fax->a = b2;
430
		break;
431
 
432
	case V0:
433
		b1 = find_changing_color(fax->ref, fax->a, fax->columns, !fax->c);
434
		if (fax->c) setbits(fax->dst, fax->a, b1);
435
		fax->a = b1;
436
		fax->c = !fax->c;
437
		break;
438
 
439
	case VR1:
440
		b1 = 1 + find_changing_color(fax->ref, fax->a, fax->columns, !fax->c);
441
		if (b1 >= fax->columns) b1 = fax->columns;
442
		if (fax->c) setbits(fax->dst, fax->a, b1);
443
		fax->a = b1;
444
		fax->c = !fax->c;
445
		break;
446
 
447
	case VR2:
448
		b1 = 2 + find_changing_color(fax->ref, fax->a, fax->columns, !fax->c);
449
		if (b1 >= fax->columns) b1 = fax->columns;
450
		if (fax->c) setbits(fax->dst, fax->a, b1);
451
		fax->a = b1;
452
		fax->c = !fax->c;
453
		break;
454
 
455
	case VR3:
456
		b1 = 3 + find_changing_color(fax->ref, fax->a, fax->columns, !fax->c);
457
		if (b1 >= fax->columns) b1 = fax->columns;
458
		if (fax->c) setbits(fax->dst, fax->a, b1);
459
		fax->a = b1;
460
		fax->c = !fax->c;
461
		break;
462
 
463
	case VL1:
464
		b1 = -1 + find_changing_color(fax->ref, fax->a, fax->columns, !fax->c);
465
		if (b1 < 0) b1 = 0;
466
		if (fax->c) setbits(fax->dst, fax->a, b1);
467
		fax->a = b1;
468
		fax->c = !fax->c;
469
		break;
470
 
471
	case VL2:
472
		b1 = -2 + find_changing_color(fax->ref, fax->a, fax->columns, !fax->c);
473
		if (b1 < 0) b1 = 0;
474
		if (fax->c) setbits(fax->dst, fax->a, b1);
475
		fax->a = b1;
476
		fax->c = !fax->c;
477
		break;
478
 
479
	case VL3:
480
		b1 = -3 + find_changing_color(fax->ref, fax->a, fax->columns, !fax->c);
481
		if (b1 < 0) b1 = 0;
482
		if (fax->c) setbits(fax->dst, fax->a, b1);
483
		fax->a = b1;
484
		fax->c = !fax->c;
485
		break;
486
 
487
	case UNCOMPRESSED:
488
		return fz_throw("uncompressed data in faxd");
489
 
490
	case ERROR:
491
		return fz_throw("invalid code in 2d faxd");
492
 
493
	default:
494
		return fz_throw("invalid code in 2d faxd (%d)", code);
495
	}
496
 
497
	return 0;
498
}
499
 
500
static int
501
read_faxd(fz_stream *stm, unsigned char *buf, int len)
502
{
503
	fz_faxd *fax = stm->state;
504
	unsigned char *p = buf;
505
	unsigned char *ep = buf + len;
506
	unsigned char *tmp;
507
	fz_error error;
508
 
509
	if (fax->stage == STATE_DONE)
510
		return 0;
511
 
512
	if (fax->stage == STATE_EOL)
513
		goto eol;
514
 
515
loop:
516
 
517
	if (fill_bits(fax))
518
	{
519
		if (fax->bidx > 31)
520
		{
521
			if (fax->a > 0)
522
				goto eol;
523
			goto rtc;
524
		}
525
	}
526
 
527
	if ((fax->word >> (32 - 12)) == 0)
528
	{
529
		eat_bits(fax, 1);
530
		goto loop;
531
	}
532
 
533
	if ((fax->word >> (32 - 12)) == 1)
534
	{
535
		eat_bits(fax, 12);
536
		fax->eolc ++;
537
 
538
		if (fax->k > 0)
539
		{
540
			if (fax->a == -1)
541
				fax->a = 0;
542
			if ((fax->word >> (32 - 1)) == 1)
543
				fax->dim = 1;
544
			else
545
				fax->dim = 2;
546
			eat_bits(fax, 1);
547
		}
548
	}
549
	else if (fax->k > 0 && fax->a == -1)
550
	{
551
		fax->a = 0;
552
		if ((fax->word >> (32 - 1)) == 1)
553
			fax->dim = 1;
554
		else
555
			fax->dim = 2;
556
		eat_bits(fax, 1);
557
	}
558
	else if (fax->dim == 1)
559
	{
560
		fax->eolc = 0;
561
		error = dec1d(fax);
562
		if (error)
563
			return fz_rethrow(error, "cannot decode 1d code");
564
	}
565
	else if (fax->dim == 2)
566
	{
567
		fax->eolc = 0;
568
		error = dec2d(fax);
569
		if (error)
570
			return fz_rethrow(error, "cannot decode 2d code");
571
	}
572
 
573
	/* no eol check after makeup codes nor in the middle of an H code */
574
	if (fax->stage == STATE_MAKEUP || fax->stage == STATE_H1 || fax->stage == STATE_H2)
575
		goto loop;
576
 
577
	/* check for eol conditions */
578
	if (fax->eolc || fax->a >= fax->columns)
579
	{
580
		if (fax->a > 0)
581
			goto eol;
582
		if (fax->eolc == (fax->k < 0 ? 2 : 6))
583
			goto rtc;
584
	}
585
 
586
	goto loop;
587
 
588
eol:
589
	fax->stage = STATE_EOL;
590
 
591
	if (fax->black_is_1)
592
	{
593
		while (fax->rp < fax->wp && p < ep)
594
			*p++ = *fax->rp++;
595
	}
596
	else
597
	{
598
		while (fax->rp < fax->wp && p < ep)
599
			*p++ = *fax->rp++ ^ 0xff;
600
	}
601
 
602
	if (fax->rp < fax->wp)
603
		return p - buf;
604
 
605
	tmp = fax->ref;
606
	fax->ref = fax->dst;
607
	fax->dst = tmp;
608
	memset(fax->dst, 0, fax->stride);
609
 
610
	fax->rp = fax->dst;
611
	fax->wp = fax->dst + fax->stride;
612
 
613
	fax->stage = STATE_NORMAL;
614
	fax->c = 0;
615
	fax->a = -1;
616
	fax->ridx ++;
617
 
618
	if (!fax->end_of_block && fax->rows)
619
	{
620
		if (fax->ridx >= fax->rows)
621
			goto rtc;
622
	}
623
 
624
	/* we have not read dim from eol, make a guess */
625
	if (fax->k > 0 && !fax->eolc && fax->a == -1)
626
	{
627
		if (fax->ridx % fax->k == 0)
628
			fax->dim = 1;
629
		else
630
			fax->dim = 2;
631
	}
632
 
633
	/* if end_of_line & encoded_byte_align, EOLs are *not* optional */
634
	if (fax->encoded_byte_align)
635
	{
636
		if (fax->end_of_line)
637
			eat_bits(fax, (12 - fax->bidx) & 7);
638
		else
639
			eat_bits(fax, (8 - fax->bidx) & 7);
640
	}
641
 
642
	/* no more space in output, don't decode the next row yet */
643
	if (p == buf + len)
644
		return p - buf;
645
 
646
	goto loop;
647
 
648
rtc:
649
	fax->stage = STATE_DONE;
650
	return p - buf;
651
}
652
 
653
static void
654
close_faxd(fz_stream *stm)
655
{
656
	fz_faxd *fax = stm->state;
657
	int i;
658
 
659
	/* if we read any extra bytes, try to put them back */
660
	i = (32 - fax->bidx) / 8;
661
	while (i--)
662
		fz_unread_byte(fax->chain);
663
 
664
	fz_close(fax->chain);
665
	fz_free(fax->ref);
666
	fz_free(fax->dst);
667
	fz_free(fax);
668
}
669
 
670
fz_stream *
671
fz_open_faxd(fz_stream *chain, fz_obj *params)
672
{
673
	fz_faxd *fax;
674
	fz_obj *obj;
675
 
676
	fax = fz_malloc(sizeof(fz_faxd));
677
	fax->chain = chain;
678
 
679
	fax->ref = NULL;
680
	fax->dst = NULL;
681
 
682
	fax->k = 0;
683
	fax->end_of_line = 0;
684
	fax->encoded_byte_align = 0;
685
	fax->columns = 1728;
686
	fax->rows = 0;
687
	fax->end_of_block = 1;
688
	fax->black_is_1 = 0;
689
 
690
	obj = fz_dict_gets(params, "K");
691
	if (obj) fax->k = fz_to_int(obj);
692
 
693
	obj = fz_dict_gets(params, "EndOfLine");
694
	if (obj) fax->end_of_line = fz_to_bool(obj);
695
 
696
	obj = fz_dict_gets(params, "EncodedByteAlign");
697
	if (obj) fax->encoded_byte_align = fz_to_bool(obj);
698
 
699
	obj = fz_dict_gets(params, "Columns");
700
	if (obj) fax->columns = fz_to_int(obj);
701
 
702
	obj = fz_dict_gets(params, "Rows");
703
	if (obj) fax->rows = fz_to_int(obj);
704
 
705
	obj = fz_dict_gets(params, "EndOfBlock");
706
	if (obj) fax->end_of_block = fz_to_bool(obj);
707
 
708
	obj = fz_dict_gets(params, "BlackIs1");
709
	if (obj) fax->black_is_1 = fz_to_bool(obj);
710
 
711
	fax->stride = ((fax->columns - 1) >> 3) + 1;
712
	fax->ridx = 0;
713
	fax->bidx = 32;
714
	fax->word = 0;
715
 
716
	fax->stage = STATE_NORMAL;
717
	fax->a = -1;
718
	fax->c = 0;
719
	fax->dim = fax->k < 0 ? 2 : 1;
720
	fax->eolc = 0;
721
 
722
	fax->ref = fz_malloc(fax->stride);
723
	fax->dst = fz_malloc(fax->stride);
724
	fax->rp = fax->dst;
725
	fax->wp = fax->dst + fax->stride;
726
 
727
	memset(fax->ref, 0, fax->stride);
728
	memset(fax->dst, 0, fax->stride);
729
 
730
	return fz_new_stream(fax, read_faxd, close_faxd);
731
}