OSDN Git Service

binding with libharu.
[putex/putex.git] / src / texsourc / lib / libhpdf / src / hpdf_image_ccitt.c
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
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
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
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         rowbytes = line_width;
179         rowpixels = width;
180
181         sp->rowbytes = (uint32) rowbytes;
182         sp->rowpixels = (uint32) rowpixels;
183
184         nruns = 2*TIFFroundup(rowpixels,32);
185         nruns += 3;
186         esp->runs = (uint32*) malloc(2*nruns * sizeof (uint32));
187         if (esp->runs == NULL)
188                 return 1;
189         esp->curruns = esp->runs;
190         esp->refruns = esp->runs + nruns;
191
192         /*
193          * 2d encoding requires a scanline
194          * buffer for the ``reference line''; the
195          * scanline against which delta encoding
196          * is referenced.  The reference line must
197          * be initialized to be ``white'' (done elsewhere).
198          */
199         esp->refline = (unsigned char*) malloc(rowbytes);
200         if (esp->refline == NULL) {
201                 return 1;
202         }
203
204         return HPDF_OK;
205 }
206
207 /*
208  * Reset encoding state at the start of a strip.
209  */
210 static HPDF_STATUS 
211 HPDF_Fax3PreEncode(struct _HPDF_CCITT_Data *pData/*, tsample_t s*/)
212 {
213         HPDF_Fax3CodecState* sp = EncoderState(pData);
214
215         /* assert(sp != NULL); */
216         sp->bit = 8;
217         sp->data = 0;
218         /* sp->tag = G3_1D; */
219         /*
220          * This is necessary for Group 4; otherwise it isn't
221          * needed because the first scanline of each strip ends
222          * up being copied into the refline.
223          */
224         if (sp->refline)
225                 memset(sp->refline, 0x00, sp->b.rowbytes);
226         sp->k = sp->maxk = 0;
227         sp->line = 0;
228         return HPDF_OK;
229 }
230
231 static HPDF_STATUS 
232 HPDF_CCITT_AppendToStream(HPDF_Stream  dst,     
233                                                   tidata_t      tif_rawdata,
234                                                   tsize_t       tif_rawcc)
235 {
236         if(HPDF_Stream_Write(dst, tif_rawdata, tif_rawcc)!=HPDF_OK)
237                 return 1;
238         return HPDF_OK;
239 }
240
241 /*
242  * Internal version of TIFFFlushData that can be
243  * called by ``encodestrip routines'' w/o concern
244  * for infinite recursion.
245  */
246 static HPDF_STATUS 
247 HPDF_CCITT_FlushData(struct _HPDF_CCITT_Data *pData)
248 {
249         if (pData->tif_rawcc > 0) {
250                 /*if (!isFillOrder(tif, tif->tif_dir.td_fillorder) &&
251                     (tif->tif_flags & TIFF_NOBITREV) == 0)
252                         TIFFReverseBits((unsigned char *pData->tif_rawdata,
253                             pData->tif_rawcc);*/
254                 if (HPDF_CCITT_AppendToStream(pData->dst,
255                     pData->tif_rawdata, pData->tif_rawcc)!=HPDF_OK)
256                         return 1;
257                 pData->tif_rawcc = 0;
258                 pData->tif_rawcp = pData->tif_rawdata;
259         }
260         return HPDF_OK;
261 }
262
263 #define HPDF_Fax3FlushBits(tif, sp) {                           \
264         if ((tif)->tif_rawcc >= (tif)->tif_rawdatasize)         \
265                 (void) HPDF_CCITT_FlushData(tif);                       \
266         *(tif)->tif_rawcp++ = (tidataval_t) (sp)->data;         \
267         (tif)->tif_rawcc++;                                     \
268         (sp)->data = 0, (sp)->bit = 8;                          \
269 }
270 #define _FlushBits(tif) {                                       \
271         if ((tif)->tif_rawcc >= (tif)->tif_rawdatasize)         \
272                 (void) HPDF_CCITT_FlushData(tif);                       \
273         *(tif)->tif_rawcp++ = (tidataval_t) data;               \
274         (tif)->tif_rawcc++;                                     \
275         data = 0, bit = 8;                                      \
276 }
277 static const int _msbmask[9] =
278     { 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff };
279 #define _PutBits(tif, bits, length) {                           \
280         while (length > bit) {                                  \
281                 data |= bits >> (length - bit);                 \
282                 length -= bit;                                  \
283                 _FlushBits(tif);                                \
284         }                                                       \
285         data |= (bits & _msbmask[length]) << (bit - length);    \
286         bit -= length;                                          \
287         if (bit == 0)                                           \
288                 _FlushBits(tif);                                \
289 }
290
291 /*
292  * Write a variable-length bit-value to
293  * the output stream.  Values are
294  * assumed to be at most 16 bits.
295  */
296 static void
297 HPDF_Fax3PutBits(struct _HPDF_CCITT_Data *pData, unsigned int bits, unsigned int length)
298 {
299         HPDF_Fax3CodecState* sp = EncoderState(pData);
300         unsigned int bit = sp->bit;
301         int data = sp->data;
302
303         _PutBits(pData, bits, length);
304
305         sp->data = data;
306         sp->bit = bit;
307 }
308
309 /*
310  * Write a code to the output stream.
311  */
312 #define putcode(tif, te)        HPDF_Fax3PutBits(tif, (te)->code, (te)->length)
313
314
315 /*
316  * Write the sequence of codes that describes
317  * the specified span of zero's or one's.  The
318  * appropriate table that holds the make-up and
319  * terminating codes is supplied.
320  */
321 static void
322 putspan(struct _HPDF_CCITT_Data *pData, int32 span, const tableentry* tab)
323 {
324         HPDF_Fax3CodecState* sp = EncoderState(pData);
325         unsigned int bit = sp->bit;
326         int data = sp->data;
327         unsigned int code, length;
328
329         while (span >= 2624) {
330                 const tableentry* te = &tab[63 + (2560>>6)];
331                 code = te->code, length = te->length;
332 #ifdef FAX3_DEBUG
333                 DEBUG_PRINT("MakeUp", te->runlen);
334 #endif
335                 _PutBits(pData, code, length);
336                 span -= te->runlen;
337         }
338         if (span >= 64) {
339                 const tableentry* te = &tab[63 + (span>>6)];
340                 assert(te->runlen == 64*(span>>6));
341                 code = te->code, length = te->length;
342 #ifdef FAX3_DEBUG
343                 DEBUG_PRINT("MakeUp", te->runlen);
344 #endif
345                 _PutBits(pData, code, length);
346                 span -= te->runlen;
347         }
348         code = tab[span].code, length = tab[span].length;
349 #ifdef FAX3_DEBUG
350         DEBUG_PRINT("  Term", tab[span].runlen);
351 #endif
352         _PutBits(pData, code, length);
353
354         sp->data = data;
355         sp->bit = bit;
356 }
357
358 static const unsigned char zeroruns[256] = {
359     8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,     /* 0x00 - 0x0f */
360     3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,     /* 0x10 - 0x1f */
361     2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,     /* 0x20 - 0x2f */
362     2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,     /* 0x30 - 0x3f */
363     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,     /* 0x40 - 0x4f */
364     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,     /* 0x50 - 0x5f */
365     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,     /* 0x60 - 0x6f */
366     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,     /* 0x70 - 0x7f */
367     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,     /* 0x80 - 0x8f */
368     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,     /* 0x90 - 0x9f */
369     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,     /* 0xa0 - 0xaf */
370     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,     /* 0xb0 - 0xbf */
371     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,     /* 0xc0 - 0xcf */
372     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,     /* 0xd0 - 0xdf */
373     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,     /* 0xe0 - 0xef */
374     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,     /* 0xf0 - 0xff */
375 };
376 static const unsigned char oneruns[256] = {
377     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,     /* 0x00 - 0x0f */
378     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,     /* 0x10 - 0x1f */
379     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,     /* 0x20 - 0x2f */
380     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,     /* 0x30 - 0x3f */
381     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,     /* 0x40 - 0x4f */
382     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,     /* 0x50 - 0x5f */
383     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,     /* 0x60 - 0x6f */
384     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,     /* 0x70 - 0x7f */
385     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,     /* 0x80 - 0x8f */
386     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,     /* 0x90 - 0x9f */
387     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,     /* 0xa0 - 0xaf */
388     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,     /* 0xb0 - 0xbf */
389     2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,     /* 0xc0 - 0xcf */
390     2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,     /* 0xd0 - 0xdf */
391     3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,     /* 0xe0 - 0xef */
392     4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 7, 8,     /* 0xf0 - 0xff */
393 };
394
395 /*
396  * Find a span of ones or zeros using the supplied
397  * table.  The ``base'' of the bit string is supplied
398  * along with the start+end bit indices.
399  */
400 static /*inline*/ int32 find0span(unsigned char* bp, int32 bs, int32 be)
401 {
402         int32 bits = be - bs;
403         int32 n, span;
404
405         bp += bs>>3;
406         /*
407          * Check partial byte on lhs.
408          */
409         if (bits > 0 && (n = (bs & 7))) {
410                 span = zeroruns[(*bp << n) & 0xff];
411                 if (span > 8-n)         /* table value too generous */
412                         span = 8-n;
413                 if (span > bits)        /* constrain span to bit range */
414                         span = bits;
415                 if (n+span < 8)         /* doesn't extend to edge of byte */
416                         return (span);
417                 bits -= span;
418                 bp++;
419         } else
420                 span = 0;
421         if (bits >= (int32)(2 * 8 * sizeof(long))) {
422                 long* lp;
423                 /*
424                  * Align to longword boundary and check longwords.
425                  */
426                 while (!isAligned(bp, long)) {
427                         if (*bp != 0x00)
428                                 return (span + zeroruns[*bp]);
429                         span += 8, bits -= 8;
430                         bp++;
431                 }
432                 lp = (long*) bp;
433                 while ((bits >= (int32)(8 * sizeof(long))) && (0 == *lp)) {
434                         span += 8*sizeof (long), bits -= 8*sizeof (long);
435                         lp++;
436                 }
437                 bp = (unsigned char*) lp;
438         }
439         /*
440          * Scan full bytes for all 0's.
441          */
442         while (bits >= 8) {
443                 if (*bp != 0x00)        /* end of run */
444                         return (span + zeroruns[*bp]);
445                 span += 8, bits -= 8;
446                 bp++;
447         }
448         /*
449          * Check partial byte on rhs.
450          */
451         if (bits > 0) {
452                 n = zeroruns[*bp];
453                 span += (n > bits ? bits : n);
454         }
455         return (span);
456 }
457
458 static /*inline*/ int32
459 find1span(unsigned char* bp, int32 bs, int32 be)
460 {
461         int32 bits = be - bs;
462         int32 n, span;
463
464         bp += bs>>3;
465         /*
466          * Check partial byte on lhs.
467          */
468         if (bits > 0 && (n = (bs & 7))) {
469                 span = oneruns[(*bp << n) & 0xff];
470                 if (span > 8-n)         /* table value too generous */
471                         span = 8-n;
472                 if (span > bits)        /* constrain span to bit range */
473                         span = bits;
474                 if (n+span < 8)         /* doesn't extend to edge of byte */
475                         return (span);
476                 bits -= span;
477                 bp++;
478         } else
479                 span = 0;
480         if (bits >= (int32)(2 * 8 * sizeof(long))) {
481                 long* lp;
482                 /*
483                  * Align to longword boundary and check longwords.
484                  */
485                 while (!isAligned(bp, long)) {
486                         if (*bp != 0xff)
487                                 return (span + oneruns[*bp]);
488                         span += 8, bits -= 8;
489                         bp++;
490                 }
491                 lp = (long*) bp;
492                 while ((bits >= (int32)(8 * sizeof(long))) && (~0 == *lp)) {
493                         span += 8*sizeof (long), bits -= 8*sizeof (long);
494                         lp++;
495                 }
496                 bp = (unsigned char*) lp;
497         }
498         /*
499          * Scan full bytes for all 1's.
500          */
501         while (bits >= 8) {
502                 if (*bp != 0xff)        /* end of run */
503                         return (span + oneruns[*bp]);
504                 span += 8, bits -= 8;
505                 bp++;
506         }
507         /*
508          * Check partial byte on rhs.
509          */
510         if (bits > 0) {
511                 n = oneruns[*bp];
512                 span += (n > bits ? bits : n);
513         }
514         return (span);
515 }
516
517 /*
518  * Return the offset of the next bit in the range
519  * [bs..be] that is different from the specified
520  * color.  The end, be, is returned if no such bit
521  * exists.
522  */
523 #define finddiff(_cp, _bs, _be, _color) \
524         (_bs + (_color ? find1span(_cp,_bs,_be) : find0span(_cp,_bs,_be)))
525 /*
526  * Like finddiff, but also check the starting bit
527  * against the end in case start > end.
528  */
529 #define finddiff2(_cp, _bs, _be, _color) \
530         (_bs < _be ? finddiff(_cp,_bs,_be,_color) : _be)
531
532
533 /*
534 void 
535 HPDF_Fax3PostEncode(struct _HPDF_CCITT_Data *pData)
536 {
537         HPDF_Fax3CodecState* sp = EncoderState(pData);
538
539         if (sp->bit != 8)
540                 HPDF_Fax3FlushBits(pData, sp);
541 }
542 */
543
544 static const tableentry horizcode =
545     { 3, 0x1, 0 };      /* 001 */
546 static const tableentry passcode =
547     { 4, 0x1, 0 };      /* 0001 */
548 static const tableentry vcodes[7] = {
549     { 7, 0x03, 0 },     /* 0000 011 */
550     { 6, 0x03, 0 },     /* 0000 11 */
551     { 3, 0x03, 0 },     /* 011 */
552     { 1, 0x1, 0 },      /* 1 */
553     { 3, 0x2, 0 },      /* 010 */
554     { 6, 0x02, 0 },     /* 0000 10 */
555     { 7, 0x02, 0 }      /* 0000 010 */
556 };
557
558 /*
559  * 2d-encode a row of pixels.  Consult the CCITT
560  * documentation for the algorithm.
561  */
562 static HPDF_STATUS 
563 HPDF_Fax3Encode2DRow(struct _HPDF_CCITT_Data *pData, unsigned char* bp, unsigned char* rp, uint32 bits)
564 {
565 #define PIXEL(buf,ix)   ((((buf)[(ix)>>3]) >> (7-((ix)&7))) & 1)
566         uint32 a0 = 0;
567         uint32 a1 = (PIXEL(bp, 0) != 0 ? 0 : finddiff(bp, 0, bits, 0));
568         uint32 b1 = (PIXEL(rp, 0) != 0 ? 0 : finddiff(rp, 0, bits, 0));
569         uint32 a2, b2;
570
571         for (;;) {
572                 b2 = finddiff2(rp, b1, bits, PIXEL(rp,b1));
573                 if (b2 >= a1) {
574                         int32 d = b1 - a1;
575                         if (!(-3 <= d && d <= 3)) {     /* horizontal mode */
576                                 a2 = finddiff2(bp, a1, bits, PIXEL(bp,a1));
577                                 putcode(pData, &horizcode);
578                                 if (a0+a1 == 0 || PIXEL(bp, a0) == 0) {
579                                         putspan(pData, a1-a0, TIFFFaxWhiteCodes);
580                                         putspan(pData, a2-a1, TIFFFaxBlackCodes);
581                                 } else {
582                                         putspan(pData, a1-a0, TIFFFaxBlackCodes);
583                                         putspan(pData, a2-a1, TIFFFaxWhiteCodes);
584                                 }
585                                 a0 = a2;
586                         } else {                        /* vertical mode */
587                                 putcode(pData, &vcodes[d+3]);
588                                 a0 = a1;
589                         }
590                 } else {                                /* pass mode */
591                         putcode(pData, &passcode);
592                         a0 = b2;
593                 }
594                 if (a0 >= bits)
595                         break;
596                 a1 = finddiff(bp, a0, bits, PIXEL(bp,a0));
597                 b1 = finddiff(rp, a0, bits, !PIXEL(bp,a0));
598                 b1 = finddiff(rp, b1, bits, PIXEL(bp,a0));
599         }
600         return HPDF_OK;
601 #undef PIXEL
602 }
603
604 /*
605  * Encode the requested amount of data.
606  */
607 static HPDF_STATUS 
608 HPDF_Fax4Encode(struct _HPDF_CCITT_Data *pData, tidata_t bp, tsize_t cc/*, tsample_t s*/)
609 {
610         HPDF_Fax3CodecState *sp = EncoderState(pData);
611
612         /* (void) s; */
613         while ((long)cc > 0) {
614                 if (HPDF_Fax3Encode2DRow(pData, bp, sp->refline, sp->b.rowpixels)!=HPDF_OK)
615                         return 1;
616                 memcpy(sp->refline, bp, sp->b.rowbytes);
617                 bp += sp->b.rowbytes;
618                 cc -= sp->b.rowbytes;
619         }
620         return HPDF_OK;
621 }
622
623 static void
624 HPDF_Fax4PostEncode(struct _HPDF_CCITT_Data *pData)
625 {
626         /* HPDF_Fax3CodecState *sp = EncoderState(pData); */
627
628         /* terminate strip w/ EOFB */
629         HPDF_Fax3PutBits(pData, EOL, 12);
630         HPDF_Fax3PutBits(pData, EOL, 12);
631         /*if (sp->bit != 8)
632                 HPDF_Fax3FlushBits(pData, sp);  
633                 */
634         HPDF_CCITT_FlushData(pData);
635 }
636
637
638
639 HPDF_STATUS 
640 HPDF_Stream_CcittToStream( const HPDF_BYTE   *buf,
641                             HPDF_Stream  dst,
642                                                         HPDF_Encrypt  e,
643                                                         HPDF_UINT          width,
644                                                         HPDF_UINT          height,
645                                                         HPDF_UINT          line_width,
646                                                         HPDF_BOOL                  top_is_first)
647 {
648         const HPDF_BYTE   *pBufPos;
649         const HPDF_BYTE   *pBufEnd; /* end marker */
650         int lineIncrement;
651         struct _HPDF_CCITT_Data data;
652
653         if(height==0) return 1;
654         if(top_is_first) {
655                 pBufPos = buf;
656                 pBufEnd=buf+(line_width*height);
657                 lineIncrement = line_width;
658         } else {
659                 pBufPos = buf+(line_width*(height-1));
660                 pBufEnd= buf-line_width;
661                 lineIncrement = -((int)line_width);
662         }       
663
664         memset(&data, 0, sizeof(struct _HPDF_CCITT_Data));
665         data.dst = dst;
666         data.tif_rawdata = (tidata_t) malloc( 16384 ); /*  16 kb buffer */
667         data.tif_rawdatasize = 16384;
668         data.tif_rawcc = 0;
669         data.tif_rawcp = data.tif_rawdata;
670
671         if(HPDF_InitCCITTFax3(&data)!=HPDF_OK)
672                 return 1;
673
674         if(HPDF_Fax3SetupState(&data, width, height, line_width)!=HPDF_OK)
675         {
676                 HPDF_FreeCCITTFax3(&data);
677                 return 1;
678         }
679
680         if(HPDF_Fax3PreEncode(&data)!=HPDF_OK)
681         {
682                 HPDF_FreeCCITTFax3(&data);
683                 return 1;
684         }
685
686         /*  encode data */
687         while(pBufEnd!=pBufPos)
688         {
689                 HPDF_Fax4Encode(&data, (tidata_t)pBufPos, line_width);
690                 pBufPos+=lineIncrement;
691         }
692
693         HPDF_Fax4PostEncode(&data);
694
695         HPDF_FreeCCITTFax3(&data);
696
697         return HPDF_OK;
698 }
699
700 HPDF_Image
701 HPDF_Image_Load1BitImageFromMem  (HPDF_MMgr        mmgr,
702                           const HPDF_BYTE   *buf,
703                           HPDF_Xref        xref,
704                           HPDF_UINT          width,
705                           HPDF_UINT          height,
706                                                   HPDF_UINT          line_width,
707                                                   HPDF_BOOL                      top_is_first
708                           )
709 {
710     HPDF_Dict image;
711     HPDF_STATUS ret = HPDF_OK;
712     /* HPDF_UINT size; */
713
714     HPDF_PTRACE ((" HPDF_Image_Load1BitImage\n"));
715
716     image = HPDF_DictStream_New (mmgr, xref);
717     if (!image)
718         return NULL;
719
720     image->header.obj_class |= HPDF_OSUBCLASS_XOBJECT;
721     ret += HPDF_Dict_AddName (image, "Type", "XObject");
722     ret += HPDF_Dict_AddName (image, "Subtype", "Image");
723     if (ret != HPDF_OK)
724         return NULL;
725
726     /* size = width * height; */
727     ret = HPDF_Dict_AddName (image, "ColorSpace", "DeviceGray");
728     if (ret != HPDF_OK)
729         return NULL;
730
731     if (HPDF_Dict_AddNumber (image, "Width", width) != HPDF_OK)
732         return NULL;
733
734     if (HPDF_Dict_AddNumber (image, "Height", height) != HPDF_OK)
735         return NULL;
736
737     if (HPDF_Dict_AddNumber (image, "BitsPerComponent", 1) != HPDF_OK)
738         return NULL;
739
740     if (HPDF_Stream_CcittToStream (buf, image->stream, NULL, width, height, line_width, top_is_first) != HPDF_OK)
741         return NULL;
742
743     return image;
744 }
745
746 /*
747  * Load image from buffer
748  * line_width - width of the line in bytes
749  * top_is_first - image orientation: 
750  *      TRUE if image is oriented TOP-BOTTOM;
751  *      FALSE if image is oriented BOTTOM-TOP
752  */
753 HPDF_Image
754 HPDF_Image_LoadRaw1BitImageFromMem  (HPDF_Doc           pdf,
755                            const HPDF_BYTE   *buf,
756                           HPDF_UINT          width,
757                           HPDF_UINT          height,
758                                                   HPDF_UINT          line_width,
759                                                   HPDF_BOOL          black_is1,
760                                                   HPDF_BOOL                      top_is_first)
761 {
762     HPDF_Image image;
763
764     HPDF_PTRACE ((" HPDF_Image_Load1BitImageFromMem\n"));
765
766     if (!HPDF_HasDoc (pdf))
767         return NULL;
768
769     image = HPDF_Image_Load1BitImageFromMem(pdf->mmgr, buf, pdf->xref, width,
770                 height, line_width, top_is_first);
771
772     if (!image)
773         HPDF_CheckError (&pdf->error);
774
775     if (pdf->compression_mode & HPDF_COMP_IMAGE)
776         {
777                 image->filter = HPDF_STREAM_FILTER_CCITT_DECODE;
778                 image->filterParams = HPDF_Dict_New(pdf->mmgr);
779                 if(image->filterParams==NULL) {
780                         return NULL;
781                 }
782                 
783                 /* pure 2D encoding, default is 0 */
784                 HPDF_Dict_AddNumber (image->filterParams, "K", -1);
785                 /* default is 1728 */
786                 HPDF_Dict_AddNumber (image->filterParams, "Columns", width);
787                 /* default is 0 */
788                 HPDF_Dict_AddNumber (image->filterParams, "Rows", height);
789                 HPDF_Dict_AddBoolean (image->filterParams, "BlackIs1", black_is1);
790         }
791
792     return image;
793 }