1 /*
2  * << Haru Free PDF Library >> -- hpdf_image.c
3  *
4  * URL: http://libharu.org
5  *
6  * Copyright (c) 1999-2006 Takeshi Kanno <takeshi_kanno@est.hi-ho.ne.jp>
7  * Copyright (c) 2007-2009 Antony Dovgal <tony@daylessday.org>
8  *
9  * Permission to use, copy, modify, distribute and sell this software
10  * and its documentation for any purpose is hereby granted without fee,
11  * provided that the above copyright notice appear in all copies and
12  * that both that copyright notice and this permission notice appear
13  * in supporting documentation.
14  * It is provided "as is" without express or implied warranty.
15  *
16  */
17 
18 #include "hpdf_conf.h"
19 #include "hpdf_utils.h"
20 #include "hpdf.h"
21 #include <memory.h>
22 #include <assert.h>
23 
24 #define	G3CODES
25 #include "t4.h"
26 
27 typedef unsigned int uint32;
28 typedef int int32;
29 typedef unsigned short uint16;
30 typedef int32 tsize_t;          /* i/o size in bytes */
31 /*
32  * Typedefs for ``method pointers'' used internally.
33  */
34 typedef	unsigned char tidataval_t;	/* internal image data value type */
35 typedef	tidataval_t* tidata_t;		/* reference to internal image data */
36 
37 /*
38  * Compression+decompression state blocks are
39  * derived from this ``base state'' block.
40  */
41 typedef struct {
42         /* int     rw_mode;                */ /* O_RDONLY for decode, else encode */
43 	int	mode;			/* operating mode */
44 	uint32	rowbytes;		/* bytes in a decoded scanline */
45 	uint32	rowpixels;		/* pixels in a scanline */
46 
47 	uint16	cleanfaxdata;		/* CleanFaxData tag */
48 	uint32	badfaxrun;		/* BadFaxRun tag */
49 	uint32	badfaxlines;		/* BadFaxLines tag */
50 	uint32	groupoptions;		/* Group 3/4 options tag */
51 	uint32	recvparams;		/* encoded Class 2 session params */
52 	char*	subaddress;		/* subaddress string */
53 	uint32	recvtime;		/* time spent receiving (secs) */
54 	char*	faxdcs;			/* Table 2/T.30 encoded session params */
55 } HPDF_Fax3BaseState;
56 
57 typedef struct {
58 	HPDF_Fax3BaseState b;
59 
60 	/* Decoder state info */
61 	const unsigned char* bitmap;	/* bit reversal table */
62 	uint32	data;			/* current i/o byte/word */
63 	int	bit;			/* current i/o bit in byte */
64 	int	EOLcnt;			/* count of EOL codes recognized */
65 	/* TIFFFaxFillFunc fill;*/		/* fill routine */
66 	uint32*	runs;			/* b&w runs for current/previous row */
67 	uint32*	refruns;		/* runs for reference line */
68 	uint32*	curruns;		/* runs for current line */
69 
70 	/* Encoder state info */
71 	/* Ttag    tag;		*/	/* encoding state */
72 	unsigned char*	refline;	/* reference line for 2d decoding */
73 	int	k;			/* #rows left that can be 2d encoded */
74 	int	maxk;			/* max #rows that can be 2d encoded */
75 
76 	int line;
77 } HPDF_Fax3CodecState;
78 
79 #define	Fax3State(tif)		(&(tif)->tif_data->b)
80 #define	EncoderState(tif)	((tif)->tif_data)
81 #define	isAligned(p,t)	((((unsigned long)(p)) & (sizeof (t)-1)) == 0)
82 
83 /* NB: the uint32 casts are to silence certain ANSI-C compilers */
84 #define TIFFhowmany(x, y) ((((uint32)(x))+(((uint32)(y))-1))/((uint32)(y)))
85 #define TIFFhowmany8(x) (((x)&0x07)?((uint32)(x)>>3)+1:(uint32)(x)>>3)
86 #define	TIFFroundup(x, y) (TIFFhowmany(x,y)*(y))
87 
88 
89 /*
90 struct _HPDF_CCITT_Encoder {
91 } HPDF_CCITT_Encoder;
92 */
93 
94 struct _HPDF_CCITT_Data {
95 	HPDF_Fax3CodecState *tif_data;
96 
97 	HPDF_Stream  dst;
98 
99 	tsize_t		tif_rawdatasize;/* # of bytes in raw data buffer */
100 	tsize_t		tif_rawcc;	/* bytes unread from raw buffer */
101 	tidata_t	tif_rawcp;	/* current spot in raw buffer */
102 	tidata_t	tif_rawdata;	/* raw data buffer */
103 
104 } HPDF_CCITT_Data;
105 
HPDF_InitCCITTFax3(struct _HPDF_CCITT_Data * pData)106 static HPDF_STATUS HPDF_InitCCITTFax3(struct _HPDF_CCITT_Data *pData)
107 {
108 	HPDF_Fax3BaseState* sp;
109 	HPDF_Fax3CodecState* esp;
110 
111 	/*
112 	 * Allocate state block so tag methods have storage to record values.
113 	 */
114 	pData->tif_data = (HPDF_Fax3CodecState *)
115 		malloc(sizeof (HPDF_Fax3CodecState));
116 
117 	if (pData->tif_data == NULL) {
118 		return 1;
119 	}
120 
121 	sp = Fax3State(pData);
122     /* sp->rw_mode = pData->tif_mode; */
123 
124 	/*
125 	 * Override parent get/set field methods.
126 	 */
127 	sp->groupoptions = 0;
128 	sp->recvparams = 0;
129 	sp->subaddress = NULL;
130 	sp->faxdcs = NULL;
131 
132 	esp = EncoderState(pData);
133 	esp->refline = NULL;
134 	esp->runs = NULL;
135 
136 	return HPDF_OK;
137 }
138 
HPDF_FreeCCITTFax3(struct _HPDF_CCITT_Data * pData)139 static HPDF_STATUS HPDF_FreeCCITTFax3(struct _HPDF_CCITT_Data *pData)
140 {
141 	if(pData->tif_data!=NULL) {
142 		HPDF_Fax3CodecState* esp=pData->tif_data;
143 		if(esp->refline!=NULL) {
144 			free(esp->refline);
145 			esp->refline=NULL;
146 		}
147 		if(esp->runs!=NULL) {
148 			free(esp->runs);
149 			esp->runs=NULL;
150 		}
151 		free(pData->tif_data);
152 		pData->tif_data=NULL;
153 	}
154 	if(pData->tif_rawdata!=NULL) {
155 		free(pData->tif_rawdata);
156 		pData->tif_rawdata=NULL;
157 	}
158 	return HPDF_OK;
159 }
160 
161 
162 /*
163  * Setup G3/G4-related compression/decompression state
164  * before data is processed.  This routine is called once
165  * per image -- it sets up different state based on whether
166  * or not decoding or encoding is being done and whether
167  * 1D- or 2D-encoded data is involved.
168  */
169 static int
HPDF_Fax3SetupState(struct _HPDF_CCITT_Data * pData,HPDF_UINT width,HPDF_UINT height,HPDF_UINT line_width)170 HPDF_Fax3SetupState(struct _HPDF_CCITT_Data *pData, HPDF_UINT          width,
171 							HPDF_UINT          height,
172 							HPDF_UINT          line_width)
173 {
174 	HPDF_Fax3BaseState* sp = Fax3State(pData);
175 	HPDF_Fax3CodecState* esp = EncoderState(pData);
176 	uint32 rowbytes, rowpixels, nruns;
177 
178 	HPDF_UNUSED (height);
179 
180 	rowbytes = line_width;
181 	rowpixels = width;
182 
183 	sp->rowbytes = (uint32) rowbytes;
184 	sp->rowpixels = (uint32) rowpixels;
185 
186 	nruns = 2*TIFFroundup(rowpixels,32);
187 	nruns += 3;
188 	esp->runs = (uint32*) malloc(2*nruns * sizeof (uint32));
189 	if (esp->runs == NULL)
190 		return 1;
191 	esp->curruns = esp->runs;
192 	esp->refruns = esp->runs + nruns;
193 
194 	/*
195 	 * 2d encoding requires a scanline
196 	 * buffer for the ``reference line''; the
197 	 * scanline against which delta encoding
198 	 * is referenced.  The reference line must
199 	 * be initialized to be ``white'' (done elsewhere).
200 	 */
201 	esp->refline = (unsigned char*) malloc(rowbytes);
202 	if (esp->refline == NULL) {
203 		return 1;
204 	}
205 
206 	return HPDF_OK;
207 }
208 
209 /*
210  * Reset encoding state at the start of a strip.
211  */
212 static HPDF_STATUS
HPDF_Fax3PreEncode(struct _HPDF_CCITT_Data * pData)213 HPDF_Fax3PreEncode(struct _HPDF_CCITT_Data *pData/*, tsample_t s*/)
214 {
215 	HPDF_Fax3CodecState* sp = EncoderState(pData);
216 
217 	/* assert(sp != NULL); */
218 	sp->bit = 8;
219 	sp->data = 0;
220 	/* sp->tag = G3_1D; */
221 	/*
222 	 * This is necessary for Group 4; otherwise it isn't
223 	 * needed because the first scanline of each strip ends
224 	 * up being copied into the refline.
225 	 */
226 	if (sp->refline)
227 		memset(sp->refline, 0x00, sp->b.rowbytes);
228 	sp->k = sp->maxk = 0;
229 	sp->line = 0;
230 	return HPDF_OK;
231 }
232 
233 static HPDF_STATUS
HPDF_CCITT_AppendToStream(HPDF_Stream dst,tidata_t tif_rawdata,tsize_t tif_rawcc)234 HPDF_CCITT_AppendToStream(HPDF_Stream  dst,
235 						  tidata_t	tif_rawdata,
236 						  tsize_t	tif_rawcc)
237 {
238 	if(HPDF_Stream_Write(dst, tif_rawdata, tif_rawcc)!=HPDF_OK)
239 		return 1;
240 	return HPDF_OK;
241 }
242 
243 /*
244  * Internal version of TIFFFlushData that can be
245  * called by ``encodestrip routines'' w/o concern
246  * for infinite recursion.
247  */
248 static HPDF_STATUS
HPDF_CCITT_FlushData(struct _HPDF_CCITT_Data * pData)249 HPDF_CCITT_FlushData(struct _HPDF_CCITT_Data *pData)
250 {
251 	if (pData->tif_rawcc > 0) {
252 		/*if (!isFillOrder(tif, tif->tif_dir.td_fillorder) &&
253 		    (tif->tif_flags & TIFF_NOBITREV) == 0)
254 			TIFFReverseBits((unsigned char *pData->tif_rawdata,
255 			    pData->tif_rawcc);*/
256 		if (HPDF_CCITT_AppendToStream(pData->dst,
257 		    pData->tif_rawdata, pData->tif_rawcc)!=HPDF_OK)
258 			return 1;
259 		pData->tif_rawcc = 0;
260 		pData->tif_rawcp = pData->tif_rawdata;
261 	}
262 	return HPDF_OK;
263 }
264 
265 #define	HPDF_Fax3FlushBits(tif, sp) {				\
266 	if ((tif)->tif_rawcc >= (tif)->tif_rawdatasize)		\
267 		(void) HPDF_CCITT_FlushData(tif);			\
268 	*(tif)->tif_rawcp++ = (tidataval_t) (sp)->data;		\
269 	(tif)->tif_rawcc++;					\
270 	(sp)->data = 0, (sp)->bit = 8;				\
271 }
272 #define	_FlushBits(tif) {					\
273 	if ((tif)->tif_rawcc >= (tif)->tif_rawdatasize)		\
274 		(void) HPDF_CCITT_FlushData(tif);			\
275 	*(tif)->tif_rawcp++ = (tidataval_t) data;		\
276 	(tif)->tif_rawcc++;					\
277 	data = 0, bit = 8;					\
278 }
279 static const int _msbmask[9] =
280     { 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff };
281 #define	_PutBits(tif, bits, length) {				\
282 	while (length > bit) {					\
283 		data |= bits >> (length - bit);			\
284 		length -= bit;					\
285 		_FlushBits(tif);				\
286 	}							\
287 	data |= (bits & _msbmask[length]) << (bit - length);	\
288 	bit -= length;						\
289 	if (bit == 0)						\
290 		_FlushBits(tif);				\
291 }
292 
293 /*
294  * Write a variable-length bit-value to
295  * the output stream.  Values are
296  * assumed to be at most 16 bits.
297  */
298 static void
HPDF_Fax3PutBits(struct _HPDF_CCITT_Data * pData,unsigned int bits,unsigned int length)299 HPDF_Fax3PutBits(struct _HPDF_CCITT_Data *pData, unsigned int bits, unsigned int length)
300 {
301 	HPDF_Fax3CodecState* sp = EncoderState(pData);
302 	unsigned int bit = sp->bit;
303 	int data = sp->data;
304 
305 	_PutBits(pData, bits, length);
306 
307 	sp->data = data;
308 	sp->bit = bit;
309 }
310 
311 /*
312  * Write a code to the output stream.
313  */
314 #define putcode(tif, te)	HPDF_Fax3PutBits(tif, (te)->code, (te)->length)
315 
316 
317 /*
318  * Write the sequence of codes that describes
319  * the specified span of zero's or one's.  The
320  * appropriate table that holds the make-up and
321  * terminating codes is supplied.
322  */
323 static void
putspan(struct _HPDF_CCITT_Data * pData,int32 span,const tableentry * tab)324 putspan(struct _HPDF_CCITT_Data *pData, int32 span, const tableentry* tab)
325 {
326 	HPDF_Fax3CodecState* sp = EncoderState(pData);
327 	unsigned int bit = sp->bit;
328 	int data = sp->data;
329 	unsigned int code, length;
330 
331 	while (span >= 2624) {
332 		const tableentry* te = &tab[63 + (2560>>6)];
333 		code = te->code, length = te->length;
334 #ifdef FAX3_DEBUG
335 		DEBUG_PRINT("MakeUp", te->runlen);
336 #endif
337 		_PutBits(pData, code, length);
338 		span -= te->runlen;
339 	}
340 	if (span >= 64) {
341 		const tableentry* te = &tab[63 + (span>>6)];
342 		assert(te->runlen == 64*(span>>6));
343 		code = te->code, length = te->length;
344 #ifdef FAX3_DEBUG
345 		DEBUG_PRINT("MakeUp", te->runlen);
346 #endif
347 		_PutBits(pData, code, length);
348 		span -= te->runlen;
349 	}
350 	code = tab[span].code, length = tab[span].length;
351 #ifdef FAX3_DEBUG
352 	DEBUG_PRINT("  Term", tab[span].runlen);
353 #endif
354 	_PutBits(pData, code, length);
355 
356 	sp->data = data;
357 	sp->bit = bit;
358 }
359 
360 static const unsigned char zeroruns[256] = {
361     8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,	/* 0x00 - 0x0f */
362     3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,	/* 0x10 - 0x1f */
363     2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,	/* 0x20 - 0x2f */
364     2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,	/* 0x30 - 0x3f */
365     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,	/* 0x40 - 0x4f */
366     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,	/* 0x50 - 0x5f */
367     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,	/* 0x60 - 0x6f */
368     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,	/* 0x70 - 0x7f */
369     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0x80 - 0x8f */
370     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0x90 - 0x9f */
371     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0xa0 - 0xaf */
372     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0xb0 - 0xbf */
373     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0xc0 - 0xcf */
374     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0xd0 - 0xdf */
375     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0xe0 - 0xef */
376     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0xf0 - 0xff */
377 };
378 static const unsigned char oneruns[256] = {
379     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0x00 - 0x0f */
380     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0x10 - 0x1f */
381     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0x20 - 0x2f */
382     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0x30 - 0x3f */
383     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0x40 - 0x4f */
384     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0x50 - 0x5f */
385     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0x60 - 0x6f */
386     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	/* 0x70 - 0x7f */
387     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,	/* 0x80 - 0x8f */
388     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,	/* 0x90 - 0x9f */
389     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,	/* 0xa0 - 0xaf */
390     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,	/* 0xb0 - 0xbf */
391     2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,	/* 0xc0 - 0xcf */
392     2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,	/* 0xd0 - 0xdf */
393     3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,	/* 0xe0 - 0xef */
394     4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 7, 8,	/* 0xf0 - 0xff */
395 };
396 
397 /*
398  * Find a span of ones or zeros using the supplied
399  * table.  The ``base'' of the bit string is supplied
400  * along with the start+end bit indices.
401  */
find0span(unsigned char * bp,int32 bs,int32 be)402 static /*inline*/ int32 find0span(unsigned char* bp, int32 bs, int32 be)
403 {
404 	int32 bits = be - bs;
405 	int32 n, span;
406 
407 	bp += bs>>3;
408 	/*
409 	 * Check partial byte on lhs.
410 	 */
411 	if (bits > 0 && (n = (bs & 7))) {
412 		span = zeroruns[(*bp << n) & 0xff];
413 		if (span > 8-n)		/* table value too generous */
414 			span = 8-n;
415 		if (span > bits)	/* constrain span to bit range */
416 			span = bits;
417 		if (n+span < 8)		/* doesn't extend to edge of byte */
418 			return (span);
419 		bits -= span;
420 		bp++;
421 	} else
422 		span = 0;
423 	if (bits >= (int32)(2 * 8 * sizeof(long))) {
424 		long* lp;
425 		/*
426 		 * Align to longword boundary and check longwords.
427 		 */
428 		while (!isAligned(bp, long)) {
429 			if (*bp != 0x00)
430 				return (span + zeroruns[*bp]);
431 			span += 8, bits -= 8;
432 			bp++;
433 		}
434 		lp = (long*) bp;
435 		while ((bits >= (int32)(8 * sizeof(long))) && (0 == *lp)) {
436 			span += 8*sizeof (long), bits -= 8*sizeof (long);
437 			lp++;
438 		}
439 		bp = (unsigned char*) lp;
440 	}
441 	/*
442 	 * Scan full bytes for all 0's.
443 	 */
444 	while (bits >= 8) {
445 		if (*bp != 0x00)	/* end of run */
446 			return (span + zeroruns[*bp]);
447 		span += 8, bits -= 8;
448 		bp++;
449 	}
450 	/*
451 	 * Check partial byte on rhs.
452 	 */
453 	if (bits > 0) {
454 		n = zeroruns[*bp];
455 		span += (n > bits ? bits : n);
456 	}
457 	return (span);
458 }
459 
460 static /*inline*/ int32
find1span(unsigned char * bp,int32 bs,int32 be)461 find1span(unsigned char* bp, int32 bs, int32 be)
462 {
463 	int32 bits = be - bs;
464 	int32 n, span;
465 
466 	bp += bs>>3;
467 	/*
468 	 * Check partial byte on lhs.
469 	 */
470 	if (bits > 0 && (n = (bs & 7))) {
471 		span = oneruns[(*bp << n) & 0xff];
472 		if (span > 8-n)		/* table value too generous */
473 			span = 8-n;
474 		if (span > bits)	/* constrain span to bit range */
475 			span = bits;
476 		if (n+span < 8)		/* doesn't extend to edge of byte */
477 			return (span);
478 		bits -= span;
479 		bp++;
480 	} else
481 		span = 0;
482 	if (bits >= (int32)(2 * 8 * sizeof(long))) {
483 		long* lp;
484 		/*
485 		 * Align to longword boundary and check longwords.
486 		 */
487 		while (!isAligned(bp, long)) {
488 			if (*bp != 0xff)
489 				return (span + oneruns[*bp]);
490 			span += 8, bits -= 8;
491 			bp++;
492 		}
493 		lp = (long*) bp;
494 		while ((bits >= (int32)(8 * sizeof(long))) && (~0 == *lp)) {
495 			span += 8*sizeof (long), bits -= 8*sizeof (long);
496 			lp++;
497 		}
498 		bp = (unsigned char*) lp;
499 	}
500 	/*
501 	 * Scan full bytes for all 1's.
502 	 */
503 	while (bits >= 8) {
504 		if (*bp != 0xff)	/* end of run */
505 			return (span + oneruns[*bp]);
506 		span += 8, bits -= 8;
507 		bp++;
508 	}
509 	/*
510 	 * Check partial byte on rhs.
511 	 */
512 	if (bits > 0) {
513 		n = oneruns[*bp];
514 		span += (n > bits ? bits : n);
515 	}
516 	return (span);
517 }
518 
519 /*
520  * Return the offset of the next bit in the range
521  * [bs..be] that is different from the specified
522  * color.  The end, be, is returned if no such bit
523  * exists.
524  */
525 #define	finddiff(_cp, _bs, _be, _color)	\
526 	(_bs + (_color ? find1span(_cp,_bs,_be) : find0span(_cp,_bs,_be)))
527 /*
528  * Like finddiff, but also check the starting bit
529  * against the end in case start > end.
530  */
531 #define	finddiff2(_cp, _bs, _be, _color) \
532 	(_bs < _be ? finddiff(_cp,_bs,_be,_color) : _be)
533 
534 
535 /*
536 void
537 HPDF_Fax3PostEncode(struct _HPDF_CCITT_Data *pData)
538 {
539 	HPDF_Fax3CodecState* sp = EncoderState(pData);
540 
541 	if (sp->bit != 8)
542 		HPDF_Fax3FlushBits(pData, sp);
543 }
544 */
545 
546 static const tableentry horizcode =
547     { 3, 0x1, 0 };	/* 001 */
548 static const tableentry passcode =
549     { 4, 0x1, 0 };	/* 0001 */
550 static const tableentry vcodes[7] = {
551     { 7, 0x03, 0 },	/* 0000 011 */
552     { 6, 0x03, 0 },	/* 0000 11 */
553     { 3, 0x03, 0 },	/* 011 */
554     { 1, 0x1, 0 },	/* 1 */
555     { 3, 0x2, 0 },	/* 010 */
556     { 6, 0x02, 0 },	/* 0000 10 */
557     { 7, 0x02, 0 }	/* 0000 010 */
558 };
559 
560 /*
561  * 2d-encode a row of pixels.  Consult the CCITT
562  * documentation for the algorithm.
563  */
564 static HPDF_STATUS
HPDF_Fax3Encode2DRow(struct _HPDF_CCITT_Data * pData,unsigned char * bp,unsigned char * rp,uint32 bits)565 HPDF_Fax3Encode2DRow(struct _HPDF_CCITT_Data *pData, unsigned char* bp, unsigned char* rp, uint32 bits)
566 {
567 #define	PIXEL(buf,ix)	((((buf)[(ix)>>3]) >> (7-((ix)&7))) & 1)
568         uint32 a0 = 0;
569 	uint32 a1 = (PIXEL(bp, 0) != 0 ? 0 : finddiff(bp, 0, bits, 0));
570 	uint32 b1 = (PIXEL(rp, 0) != 0 ? 0 : finddiff(rp, 0, bits, 0));
571 	uint32 a2, b2;
572 
573 	for (;;) {
574 		b2 = finddiff2(rp, b1, bits, PIXEL(rp,b1));
575 		if (b2 >= a1) {
576 			int32 d = b1 - a1;
577 			if (!(-3 <= d && d <= 3)) {	/* horizontal mode */
578 				a2 = finddiff2(bp, a1, bits, PIXEL(bp,a1));
579 				putcode(pData, &horizcode);
580 				if (a0+a1 == 0 || PIXEL(bp, a0) == 0) {
581 					putspan(pData, a1-a0, TIFFFaxWhiteCodes);
582 					putspan(pData, a2-a1, TIFFFaxBlackCodes);
583 				} else {
584 					putspan(pData, a1-a0, TIFFFaxBlackCodes);
585 					putspan(pData, a2-a1, TIFFFaxWhiteCodes);
586 				}
587 				a0 = a2;
588 			} else {			/* vertical mode */
589 				putcode(pData, &vcodes[d+3]);
590 				a0 = a1;
591 			}
592 		} else {				/* pass mode */
593 			putcode(pData, &passcode);
594 			a0 = b2;
595 		}
596 		if (a0 >= bits)
597 			break;
598 		a1 = finddiff(bp, a0, bits, PIXEL(bp,a0));
599 		b1 = finddiff(rp, a0, bits, !PIXEL(bp,a0));
600 		b1 = finddiff(rp, b1, bits, PIXEL(bp,a0));
601 	}
602 	return HPDF_OK;
603 #undef PIXEL
604 }
605 
606 /*
607  * Encode the requested amount of data.
608  */
609 static HPDF_STATUS
HPDF_Fax4Encode(struct _HPDF_CCITT_Data * pData,tidata_t bp,tsize_t cc)610 HPDF_Fax4Encode(struct _HPDF_CCITT_Data *pData, tidata_t bp, tsize_t cc/*, tsample_t s*/)
611 {
612 	HPDF_Fax3CodecState *sp = EncoderState(pData);
613 
614 	/* (void) s; */
615 	while ((long)cc > 0) {
616 		if (HPDF_Fax3Encode2DRow(pData, bp, sp->refline, sp->b.rowpixels)!=HPDF_OK)
617 			return 1;
618 		memcpy(sp->refline, bp, sp->b.rowbytes);
619 		bp += sp->b.rowbytes;
620 		cc -= sp->b.rowbytes;
621 	}
622 	return HPDF_OK;
623 }
624 
625 static void
HPDF_Fax4PostEncode(struct _HPDF_CCITT_Data * pData)626 HPDF_Fax4PostEncode(struct _HPDF_CCITT_Data *pData)
627 {
628 	/* HPDF_Fax3CodecState *sp = EncoderState(pData); */
629 
630 	/* terminate strip w/ EOFB */
631 	HPDF_Fax3PutBits(pData, EOL, 12);
632 	HPDF_Fax3PutBits(pData, EOL, 12);
633 	/*if (sp->bit != 8)
634 		HPDF_Fax3FlushBits(pData, sp);
635 		*/
636 	HPDF_CCITT_FlushData(pData);
637 }
638 
639 
640 
641 HPDF_STATUS
HPDF_Stream_CcittToStream(const HPDF_BYTE * buf,HPDF_Stream dst,HPDF_Encrypt e,HPDF_UINT width,HPDF_UINT height,HPDF_UINT line_width,HPDF_BOOL top_is_first)642 HPDF_Stream_CcittToStream( const HPDF_BYTE   *buf,
643                             HPDF_Stream  dst,
644 							HPDF_Encrypt  e,
645 							HPDF_UINT          width,
646 							HPDF_UINT          height,
647 							HPDF_UINT          line_width,
648 							HPDF_BOOL		   top_is_first)
649 {
650 	const HPDF_BYTE   *pBufPos;
651 	const HPDF_BYTE   *pBufEnd; /* end marker */
652 	int lineIncrement;
653 	struct _HPDF_CCITT_Data data;
654 
655 	HPDF_UNUSED (e);
656 
657 	if(height==0) return 1;
658 	if(top_is_first) {
659 		pBufPos = buf;
660 		pBufEnd=buf+(line_width*height);
661 		lineIncrement = line_width;
662 	} else {
663 		pBufPos = buf+(line_width*(height-1));
664 		pBufEnd= buf-line_width;
665 		lineIncrement = -((int)line_width);
666 	}
667 
668 	memset(&data, 0, sizeof(struct _HPDF_CCITT_Data));
669 	data.dst = dst;
670 	data.tif_rawdata = (tidata_t) malloc( 16384 ); /*  16 kb buffer */
671 	data.tif_rawdatasize = 16384;
672 	data.tif_rawcc = 0;
673 	data.tif_rawcp = data.tif_rawdata;
674 
675 	if(HPDF_InitCCITTFax3(&data)!=HPDF_OK)
676 		return 1;
677 
678 	if(HPDF_Fax3SetupState(&data, width, height, line_width)!=HPDF_OK)
679 	{
680 		HPDF_FreeCCITTFax3(&data);
681 		return 1;
682 	}
683 
684 	if(HPDF_Fax3PreEncode(&data)!=HPDF_OK)
685 	{
686 		HPDF_FreeCCITTFax3(&data);
687 		return 1;
688 	}
689 
690 	/*  encode data */
691 	while(pBufEnd!=pBufPos)
692 	{
693 		HPDF_Fax4Encode(&data, (tidata_t)pBufPos, line_width);
694 		pBufPos+=lineIncrement;
695 	}
696 
697 	HPDF_Fax4PostEncode(&data);
698 
699 	HPDF_FreeCCITTFax3(&data);
700 
701 	return HPDF_OK;
702 }
703 
704 HPDF_Image
HPDF_Image_Load1BitImageFromMem(HPDF_MMgr mmgr,const HPDF_BYTE * buf,HPDF_Xref xref,HPDF_UINT width,HPDF_UINT height,HPDF_UINT line_width,HPDF_BOOL top_is_first)705 HPDF_Image_Load1BitImageFromMem  (HPDF_MMgr        mmgr,
706                           const HPDF_BYTE   *buf,
707                           HPDF_Xref        xref,
708                           HPDF_UINT          width,
709                           HPDF_UINT          height,
710 						  HPDF_UINT          line_width,
711 						  HPDF_BOOL			 top_is_first
712                           )
713 {
714     HPDF_Dict image;
715     HPDF_STATUS ret = HPDF_OK;
716     /* HPDF_UINT size; */
717 
718     HPDF_PTRACE ((" HPDF_Image_Load1BitImage\n"));
719 
720     image = HPDF_DictStream_New (mmgr, xref);
721     if (!image)
722         return NULL;
723 
724     image->header.obj_class |= HPDF_OSUBCLASS_XOBJECT;
725     ret += HPDF_Dict_AddName (image, "Type", "XObject");
726     ret += HPDF_Dict_AddName (image, "Subtype", "Image");
727     if (ret != HPDF_OK)
728         return NULL;
729 
730     /* size = width * height; */
731     ret = HPDF_Dict_AddName (image, "ColorSpace", "DeviceGray");
732     if (ret != HPDF_OK)
733         return NULL;
734 
735     if (HPDF_Dict_AddNumber (image, "Width", width) != HPDF_OK)
736         return NULL;
737 
738     if (HPDF_Dict_AddNumber (image, "Height", height) != HPDF_OK)
739         return NULL;
740 
741     if (HPDF_Dict_AddNumber (image, "BitsPerComponent", 1) != HPDF_OK)
742         return NULL;
743 
744     if (HPDF_Stream_CcittToStream (buf, image->stream, NULL, width, height, line_width, top_is_first) != HPDF_OK)
745         return NULL;
746 
747     return image;
748 }
749 
750 /*
751  * Load image from buffer
752  * line_width - width of the line in bytes
753  * top_is_first - image orientation:
754  *      TRUE if image is oriented TOP-BOTTOM;
755  *      FALSE if image is oriented BOTTOM-TOP
756  */
757 HPDF_EXPORT(HPDF_Image)
HPDF_Image_LoadRaw1BitImageFromMem(HPDF_Doc pdf,const HPDF_BYTE * buf,HPDF_UINT width,HPDF_UINT height,HPDF_UINT line_width,HPDF_BOOL black_is1,HPDF_BOOL top_is_first)758 HPDF_Image_LoadRaw1BitImageFromMem  (HPDF_Doc           pdf,
759                            const HPDF_BYTE   *buf,
760                           HPDF_UINT          width,
761                           HPDF_UINT          height,
762 						  HPDF_UINT          line_width,
763 						  HPDF_BOOL          black_is1,
764 						  HPDF_BOOL			 top_is_first)
765 {
766     HPDF_Image image;
767 
768     HPDF_PTRACE ((" HPDF_Image_Load1BitImageFromMem\n"));
769 
770     if (!HPDF_HasDoc (pdf))
771         return NULL;
772 
773     image = HPDF_Image_Load1BitImageFromMem(pdf->mmgr, buf, pdf->xref, width,
774                 height, line_width, top_is_first);
775 
776     if (!image)
777         HPDF_CheckError (&pdf->error);
778 
779     if (pdf->compression_mode & HPDF_COMP_IMAGE)
780 	{
781 		image->filter = HPDF_STREAM_FILTER_CCITT_DECODE;
782 		image->filterParams = HPDF_Dict_New(pdf->mmgr);
783 		if(image->filterParams==NULL) {
784 			return NULL;
785 		}
786 
787 		/* pure 2D encoding, default is 0 */
788 		HPDF_Dict_AddNumber (image->filterParams, "K", -1);
789 		/* default is 1728 */
790 		HPDF_Dict_AddNumber (image->filterParams, "Columns", width);
791 		/* default is 0 */
792 		HPDF_Dict_AddNumber (image->filterParams, "Rows", height);
793 		HPDF_Dict_AddBoolean (image->filterParams, "BlackIs1", black_is1);
794 	}
795 
796     return image;
797 }
798