2 * << Haru Free PDF Library >> -- hpdf_image.c
4 * URL: http://libharu.org
6 * Copyright (c) 1999-2006 Takeshi Kanno <takeshi_kanno@est.hi-ho.ne.jp>
7 * Copyright (c) 2007-2009 Antony Dovgal <tony@daylessday.org>
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.
18 #include "hpdf_conf.h"
19 #include "hpdf_utils.h"
27 typedef unsigned int uint32;
29 typedef unsigned short uint16;
30 typedef int32 tsize_t; /* i/o size in bytes */
32 * Typedefs for ``method pointers'' used internally.
34 typedef unsigned char tidataval_t; /* internal image data value type */
35 typedef tidataval_t* tidata_t; /* reference to internal image data */
38 * Compression+decompression state blocks are
39 * derived from this ``base state'' block.
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 */
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 */
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 */
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 */
77 } HPDF_Fax3CodecState;
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)
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))
90 struct _HPDF_CCITT_Encoder {
94 struct _HPDF_CCITT_Data {
95 HPDF_Fax3CodecState *tif_data;
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 */
106 static HPDF_STATUS HPDF_InitCCITTFax3(struct _HPDF_CCITT_Data *pData)
108 HPDF_Fax3BaseState* sp;
109 HPDF_Fax3CodecState* esp;
112 * Allocate state block so tag methods have storage to record values.
114 pData->tif_data = (HPDF_Fax3CodecState *)
115 malloc(sizeof (HPDF_Fax3CodecState));
117 if (pData->tif_data == NULL) {
121 sp = Fax3State(pData);
122 /* sp->rw_mode = pData->tif_mode; */
125 * Override parent get/set field methods.
127 sp->groupoptions = 0;
129 sp->subaddress = NULL;
132 esp = EncoderState(pData);
139 static HPDF_STATUS HPDF_FreeCCITTFax3(struct _HPDF_CCITT_Data *pData)
141 if(pData->tif_data!=NULL) {
142 HPDF_Fax3CodecState* esp=pData->tif_data;
143 if(esp->refline!=NULL) {
147 if(esp->runs!=NULL) {
151 free(pData->tif_data);
152 pData->tif_data=NULL;
154 if(pData->tif_rawdata!=NULL) {
155 free(pData->tif_rawdata);
156 pData->tif_rawdata=NULL;
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.
170 HPDF_Fax3SetupState(struct _HPDF_CCITT_Data *pData, HPDF_UINT width,
172 HPDF_UINT line_width)
174 HPDF_Fax3BaseState* sp = Fax3State(pData);
175 HPDF_Fax3CodecState* esp = EncoderState(pData);
176 uint32 rowbytes, rowpixels, nruns;
178 rowbytes = line_width;
181 sp->rowbytes = (uint32) rowbytes;
182 sp->rowpixels = (uint32) rowpixels;
184 nruns = 2*TIFFroundup(rowpixels,32);
186 esp->runs = (uint32*) malloc(2*nruns * sizeof (uint32));
187 if (esp->runs == NULL)
189 esp->curruns = esp->runs;
190 esp->refruns = esp->runs + nruns;
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).
199 esp->refline = (unsigned char*) malloc(rowbytes);
200 if (esp->refline == NULL) {
208 * Reset encoding state at the start of a strip.
211 HPDF_Fax3PreEncode(struct _HPDF_CCITT_Data *pData/*, tsample_t s*/)
213 HPDF_Fax3CodecState* sp = EncoderState(pData);
215 /* assert(sp != NULL); */
218 /* sp->tag = G3_1D; */
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.
225 memset(sp->refline, 0x00, sp->b.rowbytes);
226 sp->k = sp->maxk = 0;
232 HPDF_CCITT_AppendToStream(HPDF_Stream dst,
233 tidata_t tif_rawdata,
236 if(HPDF_Stream_Write(dst, tif_rawdata, tif_rawcc)!=HPDF_OK)
242 * Internal version of TIFFFlushData that can be
243 * called by ``encodestrip routines'' w/o concern
244 * for infinite recursion.
247 HPDF_CCITT_FlushData(struct _HPDF_CCITT_Data *pData)
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,
254 if (HPDF_CCITT_AppendToStream(pData->dst,
255 pData->tif_rawdata, pData->tif_rawcc)!=HPDF_OK)
257 pData->tif_rawcc = 0;
258 pData->tif_rawcp = pData->tif_rawdata;
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; \
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++; \
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); \
285 data |= (bits & _msbmask[length]) << (bit - length); \
292 * Write a variable-length bit-value to
293 * the output stream. Values are
294 * assumed to be at most 16 bits.
297 HPDF_Fax3PutBits(struct _HPDF_CCITT_Data *pData, unsigned int bits, unsigned int length)
299 HPDF_Fax3CodecState* sp = EncoderState(pData);
300 unsigned int bit = sp->bit;
303 _PutBits(pData, bits, length);
310 * Write a code to the output stream.
312 #define putcode(tif, te) HPDF_Fax3PutBits(tif, (te)->code, (te)->length)
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.
322 putspan(struct _HPDF_CCITT_Data *pData, int32 span, const tableentry* tab)
324 HPDF_Fax3CodecState* sp = EncoderState(pData);
325 unsigned int bit = sp->bit;
327 unsigned int code, length;
329 while (span >= 2624) {
330 const tableentry* te = &tab[63 + (2560>>6)];
331 code = te->code, length = te->length;
333 DEBUG_PRINT("MakeUp", te->runlen);
335 _PutBits(pData, code, length);
339 const tableentry* te = &tab[63 + (span>>6)];
340 assert(te->runlen == 64*(span>>6));
341 code = te->code, length = te->length;
343 DEBUG_PRINT("MakeUp", te->runlen);
345 _PutBits(pData, code, length);
348 code = tab[span].code, length = tab[span].length;
350 DEBUG_PRINT(" Term", tab[span].runlen);
352 _PutBits(pData, code, length);
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 */
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 */
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.
400 static /*inline*/ int32 find0span(unsigned char* bp, int32 bs, int32 be)
402 int32 bits = be - bs;
407 * Check partial byte on lhs.
409 if (bits > 0 && (n = (bs & 7))) {
410 span = zeroruns[(*bp << n) & 0xff];
411 if (span > 8-n) /* table value too generous */
413 if (span > bits) /* constrain span to bit range */
415 if (n+span < 8) /* doesn't extend to edge of byte */
421 if (bits >= (int32)(2 * 8 * sizeof(long))) {
424 * Align to longword boundary and check longwords.
426 while (!isAligned(bp, long)) {
428 return (span + zeroruns[*bp]);
429 span += 8, bits -= 8;
433 while ((bits >= (int32)(8 * sizeof(long))) && (0 == *lp)) {
434 span += 8*sizeof (long), bits -= 8*sizeof (long);
437 bp = (unsigned char*) lp;
440 * Scan full bytes for all 0's.
443 if (*bp != 0x00) /* end of run */
444 return (span + zeroruns[*bp]);
445 span += 8, bits -= 8;
449 * Check partial byte on rhs.
453 span += (n > bits ? bits : n);
458 static /*inline*/ int32
459 find1span(unsigned char* bp, int32 bs, int32 be)
461 int32 bits = be - bs;
466 * Check partial byte on lhs.
468 if (bits > 0 && (n = (bs & 7))) {
469 span = oneruns[(*bp << n) & 0xff];
470 if (span > 8-n) /* table value too generous */
472 if (span > bits) /* constrain span to bit range */
474 if (n+span < 8) /* doesn't extend to edge of byte */
480 if (bits >= (int32)(2 * 8 * sizeof(long))) {
483 * Align to longword boundary and check longwords.
485 while (!isAligned(bp, long)) {
487 return (span + oneruns[*bp]);
488 span += 8, bits -= 8;
492 while ((bits >= (int32)(8 * sizeof(long))) && (~0 == *lp)) {
493 span += 8*sizeof (long), bits -= 8*sizeof (long);
496 bp = (unsigned char*) lp;
499 * Scan full bytes for all 1's.
502 if (*bp != 0xff) /* end of run */
503 return (span + oneruns[*bp]);
504 span += 8, bits -= 8;
508 * Check partial byte on rhs.
512 span += (n > bits ? bits : n);
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
523 #define finddiff(_cp, _bs, _be, _color) \
524 (_bs + (_color ? find1span(_cp,_bs,_be) : find0span(_cp,_bs,_be)))
526 * Like finddiff, but also check the starting bit
527 * against the end in case start > end.
529 #define finddiff2(_cp, _bs, _be, _color) \
530 (_bs < _be ? finddiff(_cp,_bs,_be,_color) : _be)
535 HPDF_Fax3PostEncode(struct _HPDF_CCITT_Data *pData)
537 HPDF_Fax3CodecState* sp = EncoderState(pData);
540 HPDF_Fax3FlushBits(pData, sp);
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 */
559 * 2d-encode a row of pixels. Consult the CCITT
560 * documentation for the algorithm.
563 HPDF_Fax3Encode2DRow(struct _HPDF_CCITT_Data *pData, unsigned char* bp, unsigned char* rp, uint32 bits)
565 #define PIXEL(buf,ix) ((((buf)[(ix)>>3]) >> (7-((ix)&7))) & 1)
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));
572 b2 = finddiff2(rp, b1, bits, PIXEL(rp,b1));
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);
582 putspan(pData, a1-a0, TIFFFaxBlackCodes);
583 putspan(pData, a2-a1, TIFFFaxWhiteCodes);
586 } else { /* vertical mode */
587 putcode(pData, &vcodes[d+3]);
590 } else { /* pass mode */
591 putcode(pData, &passcode);
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));
605 * Encode the requested amount of data.
608 HPDF_Fax4Encode(struct _HPDF_CCITT_Data *pData, tidata_t bp, tsize_t cc/*, tsample_t s*/)
610 HPDF_Fax3CodecState *sp = EncoderState(pData);
613 while ((long)cc > 0) {
614 if (HPDF_Fax3Encode2DRow(pData, bp, sp->refline, sp->b.rowpixels)!=HPDF_OK)
616 memcpy(sp->refline, bp, sp->b.rowbytes);
617 bp += sp->b.rowbytes;
618 cc -= sp->b.rowbytes;
624 HPDF_Fax4PostEncode(struct _HPDF_CCITT_Data *pData)
626 /* HPDF_Fax3CodecState *sp = EncoderState(pData); */
628 /* terminate strip w/ EOFB */
629 HPDF_Fax3PutBits(pData, EOL, 12);
630 HPDF_Fax3PutBits(pData, EOL, 12);
632 HPDF_Fax3FlushBits(pData, sp);
634 HPDF_CCITT_FlushData(pData);
640 HPDF_Stream_CcittToStream( const HPDF_BYTE *buf,
645 HPDF_UINT line_width,
646 HPDF_BOOL top_is_first)
648 const HPDF_BYTE *pBufPos;
649 const HPDF_BYTE *pBufEnd; /* end marker */
651 struct _HPDF_CCITT_Data data;
653 if(height==0) return 1;
656 pBufEnd=buf+(line_width*height);
657 lineIncrement = line_width;
659 pBufPos = buf+(line_width*(height-1));
660 pBufEnd= buf-line_width;
661 lineIncrement = -((int)line_width);
664 memset(&data, 0, sizeof(struct _HPDF_CCITT_Data));
666 data.tif_rawdata = (tidata_t) malloc( 16384 ); /* 16 kb buffer */
667 data.tif_rawdatasize = 16384;
669 data.tif_rawcp = data.tif_rawdata;
671 if(HPDF_InitCCITTFax3(&data)!=HPDF_OK)
674 if(HPDF_Fax3SetupState(&data, width, height, line_width)!=HPDF_OK)
676 HPDF_FreeCCITTFax3(&data);
680 if(HPDF_Fax3PreEncode(&data)!=HPDF_OK)
682 HPDF_FreeCCITTFax3(&data);
687 while(pBufEnd!=pBufPos)
689 HPDF_Fax4Encode(&data, (tidata_t)pBufPos, line_width);
690 pBufPos+=lineIncrement;
693 HPDF_Fax4PostEncode(&data);
695 HPDF_FreeCCITTFax3(&data);
701 HPDF_Image_Load1BitImageFromMem (HPDF_MMgr mmgr,
702 const HPDF_BYTE *buf,
706 HPDF_UINT line_width,
707 HPDF_BOOL top_is_first
711 HPDF_STATUS ret = HPDF_OK;
712 /* HPDF_UINT size; */
714 HPDF_PTRACE ((" HPDF_Image_Load1BitImage\n"));
716 image = HPDF_DictStream_New (mmgr, xref);
720 image->header.obj_class |= HPDF_OSUBCLASS_XOBJECT;
721 ret += HPDF_Dict_AddName (image, "Type", "XObject");
722 ret += HPDF_Dict_AddName (image, "Subtype", "Image");
726 /* size = width * height; */
727 ret = HPDF_Dict_AddName (image, "ColorSpace", "DeviceGray");
731 if (HPDF_Dict_AddNumber (image, "Width", width) != HPDF_OK)
734 if (HPDF_Dict_AddNumber (image, "Height", height) != HPDF_OK)
737 if (HPDF_Dict_AddNumber (image, "BitsPerComponent", 1) != HPDF_OK)
740 if (HPDF_Stream_CcittToStream (buf, image->stream, NULL, width, height, line_width, top_is_first) != HPDF_OK)
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
754 HPDF_Image_LoadRaw1BitImageFromMem (HPDF_Doc pdf,
755 const HPDF_BYTE *buf,
758 HPDF_UINT line_width,
760 HPDF_BOOL top_is_first)
764 HPDF_PTRACE ((" HPDF_Image_Load1BitImageFromMem\n"));
766 if (!HPDF_HasDoc (pdf))
769 image = HPDF_Image_Load1BitImageFromMem(pdf->mmgr, buf, pdf->xref, width,
770 height, line_width, top_is_first);
773 HPDF_CheckError (&pdf->error);
775 if (pdf->compression_mode & HPDF_COMP_IMAGE)
777 image->filter = HPDF_STREAM_FILTER_CCITT_DECODE;
778 image->filterParams = HPDF_Dict_New(pdf->mmgr);
779 if(image->filterParams==NULL) {
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);
788 HPDF_Dict_AddNumber (image->filterParams, "Rows", height);
789 HPDF_Dict_AddBoolean (image->filterParams, "BlackIs1", black_is1);