xref: /aosp_15_r20/external/pdfium/third_party/libtiff/tif_fax3.c (revision 3ac0a46f773bac49fa9476ec2b1cf3f8da5ec3a4)
1*3ac0a46fSAndroid Build Coastguard Worker /*
2*3ac0a46fSAndroid Build Coastguard Worker  * Copyright (c) 1990-1997 Sam Leffler
3*3ac0a46fSAndroid Build Coastguard Worker  * Copyright (c) 1991-1997 Silicon Graphics, Inc.
4*3ac0a46fSAndroid Build Coastguard Worker  *
5*3ac0a46fSAndroid Build Coastguard Worker  * Permission to use, copy, modify, distribute, and sell this software and
6*3ac0a46fSAndroid Build Coastguard Worker  * its documentation for any purpose is hereby granted without fee, provided
7*3ac0a46fSAndroid Build Coastguard Worker  * that (i) the above copyright notices and this permission notice appear in
8*3ac0a46fSAndroid Build Coastguard Worker  * all copies of the software and related documentation, and (ii) the names of
9*3ac0a46fSAndroid Build Coastguard Worker  * Sam Leffler and Silicon Graphics may not be used in any advertising or
10*3ac0a46fSAndroid Build Coastguard Worker  * publicity relating to the software without the specific, prior written
11*3ac0a46fSAndroid Build Coastguard Worker  * permission of Sam Leffler and Silicon Graphics.
12*3ac0a46fSAndroid Build Coastguard Worker  *
13*3ac0a46fSAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
14*3ac0a46fSAndroid Build Coastguard Worker  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
15*3ac0a46fSAndroid Build Coastguard Worker  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
16*3ac0a46fSAndroid Build Coastguard Worker  *
17*3ac0a46fSAndroid Build Coastguard Worker  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
18*3ac0a46fSAndroid Build Coastguard Worker  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
19*3ac0a46fSAndroid Build Coastguard Worker  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
20*3ac0a46fSAndroid Build Coastguard Worker  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
21*3ac0a46fSAndroid Build Coastguard Worker  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
22*3ac0a46fSAndroid Build Coastguard Worker  * OF THIS SOFTWARE.
23*3ac0a46fSAndroid Build Coastguard Worker  */
24*3ac0a46fSAndroid Build Coastguard Worker 
25*3ac0a46fSAndroid Build Coastguard Worker #include "tiffiop.h"
26*3ac0a46fSAndroid Build Coastguard Worker #ifdef CCITT_SUPPORT
27*3ac0a46fSAndroid Build Coastguard Worker /*
28*3ac0a46fSAndroid Build Coastguard Worker  * TIFF Library.
29*3ac0a46fSAndroid Build Coastguard Worker  *
30*3ac0a46fSAndroid Build Coastguard Worker  * CCITT Group 3 (T.4) and Group 4 (T.6) Compression Support.
31*3ac0a46fSAndroid Build Coastguard Worker  *
32*3ac0a46fSAndroid Build Coastguard Worker  * This file contains support for decoding and encoding TIFF
33*3ac0a46fSAndroid Build Coastguard Worker  * compression algorithms 2, 3, 4, and 32771.
34*3ac0a46fSAndroid Build Coastguard Worker  *
35*3ac0a46fSAndroid Build Coastguard Worker  * Decoder support is derived, with permission, from the code
36*3ac0a46fSAndroid Build Coastguard Worker  * in Frank Cringle's viewfax program;
37*3ac0a46fSAndroid Build Coastguard Worker  *      Copyright (C) 1990, 1995  Frank D. Cringle.
38*3ac0a46fSAndroid Build Coastguard Worker  */
39*3ac0a46fSAndroid Build Coastguard Worker #include "tif_fax3.h"
40*3ac0a46fSAndroid Build Coastguard Worker #define G3CODES
41*3ac0a46fSAndroid Build Coastguard Worker #include "t4.h"
42*3ac0a46fSAndroid Build Coastguard Worker #include <stdio.h>
43*3ac0a46fSAndroid Build Coastguard Worker 
44*3ac0a46fSAndroid Build Coastguard Worker /*
45*3ac0a46fSAndroid Build Coastguard Worker  * Compression+decompression state blocks are
46*3ac0a46fSAndroid Build Coastguard Worker  * derived from this ``base state'' block.
47*3ac0a46fSAndroid Build Coastguard Worker  */
48*3ac0a46fSAndroid Build Coastguard Worker typedef struct
49*3ac0a46fSAndroid Build Coastguard Worker {
50*3ac0a46fSAndroid Build Coastguard Worker     int rw_mode;        /* O_RDONLY for decode, else encode */
51*3ac0a46fSAndroid Build Coastguard Worker     int mode;           /* operating mode */
52*3ac0a46fSAndroid Build Coastguard Worker     tmsize_t rowbytes;  /* bytes in a decoded scanline */
53*3ac0a46fSAndroid Build Coastguard Worker     uint32_t rowpixels; /* pixels in a scanline */
54*3ac0a46fSAndroid Build Coastguard Worker 
55*3ac0a46fSAndroid Build Coastguard Worker     uint16_t cleanfaxdata; /* CleanFaxData tag */
56*3ac0a46fSAndroid Build Coastguard Worker     uint32_t badfaxrun;    /* BadFaxRun tag */
57*3ac0a46fSAndroid Build Coastguard Worker     uint32_t badfaxlines;  /* BadFaxLines tag */
58*3ac0a46fSAndroid Build Coastguard Worker     uint32_t groupoptions; /* Group 3/4 options tag */
59*3ac0a46fSAndroid Build Coastguard Worker 
60*3ac0a46fSAndroid Build Coastguard Worker     TIFFVGetMethod vgetparent; /* super-class method */
61*3ac0a46fSAndroid Build Coastguard Worker     TIFFVSetMethod vsetparent; /* super-class method */
62*3ac0a46fSAndroid Build Coastguard Worker     TIFFPrintMethod printdir;  /* super-class method */
63*3ac0a46fSAndroid Build Coastguard Worker } Fax3BaseState;
64*3ac0a46fSAndroid Build Coastguard Worker #define Fax3State(tif) ((Fax3BaseState *)(tif)->tif_data)
65*3ac0a46fSAndroid Build Coastguard Worker 
66*3ac0a46fSAndroid Build Coastguard Worker typedef enum
67*3ac0a46fSAndroid Build Coastguard Worker {
68*3ac0a46fSAndroid Build Coastguard Worker     G3_1D,
69*3ac0a46fSAndroid Build Coastguard Worker     G3_2D
70*3ac0a46fSAndroid Build Coastguard Worker } Ttag;
71*3ac0a46fSAndroid Build Coastguard Worker typedef struct
72*3ac0a46fSAndroid Build Coastguard Worker {
73*3ac0a46fSAndroid Build Coastguard Worker     Fax3BaseState b;
74*3ac0a46fSAndroid Build Coastguard Worker 
75*3ac0a46fSAndroid Build Coastguard Worker     /* Decoder state info */
76*3ac0a46fSAndroid Build Coastguard Worker     const unsigned char *bitmap; /* bit reversal table */
77*3ac0a46fSAndroid Build Coastguard Worker     uint32_t data;               /* current i/o byte/word */
78*3ac0a46fSAndroid Build Coastguard Worker     int bit;                     /* current i/o bit in byte */
79*3ac0a46fSAndroid Build Coastguard Worker     int EOLcnt;                  /* count of EOL codes recognized */
80*3ac0a46fSAndroid Build Coastguard Worker     TIFFFaxFillFunc fill;        /* fill routine */
81*3ac0a46fSAndroid Build Coastguard Worker     uint32_t *runs;              /* b&w runs for current/previous row */
82*3ac0a46fSAndroid Build Coastguard Worker     uint32_t nruns;              /* size of the refruns / curruns arrays */
83*3ac0a46fSAndroid Build Coastguard Worker     uint32_t *refruns;           /* runs for reference line */
84*3ac0a46fSAndroid Build Coastguard Worker     uint32_t *curruns;           /* runs for current line */
85*3ac0a46fSAndroid Build Coastguard Worker 
86*3ac0a46fSAndroid Build Coastguard Worker     /* Encoder state info */
87*3ac0a46fSAndroid Build Coastguard Worker     Ttag tag;               /* encoding state */
88*3ac0a46fSAndroid Build Coastguard Worker     unsigned char *refline; /* reference line for 2d decoding */
89*3ac0a46fSAndroid Build Coastguard Worker     int k;                  /* #rows left that can be 2d encoded */
90*3ac0a46fSAndroid Build Coastguard Worker     int maxk;               /* max #rows that can be 2d encoded */
91*3ac0a46fSAndroid Build Coastguard Worker 
92*3ac0a46fSAndroid Build Coastguard Worker     int line;
93*3ac0a46fSAndroid Build Coastguard Worker } Fax3CodecState;
94*3ac0a46fSAndroid Build Coastguard Worker #define DecoderState(tif) ((Fax3CodecState *)Fax3State(tif))
95*3ac0a46fSAndroid Build Coastguard Worker #define EncoderState(tif) ((Fax3CodecState *)Fax3State(tif))
96*3ac0a46fSAndroid Build Coastguard Worker 
97*3ac0a46fSAndroid Build Coastguard Worker #define is2DEncoding(sp) (sp->b.groupoptions & GROUP3OPT_2DENCODING)
98*3ac0a46fSAndroid Build Coastguard Worker #define isAligned(p, t) ((((size_t)(p)) & (sizeof(t) - 1)) == 0)
99*3ac0a46fSAndroid Build Coastguard Worker 
100*3ac0a46fSAndroid Build Coastguard Worker /*
101*3ac0a46fSAndroid Build Coastguard Worker  * Group 3 and Group 4 Decoding.
102*3ac0a46fSAndroid Build Coastguard Worker  */
103*3ac0a46fSAndroid Build Coastguard Worker 
104*3ac0a46fSAndroid Build Coastguard Worker /*
105*3ac0a46fSAndroid Build Coastguard Worker  * These macros glue the TIFF library state to
106*3ac0a46fSAndroid Build Coastguard Worker  * the state expected by Frank's decoder.
107*3ac0a46fSAndroid Build Coastguard Worker  */
108*3ac0a46fSAndroid Build Coastguard Worker #define DECLARE_STATE(tif, sp, mod)                                            \
109*3ac0a46fSAndroid Build Coastguard Worker     static const char module[] = mod;                                          \
110*3ac0a46fSAndroid Build Coastguard Worker     Fax3CodecState *sp = DecoderState(tif);                                    \
111*3ac0a46fSAndroid Build Coastguard Worker     int a0;                                   /* reference element */          \
112*3ac0a46fSAndroid Build Coastguard Worker     int lastx = sp->b.rowpixels;              /* last element in row */        \
113*3ac0a46fSAndroid Build Coastguard Worker     uint32_t BitAcc;                          /* bit accumulator */            \
114*3ac0a46fSAndroid Build Coastguard Worker     int BitsAvail;                            /* # valid bits in BitAcc */     \
115*3ac0a46fSAndroid Build Coastguard Worker     int RunLength;                            /* length of current run */      \
116*3ac0a46fSAndroid Build Coastguard Worker     unsigned char *cp;                        /* next byte of input data */    \
117*3ac0a46fSAndroid Build Coastguard Worker     unsigned char *ep;                        /* end of input data */          \
118*3ac0a46fSAndroid Build Coastguard Worker     uint32_t *pa;                             /* place to stuff next run */    \
119*3ac0a46fSAndroid Build Coastguard Worker     uint32_t *thisrun;                        /* current row's run array */    \
120*3ac0a46fSAndroid Build Coastguard Worker     int EOLcnt;                               /* # EOL codes recognized */     \
121*3ac0a46fSAndroid Build Coastguard Worker     const unsigned char *bitmap = sp->bitmap; /* input data bit reverser */    \
122*3ac0a46fSAndroid Build Coastguard Worker     const TIFFFaxTabEnt *TabEnt
123*3ac0a46fSAndroid Build Coastguard Worker #define DECLARE_STATE_2D(tif, sp, mod)                                         \
124*3ac0a46fSAndroid Build Coastguard Worker     DECLARE_STATE(tif, sp, mod);                                               \
125*3ac0a46fSAndroid Build Coastguard Worker     int b1; /* next change on prev line */                                     \
126*3ac0a46fSAndroid Build Coastguard Worker     uint32_t                                                                   \
127*3ac0a46fSAndroid Build Coastguard Worker         *pb /* next run in reference line */ /*                                \
128*3ac0a46fSAndroid Build Coastguard Worker                                               * Load any state that may be     \
129*3ac0a46fSAndroid Build Coastguard Worker                                               * changed during decoding.       \
130*3ac0a46fSAndroid Build Coastguard Worker                                               */
131*3ac0a46fSAndroid Build Coastguard Worker #define CACHE_STATE(tif, sp)                                                   \
132*3ac0a46fSAndroid Build Coastguard Worker     do                                                                         \
133*3ac0a46fSAndroid Build Coastguard Worker     {                                                                          \
134*3ac0a46fSAndroid Build Coastguard Worker         BitAcc = sp->data;                                                     \
135*3ac0a46fSAndroid Build Coastguard Worker         BitsAvail = sp->bit;                                                   \
136*3ac0a46fSAndroid Build Coastguard Worker         EOLcnt = sp->EOLcnt;                                                   \
137*3ac0a46fSAndroid Build Coastguard Worker         cp = (unsigned char *)tif->tif_rawcp;                                  \
138*3ac0a46fSAndroid Build Coastguard Worker         ep = cp + tif->tif_rawcc;                                              \
139*3ac0a46fSAndroid Build Coastguard Worker     } while (0)
140*3ac0a46fSAndroid Build Coastguard Worker /*
141*3ac0a46fSAndroid Build Coastguard Worker  * Save state possibly changed during decoding.
142*3ac0a46fSAndroid Build Coastguard Worker  */
143*3ac0a46fSAndroid Build Coastguard Worker #define UNCACHE_STATE(tif, sp)                                                 \
144*3ac0a46fSAndroid Build Coastguard Worker     do                                                                         \
145*3ac0a46fSAndroid Build Coastguard Worker     {                                                                          \
146*3ac0a46fSAndroid Build Coastguard Worker         sp->bit = BitsAvail;                                                   \
147*3ac0a46fSAndroid Build Coastguard Worker         sp->data = BitAcc;                                                     \
148*3ac0a46fSAndroid Build Coastguard Worker         sp->EOLcnt = EOLcnt;                                                   \
149*3ac0a46fSAndroid Build Coastguard Worker         tif->tif_rawcc -= (tmsize_t)((uint8_t *)cp - tif->tif_rawcp);          \
150*3ac0a46fSAndroid Build Coastguard Worker         tif->tif_rawcp = (uint8_t *)cp;                                        \
151*3ac0a46fSAndroid Build Coastguard Worker     } while (0)
152*3ac0a46fSAndroid Build Coastguard Worker 
153*3ac0a46fSAndroid Build Coastguard Worker /*
154*3ac0a46fSAndroid Build Coastguard Worker  * Setup state for decoding a strip.
155*3ac0a46fSAndroid Build Coastguard Worker  */
Fax3PreDecode(TIFF * tif,uint16_t s)156*3ac0a46fSAndroid Build Coastguard Worker static int Fax3PreDecode(TIFF *tif, uint16_t s)
157*3ac0a46fSAndroid Build Coastguard Worker {
158*3ac0a46fSAndroid Build Coastguard Worker     Fax3CodecState *sp = DecoderState(tif);
159*3ac0a46fSAndroid Build Coastguard Worker 
160*3ac0a46fSAndroid Build Coastguard Worker     (void)s;
161*3ac0a46fSAndroid Build Coastguard Worker     assert(sp != NULL);
162*3ac0a46fSAndroid Build Coastguard Worker     sp->bit = 0; /* force initial read */
163*3ac0a46fSAndroid Build Coastguard Worker     sp->data = 0;
164*3ac0a46fSAndroid Build Coastguard Worker     sp->EOLcnt = 0; /* force initial scan for EOL */
165*3ac0a46fSAndroid Build Coastguard Worker     /*
166*3ac0a46fSAndroid Build Coastguard Worker      * Decoder assumes lsb-to-msb bit order.  Note that we select
167*3ac0a46fSAndroid Build Coastguard Worker      * this here rather than in Fax3SetupState so that viewers can
168*3ac0a46fSAndroid Build Coastguard Worker      * hold the image open, fiddle with the FillOrder tag value,
169*3ac0a46fSAndroid Build Coastguard Worker      * and then re-decode the image.  Otherwise they'd need to close
170*3ac0a46fSAndroid Build Coastguard Worker      * and open the image to get the state reset.
171*3ac0a46fSAndroid Build Coastguard Worker      */
172*3ac0a46fSAndroid Build Coastguard Worker     sp->bitmap =
173*3ac0a46fSAndroid Build Coastguard Worker         TIFFGetBitRevTable(tif->tif_dir.td_fillorder != FILLORDER_LSB2MSB);
174*3ac0a46fSAndroid Build Coastguard Worker     sp->curruns = sp->runs;
175*3ac0a46fSAndroid Build Coastguard Worker     if (sp->refruns)
176*3ac0a46fSAndroid Build Coastguard Worker     { /* init reference line to white */
177*3ac0a46fSAndroid Build Coastguard Worker         sp->refruns = sp->runs + sp->nruns;
178*3ac0a46fSAndroid Build Coastguard Worker         sp->refruns[0] = (uint32_t)sp->b.rowpixels;
179*3ac0a46fSAndroid Build Coastguard Worker         sp->refruns[1] = 0;
180*3ac0a46fSAndroid Build Coastguard Worker     }
181*3ac0a46fSAndroid Build Coastguard Worker     sp->line = 0;
182*3ac0a46fSAndroid Build Coastguard Worker     return (1);
183*3ac0a46fSAndroid Build Coastguard Worker }
184*3ac0a46fSAndroid Build Coastguard Worker 
185*3ac0a46fSAndroid Build Coastguard Worker /*
186*3ac0a46fSAndroid Build Coastguard Worker  * Routine for handling various errors/conditions.
187*3ac0a46fSAndroid Build Coastguard Worker  * Note how they are "glued into the decoder" by
188*3ac0a46fSAndroid Build Coastguard Worker  * overriding the definitions used by the decoder.
189*3ac0a46fSAndroid Build Coastguard Worker  */
190*3ac0a46fSAndroid Build Coastguard Worker 
Fax3Unexpected(const char * module,TIFF * tif,uint32_t line,uint32_t a0)191*3ac0a46fSAndroid Build Coastguard Worker static void Fax3Unexpected(const char *module, TIFF *tif, uint32_t line,
192*3ac0a46fSAndroid Build Coastguard Worker                            uint32_t a0)
193*3ac0a46fSAndroid Build Coastguard Worker {
194*3ac0a46fSAndroid Build Coastguard Worker     TIFFErrorExtR(tif, module,
195*3ac0a46fSAndroid Build Coastguard Worker                   "Bad code word at line %" PRIu32 " of %s %" PRIu32
196*3ac0a46fSAndroid Build Coastguard Worker                   " (x %" PRIu32 ")",
197*3ac0a46fSAndroid Build Coastguard Worker                   line, isTiled(tif) ? "tile" : "strip",
198*3ac0a46fSAndroid Build Coastguard Worker                   (isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip), a0);
199*3ac0a46fSAndroid Build Coastguard Worker }
200*3ac0a46fSAndroid Build Coastguard Worker #define unexpected(table, a0) Fax3Unexpected(module, tif, sp->line, a0)
201*3ac0a46fSAndroid Build Coastguard Worker 
Fax3Extension(const char * module,TIFF * tif,uint32_t line,uint32_t a0)202*3ac0a46fSAndroid Build Coastguard Worker static void Fax3Extension(const char *module, TIFF *tif, uint32_t line,
203*3ac0a46fSAndroid Build Coastguard Worker                           uint32_t a0)
204*3ac0a46fSAndroid Build Coastguard Worker {
205*3ac0a46fSAndroid Build Coastguard Worker     TIFFErrorExtR(tif, module,
206*3ac0a46fSAndroid Build Coastguard Worker                   "Uncompressed data (not supported) at line %" PRIu32
207*3ac0a46fSAndroid Build Coastguard Worker                   " of %s %" PRIu32 " (x %" PRIu32 ")",
208*3ac0a46fSAndroid Build Coastguard Worker                   line, isTiled(tif) ? "tile" : "strip",
209*3ac0a46fSAndroid Build Coastguard Worker                   (isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip), a0);
210*3ac0a46fSAndroid Build Coastguard Worker }
211*3ac0a46fSAndroid Build Coastguard Worker #define extension(a0) Fax3Extension(module, tif, sp->line, a0)
212*3ac0a46fSAndroid Build Coastguard Worker 
Fax3BadLength(const char * module,TIFF * tif,uint32_t line,uint32_t a0,uint32_t lastx)213*3ac0a46fSAndroid Build Coastguard Worker static void Fax3BadLength(const char *module, TIFF *tif, uint32_t line,
214*3ac0a46fSAndroid Build Coastguard Worker                           uint32_t a0, uint32_t lastx)
215*3ac0a46fSAndroid Build Coastguard Worker {
216*3ac0a46fSAndroid Build Coastguard Worker     TIFFWarningExtR(tif, module,
217*3ac0a46fSAndroid Build Coastguard Worker                     "%s at line %" PRIu32 " of %s %" PRIu32 " (got %" PRIu32
218*3ac0a46fSAndroid Build Coastguard Worker                     ", expected %" PRIu32 ")",
219*3ac0a46fSAndroid Build Coastguard Worker                     a0 < lastx ? "Premature EOL" : "Line length mismatch", line,
220*3ac0a46fSAndroid Build Coastguard Worker                     isTiled(tif) ? "tile" : "strip",
221*3ac0a46fSAndroid Build Coastguard Worker                     (isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip), a0,
222*3ac0a46fSAndroid Build Coastguard Worker                     lastx);
223*3ac0a46fSAndroid Build Coastguard Worker }
224*3ac0a46fSAndroid Build Coastguard Worker #define badlength(a0, lastx) Fax3BadLength(module, tif, sp->line, a0, lastx)
225*3ac0a46fSAndroid Build Coastguard Worker 
Fax3PrematureEOF(const char * module,TIFF * tif,uint32_t line,uint32_t a0)226*3ac0a46fSAndroid Build Coastguard Worker static void Fax3PrematureEOF(const char *module, TIFF *tif, uint32_t line,
227*3ac0a46fSAndroid Build Coastguard Worker                              uint32_t a0)
228*3ac0a46fSAndroid Build Coastguard Worker {
229*3ac0a46fSAndroid Build Coastguard Worker     TIFFWarningExtR(tif, module,
230*3ac0a46fSAndroid Build Coastguard Worker                     "Premature EOF at line %" PRIu32 " of %s %" PRIu32
231*3ac0a46fSAndroid Build Coastguard Worker                     " (x %" PRIu32 ")",
232*3ac0a46fSAndroid Build Coastguard Worker                     line, isTiled(tif) ? "tile" : "strip",
233*3ac0a46fSAndroid Build Coastguard Worker                     (isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip), a0);
234*3ac0a46fSAndroid Build Coastguard Worker }
235*3ac0a46fSAndroid Build Coastguard Worker #define prematureEOF(a0) Fax3PrematureEOF(module, tif, sp->line, a0)
236*3ac0a46fSAndroid Build Coastguard Worker 
237*3ac0a46fSAndroid Build Coastguard Worker #define Nop
238*3ac0a46fSAndroid Build Coastguard Worker 
239*3ac0a46fSAndroid Build Coastguard Worker /**
240*3ac0a46fSAndroid Build Coastguard Worker  * Decode the requested amount of G3 1D-encoded data.
241*3ac0a46fSAndroid Build Coastguard Worker  * @param buf destination buffer
242*3ac0a46fSAndroid Build Coastguard Worker  * @param occ available bytes in destination buffer
243*3ac0a46fSAndroid Build Coastguard Worker  * @param s number of planes (ignored)
244*3ac0a46fSAndroid Build Coastguard Worker  * @returns 1 for success, -1 in case of error
245*3ac0a46fSAndroid Build Coastguard Worker  */
Fax3Decode1D(TIFF * tif,uint8_t * buf,tmsize_t occ,uint16_t s)246*3ac0a46fSAndroid Build Coastguard Worker static int Fax3Decode1D(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s)
247*3ac0a46fSAndroid Build Coastguard Worker {
248*3ac0a46fSAndroid Build Coastguard Worker     DECLARE_STATE(tif, sp, "Fax3Decode1D");
249*3ac0a46fSAndroid Build Coastguard Worker     (void)s;
250*3ac0a46fSAndroid Build Coastguard Worker     if (occ % sp->b.rowbytes)
251*3ac0a46fSAndroid Build Coastguard Worker     {
252*3ac0a46fSAndroid Build Coastguard Worker         TIFFErrorExtR(tif, module, "Fractional scanlines cannot be read");
253*3ac0a46fSAndroid Build Coastguard Worker         return (-1);
254*3ac0a46fSAndroid Build Coastguard Worker     }
255*3ac0a46fSAndroid Build Coastguard Worker     CACHE_STATE(tif, sp);
256*3ac0a46fSAndroid Build Coastguard Worker     thisrun = sp->curruns;
257*3ac0a46fSAndroid Build Coastguard Worker     while (occ > 0)
258*3ac0a46fSAndroid Build Coastguard Worker     {
259*3ac0a46fSAndroid Build Coastguard Worker         a0 = 0;
260*3ac0a46fSAndroid Build Coastguard Worker         RunLength = 0;
261*3ac0a46fSAndroid Build Coastguard Worker         pa = thisrun;
262*3ac0a46fSAndroid Build Coastguard Worker #ifdef FAX3_DEBUG
263*3ac0a46fSAndroid Build Coastguard Worker         printf("\nBitAcc=%08" PRIX32 ", BitsAvail = %d\n", BitAcc, BitsAvail);
264*3ac0a46fSAndroid Build Coastguard Worker         printf("-------------------- %" PRIu32 "\n", tif->tif_row);
265*3ac0a46fSAndroid Build Coastguard Worker         fflush(stdout);
266*3ac0a46fSAndroid Build Coastguard Worker #endif
267*3ac0a46fSAndroid Build Coastguard Worker         SYNC_EOL(EOF1D);
268*3ac0a46fSAndroid Build Coastguard Worker         EXPAND1D(EOF1Da);
269*3ac0a46fSAndroid Build Coastguard Worker         (*sp->fill)(buf, thisrun, pa, lastx);
270*3ac0a46fSAndroid Build Coastguard Worker         buf += sp->b.rowbytes;
271*3ac0a46fSAndroid Build Coastguard Worker         occ -= sp->b.rowbytes;
272*3ac0a46fSAndroid Build Coastguard Worker         sp->line++;
273*3ac0a46fSAndroid Build Coastguard Worker         continue;
274*3ac0a46fSAndroid Build Coastguard Worker     EOF1D: /* premature EOF */
275*3ac0a46fSAndroid Build Coastguard Worker         CLEANUP_RUNS();
276*3ac0a46fSAndroid Build Coastguard Worker     EOF1Da: /* premature EOF */
277*3ac0a46fSAndroid Build Coastguard Worker         (*sp->fill)(buf, thisrun, pa, lastx);
278*3ac0a46fSAndroid Build Coastguard Worker         UNCACHE_STATE(tif, sp);
279*3ac0a46fSAndroid Build Coastguard Worker         return (-1);
280*3ac0a46fSAndroid Build Coastguard Worker     }
281*3ac0a46fSAndroid Build Coastguard Worker     UNCACHE_STATE(tif, sp);
282*3ac0a46fSAndroid Build Coastguard Worker     return (1);
283*3ac0a46fSAndroid Build Coastguard Worker }
284*3ac0a46fSAndroid Build Coastguard Worker 
285*3ac0a46fSAndroid Build Coastguard Worker #define SWAP(t, a, b)                                                          \
286*3ac0a46fSAndroid Build Coastguard Worker     {                                                                          \
287*3ac0a46fSAndroid Build Coastguard Worker         t x;                                                                   \
288*3ac0a46fSAndroid Build Coastguard Worker         x = (a);                                                               \
289*3ac0a46fSAndroid Build Coastguard Worker         (a) = (b);                                                             \
290*3ac0a46fSAndroid Build Coastguard Worker         (b) = x;                                                               \
291*3ac0a46fSAndroid Build Coastguard Worker     }
292*3ac0a46fSAndroid Build Coastguard Worker /*
293*3ac0a46fSAndroid Build Coastguard Worker  * Decode the requested amount of G3 2D-encoded data.
294*3ac0a46fSAndroid Build Coastguard Worker  */
Fax3Decode2D(TIFF * tif,uint8_t * buf,tmsize_t occ,uint16_t s)295*3ac0a46fSAndroid Build Coastguard Worker static int Fax3Decode2D(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s)
296*3ac0a46fSAndroid Build Coastguard Worker {
297*3ac0a46fSAndroid Build Coastguard Worker     DECLARE_STATE_2D(tif, sp, "Fax3Decode2D");
298*3ac0a46fSAndroid Build Coastguard Worker     int is1D; /* current line is 1d/2d-encoded */
299*3ac0a46fSAndroid Build Coastguard Worker     (void)s;
300*3ac0a46fSAndroid Build Coastguard Worker     if (occ % sp->b.rowbytes)
301*3ac0a46fSAndroid Build Coastguard Worker     {
302*3ac0a46fSAndroid Build Coastguard Worker         TIFFErrorExtR(tif, module, "Fractional scanlines cannot be read");
303*3ac0a46fSAndroid Build Coastguard Worker         return (-1);
304*3ac0a46fSAndroid Build Coastguard Worker     }
305*3ac0a46fSAndroid Build Coastguard Worker     CACHE_STATE(tif, sp);
306*3ac0a46fSAndroid Build Coastguard Worker     while (occ > 0)
307*3ac0a46fSAndroid Build Coastguard Worker     {
308*3ac0a46fSAndroid Build Coastguard Worker         a0 = 0;
309*3ac0a46fSAndroid Build Coastguard Worker         RunLength = 0;
310*3ac0a46fSAndroid Build Coastguard Worker         pa = thisrun = sp->curruns;
311*3ac0a46fSAndroid Build Coastguard Worker #ifdef FAX3_DEBUG
312*3ac0a46fSAndroid Build Coastguard Worker         printf("\nBitAcc=%08" PRIX32 ", BitsAvail = %d EOLcnt = %d", BitAcc,
313*3ac0a46fSAndroid Build Coastguard Worker                BitsAvail, EOLcnt);
314*3ac0a46fSAndroid Build Coastguard Worker #endif
315*3ac0a46fSAndroid Build Coastguard Worker         SYNC_EOL(EOF2D);
316*3ac0a46fSAndroid Build Coastguard Worker         NeedBits8(1, EOF2D);
317*3ac0a46fSAndroid Build Coastguard Worker         is1D = GetBits(1); /* 1D/2D-encoding tag bit */
318*3ac0a46fSAndroid Build Coastguard Worker         ClrBits(1);
319*3ac0a46fSAndroid Build Coastguard Worker #ifdef FAX3_DEBUG
320*3ac0a46fSAndroid Build Coastguard Worker         printf(" %s\n-------------------- %" PRIu32 "\n", is1D ? "1D" : "2D",
321*3ac0a46fSAndroid Build Coastguard Worker                tif->tif_row);
322*3ac0a46fSAndroid Build Coastguard Worker         fflush(stdout);
323*3ac0a46fSAndroid Build Coastguard Worker #endif
324*3ac0a46fSAndroid Build Coastguard Worker         pb = sp->refruns;
325*3ac0a46fSAndroid Build Coastguard Worker         b1 = *pb++;
326*3ac0a46fSAndroid Build Coastguard Worker         if (is1D)
327*3ac0a46fSAndroid Build Coastguard Worker             EXPAND1D(EOF2Da);
328*3ac0a46fSAndroid Build Coastguard Worker         else
329*3ac0a46fSAndroid Build Coastguard Worker             EXPAND2D(EOF2Da);
330*3ac0a46fSAndroid Build Coastguard Worker         (*sp->fill)(buf, thisrun, pa, lastx);
331*3ac0a46fSAndroid Build Coastguard Worker         if (pa < thisrun + sp->nruns)
332*3ac0a46fSAndroid Build Coastguard Worker         {
333*3ac0a46fSAndroid Build Coastguard Worker             SETVALUE(0); /* imaginary change for reference */
334*3ac0a46fSAndroid Build Coastguard Worker         }
335*3ac0a46fSAndroid Build Coastguard Worker         SWAP(uint32_t *, sp->curruns, sp->refruns);
336*3ac0a46fSAndroid Build Coastguard Worker         buf += sp->b.rowbytes;
337*3ac0a46fSAndroid Build Coastguard Worker         occ -= sp->b.rowbytes;
338*3ac0a46fSAndroid Build Coastguard Worker         sp->line++;
339*3ac0a46fSAndroid Build Coastguard Worker         continue;
340*3ac0a46fSAndroid Build Coastguard Worker     EOF2D: /* premature EOF */
341*3ac0a46fSAndroid Build Coastguard Worker         CLEANUP_RUNS();
342*3ac0a46fSAndroid Build Coastguard Worker     EOF2Da: /* premature EOF */
343*3ac0a46fSAndroid Build Coastguard Worker         (*sp->fill)(buf, thisrun, pa, lastx);
344*3ac0a46fSAndroid Build Coastguard Worker         UNCACHE_STATE(tif, sp);
345*3ac0a46fSAndroid Build Coastguard Worker         return (-1);
346*3ac0a46fSAndroid Build Coastguard Worker     }
347*3ac0a46fSAndroid Build Coastguard Worker     UNCACHE_STATE(tif, sp);
348*3ac0a46fSAndroid Build Coastguard Worker     return (1);
349*3ac0a46fSAndroid Build Coastguard Worker }
350*3ac0a46fSAndroid Build Coastguard Worker #undef SWAP
351*3ac0a46fSAndroid Build Coastguard Worker 
352*3ac0a46fSAndroid Build Coastguard Worker #define FILL(n, cp)                                                            \
353*3ac0a46fSAndroid Build Coastguard Worker     for (int32_t ifill = 0; ifill < (n); ++ifill)                              \
354*3ac0a46fSAndroid Build Coastguard Worker     {                                                                          \
355*3ac0a46fSAndroid Build Coastguard Worker         (cp)[ifill] = 0xff;                                                    \
356*3ac0a46fSAndroid Build Coastguard Worker     }                                                                          \
357*3ac0a46fSAndroid Build Coastguard Worker     (cp) += (n);
358*3ac0a46fSAndroid Build Coastguard Worker 
359*3ac0a46fSAndroid Build Coastguard Worker #define ZERO(n, cp)                                                            \
360*3ac0a46fSAndroid Build Coastguard Worker     for (int32_t izero = 0; izero < (n); ++izero)                              \
361*3ac0a46fSAndroid Build Coastguard Worker     {                                                                          \
362*3ac0a46fSAndroid Build Coastguard Worker         (cp)[izero] = 0;                                                       \
363*3ac0a46fSAndroid Build Coastguard Worker     }                                                                          \
364*3ac0a46fSAndroid Build Coastguard Worker     (cp) += (n);
365*3ac0a46fSAndroid Build Coastguard Worker 
366*3ac0a46fSAndroid Build Coastguard Worker /*
367*3ac0a46fSAndroid Build Coastguard Worker  * Bit-fill a row according to the white/black
368*3ac0a46fSAndroid Build Coastguard Worker  * runs generated during G3/G4 decoding.
369*3ac0a46fSAndroid Build Coastguard Worker  */
_TIFFFax3fillruns(unsigned char * buf,uint32_t * runs,uint32_t * erun,uint32_t lastx)370*3ac0a46fSAndroid Build Coastguard Worker void _TIFFFax3fillruns(unsigned char *buf, uint32_t *runs, uint32_t *erun,
371*3ac0a46fSAndroid Build Coastguard Worker                        uint32_t lastx)
372*3ac0a46fSAndroid Build Coastguard Worker {
373*3ac0a46fSAndroid Build Coastguard Worker     static const unsigned char _fillmasks[] = {0x00, 0x80, 0xc0, 0xe0, 0xf0,
374*3ac0a46fSAndroid Build Coastguard Worker                                                0xf8, 0xfc, 0xfe, 0xff};
375*3ac0a46fSAndroid Build Coastguard Worker     unsigned char *cp;
376*3ac0a46fSAndroid Build Coastguard Worker     uint32_t x, bx, run;
377*3ac0a46fSAndroid Build Coastguard Worker     int32_t n, nw;
378*3ac0a46fSAndroid Build Coastguard Worker     int64_t *lp;
379*3ac0a46fSAndroid Build Coastguard Worker 
380*3ac0a46fSAndroid Build Coastguard Worker     if ((erun - runs) & 1)
381*3ac0a46fSAndroid Build Coastguard Worker         *erun++ = 0;
382*3ac0a46fSAndroid Build Coastguard Worker     x = 0;
383*3ac0a46fSAndroid Build Coastguard Worker     for (; runs < erun; runs += 2)
384*3ac0a46fSAndroid Build Coastguard Worker     {
385*3ac0a46fSAndroid Build Coastguard Worker         run = runs[0];
386*3ac0a46fSAndroid Build Coastguard Worker         if (x + run > lastx || run > lastx)
387*3ac0a46fSAndroid Build Coastguard Worker             run = runs[0] = (uint32_t)(lastx - x);
388*3ac0a46fSAndroid Build Coastguard Worker         if (run)
389*3ac0a46fSAndroid Build Coastguard Worker         {
390*3ac0a46fSAndroid Build Coastguard Worker             cp = buf + (x >> 3);
391*3ac0a46fSAndroid Build Coastguard Worker             bx = x & 7;
392*3ac0a46fSAndroid Build Coastguard Worker             if (run > 8 - bx)
393*3ac0a46fSAndroid Build Coastguard Worker             {
394*3ac0a46fSAndroid Build Coastguard Worker                 if (bx)
395*3ac0a46fSAndroid Build Coastguard Worker                 { /* align to byte boundary */
396*3ac0a46fSAndroid Build Coastguard Worker                     *cp++ &= 0xff << (8 - bx);
397*3ac0a46fSAndroid Build Coastguard Worker                     run -= 8 - bx;
398*3ac0a46fSAndroid Build Coastguard Worker                 }
399*3ac0a46fSAndroid Build Coastguard Worker                 if ((n = run >> 3) != 0)
400*3ac0a46fSAndroid Build Coastguard Worker                 { /* multiple bytes to fill */
401*3ac0a46fSAndroid Build Coastguard Worker                     if ((n / sizeof(int64_t)) > 1)
402*3ac0a46fSAndroid Build Coastguard Worker                     {
403*3ac0a46fSAndroid Build Coastguard Worker                         /*
404*3ac0a46fSAndroid Build Coastguard Worker                          * Align to int64_tword boundary and fill.
405*3ac0a46fSAndroid Build Coastguard Worker                          */
406*3ac0a46fSAndroid Build Coastguard Worker                         for (; n && !isAligned(cp, int64_t); n--)
407*3ac0a46fSAndroid Build Coastguard Worker                             *cp++ = 0x00;
408*3ac0a46fSAndroid Build Coastguard Worker                         lp = (int64_t *)cp;
409*3ac0a46fSAndroid Build Coastguard Worker                         nw = (int32_t)(n / sizeof(int64_t));
410*3ac0a46fSAndroid Build Coastguard Worker                         n -= nw * sizeof(int64_t);
411*3ac0a46fSAndroid Build Coastguard Worker                         do
412*3ac0a46fSAndroid Build Coastguard Worker                         {
413*3ac0a46fSAndroid Build Coastguard Worker                             *lp++ = 0L;
414*3ac0a46fSAndroid Build Coastguard Worker                         } while (--nw);
415*3ac0a46fSAndroid Build Coastguard Worker                         cp = (unsigned char *)lp;
416*3ac0a46fSAndroid Build Coastguard Worker                     }
417*3ac0a46fSAndroid Build Coastguard Worker                     ZERO(n, cp);
418*3ac0a46fSAndroid Build Coastguard Worker                     run &= 7;
419*3ac0a46fSAndroid Build Coastguard Worker                 }
420*3ac0a46fSAndroid Build Coastguard Worker                 if (run)
421*3ac0a46fSAndroid Build Coastguard Worker                     cp[0] &= 0xff >> run;
422*3ac0a46fSAndroid Build Coastguard Worker             }
423*3ac0a46fSAndroid Build Coastguard Worker             else
424*3ac0a46fSAndroid Build Coastguard Worker                 cp[0] &= ~(_fillmasks[run] >> bx);
425*3ac0a46fSAndroid Build Coastguard Worker             x += runs[0];
426*3ac0a46fSAndroid Build Coastguard Worker         }
427*3ac0a46fSAndroid Build Coastguard Worker         run = runs[1];
428*3ac0a46fSAndroid Build Coastguard Worker         if (x + run > lastx || run > lastx)
429*3ac0a46fSAndroid Build Coastguard Worker             run = runs[1] = lastx - x;
430*3ac0a46fSAndroid Build Coastguard Worker         if (run)
431*3ac0a46fSAndroid Build Coastguard Worker         {
432*3ac0a46fSAndroid Build Coastguard Worker             cp = buf + (x >> 3);
433*3ac0a46fSAndroid Build Coastguard Worker             bx = x & 7;
434*3ac0a46fSAndroid Build Coastguard Worker             if (run > 8 - bx)
435*3ac0a46fSAndroid Build Coastguard Worker             {
436*3ac0a46fSAndroid Build Coastguard Worker                 if (bx)
437*3ac0a46fSAndroid Build Coastguard Worker                 { /* align to byte boundary */
438*3ac0a46fSAndroid Build Coastguard Worker                     *cp++ |= 0xff >> bx;
439*3ac0a46fSAndroid Build Coastguard Worker                     run -= 8 - bx;
440*3ac0a46fSAndroid Build Coastguard Worker                 }
441*3ac0a46fSAndroid Build Coastguard Worker                 if ((n = run >> 3) != 0)
442*3ac0a46fSAndroid Build Coastguard Worker                 { /* multiple bytes to fill */
443*3ac0a46fSAndroid Build Coastguard Worker                     if ((n / sizeof(int64_t)) > 1)
444*3ac0a46fSAndroid Build Coastguard Worker                     {
445*3ac0a46fSAndroid Build Coastguard Worker                         /*
446*3ac0a46fSAndroid Build Coastguard Worker                          * Align to int64_t boundary and fill.
447*3ac0a46fSAndroid Build Coastguard Worker                          */
448*3ac0a46fSAndroid Build Coastguard Worker                         for (; n && !isAligned(cp, int64_t); n--)
449*3ac0a46fSAndroid Build Coastguard Worker                             *cp++ = 0xff;
450*3ac0a46fSAndroid Build Coastguard Worker                         lp = (int64_t *)cp;
451*3ac0a46fSAndroid Build Coastguard Worker                         nw = (int32_t)(n / sizeof(int64_t));
452*3ac0a46fSAndroid Build Coastguard Worker                         n -= nw * sizeof(int64_t);
453*3ac0a46fSAndroid Build Coastguard Worker                         do
454*3ac0a46fSAndroid Build Coastguard Worker                         {
455*3ac0a46fSAndroid Build Coastguard Worker                             *lp++ = -1L;
456*3ac0a46fSAndroid Build Coastguard Worker                         } while (--nw);
457*3ac0a46fSAndroid Build Coastguard Worker                         cp = (unsigned char *)lp;
458*3ac0a46fSAndroid Build Coastguard Worker                     }
459*3ac0a46fSAndroid Build Coastguard Worker                     FILL(n, cp);
460*3ac0a46fSAndroid Build Coastguard Worker                     run &= 7;
461*3ac0a46fSAndroid Build Coastguard Worker                 }
462*3ac0a46fSAndroid Build Coastguard Worker                 /* Explicit 0xff masking to make icc -check=conversions happy */
463*3ac0a46fSAndroid Build Coastguard Worker                 if (run)
464*3ac0a46fSAndroid Build Coastguard Worker                     cp[0] = (unsigned char)((cp[0] | (0xff00 >> run)) & 0xff);
465*3ac0a46fSAndroid Build Coastguard Worker             }
466*3ac0a46fSAndroid Build Coastguard Worker             else
467*3ac0a46fSAndroid Build Coastguard Worker                 cp[0] |= _fillmasks[run] >> bx;
468*3ac0a46fSAndroid Build Coastguard Worker             x += runs[1];
469*3ac0a46fSAndroid Build Coastguard Worker         }
470*3ac0a46fSAndroid Build Coastguard Worker     }
471*3ac0a46fSAndroid Build Coastguard Worker     assert(x == lastx);
472*3ac0a46fSAndroid Build Coastguard Worker }
473*3ac0a46fSAndroid Build Coastguard Worker #undef ZERO
474*3ac0a46fSAndroid Build Coastguard Worker #undef FILL
475*3ac0a46fSAndroid Build Coastguard Worker 
Fax3FixupTags(TIFF * tif)476*3ac0a46fSAndroid Build Coastguard Worker static int Fax3FixupTags(TIFF *tif)
477*3ac0a46fSAndroid Build Coastguard Worker {
478*3ac0a46fSAndroid Build Coastguard Worker     (void)tif;
479*3ac0a46fSAndroid Build Coastguard Worker     return (1);
480*3ac0a46fSAndroid Build Coastguard Worker }
481*3ac0a46fSAndroid Build Coastguard Worker 
482*3ac0a46fSAndroid Build Coastguard Worker /*
483*3ac0a46fSAndroid Build Coastguard Worker  * Setup G3/G4-related compression/decompression state
484*3ac0a46fSAndroid Build Coastguard Worker  * before data is processed.  This routine is called once
485*3ac0a46fSAndroid Build Coastguard Worker  * per image -- it sets up different state based on whether
486*3ac0a46fSAndroid Build Coastguard Worker  * or not decoding or encoding is being done and whether
487*3ac0a46fSAndroid Build Coastguard Worker  * 1D- or 2D-encoded data is involved.
488*3ac0a46fSAndroid Build Coastguard Worker  */
Fax3SetupState(TIFF * tif)489*3ac0a46fSAndroid Build Coastguard Worker static int Fax3SetupState(TIFF *tif)
490*3ac0a46fSAndroid Build Coastguard Worker {
491*3ac0a46fSAndroid Build Coastguard Worker     static const char module[] = "Fax3SetupState";
492*3ac0a46fSAndroid Build Coastguard Worker     TIFFDirectory *td = &tif->tif_dir;
493*3ac0a46fSAndroid Build Coastguard Worker     Fax3BaseState *sp = Fax3State(tif);
494*3ac0a46fSAndroid Build Coastguard Worker     int needsRefLine;
495*3ac0a46fSAndroid Build Coastguard Worker     Fax3CodecState *dsp = (Fax3CodecState *)Fax3State(tif);
496*3ac0a46fSAndroid Build Coastguard Worker     tmsize_t rowbytes;
497*3ac0a46fSAndroid Build Coastguard Worker     uint32_t rowpixels;
498*3ac0a46fSAndroid Build Coastguard Worker 
499*3ac0a46fSAndroid Build Coastguard Worker     if (td->td_bitspersample != 1)
500*3ac0a46fSAndroid Build Coastguard Worker     {
501*3ac0a46fSAndroid Build Coastguard Worker         TIFFErrorExtR(tif, module,
502*3ac0a46fSAndroid Build Coastguard Worker                       "Bits/sample must be 1 for Group 3/4 encoding/decoding");
503*3ac0a46fSAndroid Build Coastguard Worker         return (0);
504*3ac0a46fSAndroid Build Coastguard Worker     }
505*3ac0a46fSAndroid Build Coastguard Worker     /*
506*3ac0a46fSAndroid Build Coastguard Worker      * Calculate the scanline/tile widths.
507*3ac0a46fSAndroid Build Coastguard Worker      */
508*3ac0a46fSAndroid Build Coastguard Worker     if (isTiled(tif))
509*3ac0a46fSAndroid Build Coastguard Worker     {
510*3ac0a46fSAndroid Build Coastguard Worker         rowbytes = TIFFTileRowSize(tif);
511*3ac0a46fSAndroid Build Coastguard Worker         rowpixels = td->td_tilewidth;
512*3ac0a46fSAndroid Build Coastguard Worker     }
513*3ac0a46fSAndroid Build Coastguard Worker     else
514*3ac0a46fSAndroid Build Coastguard Worker     {
515*3ac0a46fSAndroid Build Coastguard Worker         rowbytes = TIFFScanlineSize(tif);
516*3ac0a46fSAndroid Build Coastguard Worker         rowpixels = td->td_imagewidth;
517*3ac0a46fSAndroid Build Coastguard Worker     }
518*3ac0a46fSAndroid Build Coastguard Worker     if ((int64_t)rowbytes < ((int64_t)rowpixels + 7) / 8)
519*3ac0a46fSAndroid Build Coastguard Worker     {
520*3ac0a46fSAndroid Build Coastguard Worker         TIFFErrorExtR(tif, module,
521*3ac0a46fSAndroid Build Coastguard Worker                       "Inconsistent number of bytes per row : rowbytes=%" PRId64
522*3ac0a46fSAndroid Build Coastguard Worker                       " rowpixels=%" PRIu32,
523*3ac0a46fSAndroid Build Coastguard Worker                       (int64_t)rowbytes, rowpixels);
524*3ac0a46fSAndroid Build Coastguard Worker         return (0);
525*3ac0a46fSAndroid Build Coastguard Worker     }
526*3ac0a46fSAndroid Build Coastguard Worker     sp->rowbytes = rowbytes;
527*3ac0a46fSAndroid Build Coastguard Worker     sp->rowpixels = rowpixels;
528*3ac0a46fSAndroid Build Coastguard Worker     /*
529*3ac0a46fSAndroid Build Coastguard Worker      * Allocate any additional space required for decoding/encoding.
530*3ac0a46fSAndroid Build Coastguard Worker      */
531*3ac0a46fSAndroid Build Coastguard Worker     needsRefLine = ((sp->groupoptions & GROUP3OPT_2DENCODING) ||
532*3ac0a46fSAndroid Build Coastguard Worker                     td->td_compression == COMPRESSION_CCITTFAX4);
533*3ac0a46fSAndroid Build Coastguard Worker 
534*3ac0a46fSAndroid Build Coastguard Worker     /*
535*3ac0a46fSAndroid Build Coastguard Worker       Assure that allocation computations do not overflow.
536*3ac0a46fSAndroid Build Coastguard Worker 
537*3ac0a46fSAndroid Build Coastguard Worker       TIFFroundup and TIFFSafeMultiply return zero on integer overflow
538*3ac0a46fSAndroid Build Coastguard Worker     */
539*3ac0a46fSAndroid Build Coastguard Worker     dsp->runs = (uint32_t *)NULL;
540*3ac0a46fSAndroid Build Coastguard Worker     dsp->nruns = TIFFroundup_32(rowpixels + 1, 32);
541*3ac0a46fSAndroid Build Coastguard Worker     if (needsRefLine)
542*3ac0a46fSAndroid Build Coastguard Worker     {
543*3ac0a46fSAndroid Build Coastguard Worker         dsp->nruns = TIFFSafeMultiply(uint32_t, dsp->nruns, 2);
544*3ac0a46fSAndroid Build Coastguard Worker     }
545*3ac0a46fSAndroid Build Coastguard Worker     if ((dsp->nruns == 0) || (TIFFSafeMultiply(uint32_t, dsp->nruns, 2) == 0))
546*3ac0a46fSAndroid Build Coastguard Worker     {
547*3ac0a46fSAndroid Build Coastguard Worker         TIFFErrorExtR(tif, tif->tif_name,
548*3ac0a46fSAndroid Build Coastguard Worker                       "Row pixels integer overflow (rowpixels %" PRIu32 ")",
549*3ac0a46fSAndroid Build Coastguard Worker                       rowpixels);
550*3ac0a46fSAndroid Build Coastguard Worker         return (0);
551*3ac0a46fSAndroid Build Coastguard Worker     }
552*3ac0a46fSAndroid Build Coastguard Worker     dsp->runs = (uint32_t *)_TIFFCheckMalloc(
553*3ac0a46fSAndroid Build Coastguard Worker         tif, TIFFSafeMultiply(uint32_t, dsp->nruns, 2), sizeof(uint32_t),
554*3ac0a46fSAndroid Build Coastguard Worker         "for Group 3/4 run arrays");
555*3ac0a46fSAndroid Build Coastguard Worker     if (dsp->runs == NULL)
556*3ac0a46fSAndroid Build Coastguard Worker         return (0);
557*3ac0a46fSAndroid Build Coastguard Worker     memset(dsp->runs, 0,
558*3ac0a46fSAndroid Build Coastguard Worker            TIFFSafeMultiply(uint32_t, dsp->nruns, 2) * sizeof(uint32_t));
559*3ac0a46fSAndroid Build Coastguard Worker     dsp->curruns = dsp->runs;
560*3ac0a46fSAndroid Build Coastguard Worker     if (needsRefLine)
561*3ac0a46fSAndroid Build Coastguard Worker         dsp->refruns = dsp->runs + dsp->nruns;
562*3ac0a46fSAndroid Build Coastguard Worker     else
563*3ac0a46fSAndroid Build Coastguard Worker         dsp->refruns = NULL;
564*3ac0a46fSAndroid Build Coastguard Worker     if (td->td_compression == COMPRESSION_CCITTFAX3 && is2DEncoding(dsp))
565*3ac0a46fSAndroid Build Coastguard Worker     { /* NB: default is 1D routine */
566*3ac0a46fSAndroid Build Coastguard Worker         tif->tif_decoderow = Fax3Decode2D;
567*3ac0a46fSAndroid Build Coastguard Worker         tif->tif_decodestrip = Fax3Decode2D;
568*3ac0a46fSAndroid Build Coastguard Worker         tif->tif_decodetile = Fax3Decode2D;
569*3ac0a46fSAndroid Build Coastguard Worker     }
570*3ac0a46fSAndroid Build Coastguard Worker 
571*3ac0a46fSAndroid Build Coastguard Worker     if (needsRefLine)
572*3ac0a46fSAndroid Build Coastguard Worker     { /* 2d encoding */
573*3ac0a46fSAndroid Build Coastguard Worker         Fax3CodecState *esp = EncoderState(tif);
574*3ac0a46fSAndroid Build Coastguard Worker         /*
575*3ac0a46fSAndroid Build Coastguard Worker          * 2d encoding requires a scanline
576*3ac0a46fSAndroid Build Coastguard Worker          * buffer for the ``reference line''; the
577*3ac0a46fSAndroid Build Coastguard Worker          * scanline against which delta encoding
578*3ac0a46fSAndroid Build Coastguard Worker          * is referenced.  The reference line must
579*3ac0a46fSAndroid Build Coastguard Worker          * be initialized to be ``white'' (done elsewhere).
580*3ac0a46fSAndroid Build Coastguard Worker          */
581*3ac0a46fSAndroid Build Coastguard Worker         esp->refline = (unsigned char *)_TIFFmallocExt(tif, rowbytes);
582*3ac0a46fSAndroid Build Coastguard Worker         if (esp->refline == NULL)
583*3ac0a46fSAndroid Build Coastguard Worker         {
584*3ac0a46fSAndroid Build Coastguard Worker             TIFFErrorExtR(tif, module, "No space for Group 3/4 reference line");
585*3ac0a46fSAndroid Build Coastguard Worker             return (0);
586*3ac0a46fSAndroid Build Coastguard Worker         }
587*3ac0a46fSAndroid Build Coastguard Worker     }
588*3ac0a46fSAndroid Build Coastguard Worker     else /* 1d encoding */
589*3ac0a46fSAndroid Build Coastguard Worker         EncoderState(tif)->refline = NULL;
590*3ac0a46fSAndroid Build Coastguard Worker 
591*3ac0a46fSAndroid Build Coastguard Worker     return (1);
592*3ac0a46fSAndroid Build Coastguard Worker }
593*3ac0a46fSAndroid Build Coastguard Worker 
594*3ac0a46fSAndroid Build Coastguard Worker /*
595*3ac0a46fSAndroid Build Coastguard Worker  * CCITT Group 3 FAX Encoding.
596*3ac0a46fSAndroid Build Coastguard Worker  */
597*3ac0a46fSAndroid Build Coastguard Worker 
598*3ac0a46fSAndroid Build Coastguard Worker #define Fax3FlushBits(tif, sp)                                                 \
599*3ac0a46fSAndroid Build Coastguard Worker     {                                                                          \
600*3ac0a46fSAndroid Build Coastguard Worker         if ((tif)->tif_rawcc >= (tif)->tif_rawdatasize)                        \
601*3ac0a46fSAndroid Build Coastguard Worker         {                                                                      \
602*3ac0a46fSAndroid Build Coastguard Worker             if (!TIFFFlushData1(tif))                                          \
603*3ac0a46fSAndroid Build Coastguard Worker                 return 0;                                                      \
604*3ac0a46fSAndroid Build Coastguard Worker         }                                                                      \
605*3ac0a46fSAndroid Build Coastguard Worker         *(tif)->tif_rawcp++ = (uint8_t)(sp)->data;                             \
606*3ac0a46fSAndroid Build Coastguard Worker         (tif)->tif_rawcc++;                                                    \
607*3ac0a46fSAndroid Build Coastguard Worker         (sp)->data = 0, (sp)->bit = 8;                                         \
608*3ac0a46fSAndroid Build Coastguard Worker     }
609*3ac0a46fSAndroid Build Coastguard Worker #define _FlushBits(tif)                                                        \
610*3ac0a46fSAndroid Build Coastguard Worker     {                                                                          \
611*3ac0a46fSAndroid Build Coastguard Worker         if ((tif)->tif_rawcc >= (tif)->tif_rawdatasize)                        \
612*3ac0a46fSAndroid Build Coastguard Worker         {                                                                      \
613*3ac0a46fSAndroid Build Coastguard Worker             if (!TIFFFlushData1(tif))                                          \
614*3ac0a46fSAndroid Build Coastguard Worker                 return 0;                                                      \
615*3ac0a46fSAndroid Build Coastguard Worker         }                                                                      \
616*3ac0a46fSAndroid Build Coastguard Worker         *(tif)->tif_rawcp++ = (uint8_t)data;                                   \
617*3ac0a46fSAndroid Build Coastguard Worker         (tif)->tif_rawcc++;                                                    \
618*3ac0a46fSAndroid Build Coastguard Worker         data = 0, bit = 8;                                                     \
619*3ac0a46fSAndroid Build Coastguard Worker     }
620*3ac0a46fSAndroid Build Coastguard Worker static const int _msbmask[9] = {0x00, 0x01, 0x03, 0x07, 0x0f,
621*3ac0a46fSAndroid Build Coastguard Worker                                 0x1f, 0x3f, 0x7f, 0xff};
622*3ac0a46fSAndroid Build Coastguard Worker #define _PutBits(tif, bits, length)                                            \
623*3ac0a46fSAndroid Build Coastguard Worker     {                                                                          \
624*3ac0a46fSAndroid Build Coastguard Worker         while (length > bit)                                                   \
625*3ac0a46fSAndroid Build Coastguard Worker         {                                                                      \
626*3ac0a46fSAndroid Build Coastguard Worker             data |= bits >> (length - bit);                                    \
627*3ac0a46fSAndroid Build Coastguard Worker             length -= bit;                                                     \
628*3ac0a46fSAndroid Build Coastguard Worker             _FlushBits(tif);                                                   \
629*3ac0a46fSAndroid Build Coastguard Worker         }                                                                      \
630*3ac0a46fSAndroid Build Coastguard Worker         assert(length < 9);                                                    \
631*3ac0a46fSAndroid Build Coastguard Worker         data |= (bits & _msbmask[length]) << (bit - length);                   \
632*3ac0a46fSAndroid Build Coastguard Worker         bit -= length;                                                         \
633*3ac0a46fSAndroid Build Coastguard Worker         if (bit == 0)                                                          \
634*3ac0a46fSAndroid Build Coastguard Worker             _FlushBits(tif);                                                   \
635*3ac0a46fSAndroid Build Coastguard Worker     }
636*3ac0a46fSAndroid Build Coastguard Worker 
637*3ac0a46fSAndroid Build Coastguard Worker /*
638*3ac0a46fSAndroid Build Coastguard Worker  * Write a variable-length bit-value to
639*3ac0a46fSAndroid Build Coastguard Worker  * the output stream.  Values are
640*3ac0a46fSAndroid Build Coastguard Worker  * assumed to be at most 16 bits.
641*3ac0a46fSAndroid Build Coastguard Worker  */
Fax3PutBits(TIFF * tif,unsigned int bits,unsigned int length)642*3ac0a46fSAndroid Build Coastguard Worker static int Fax3PutBits(TIFF *tif, unsigned int bits, unsigned int length)
643*3ac0a46fSAndroid Build Coastguard Worker {
644*3ac0a46fSAndroid Build Coastguard Worker     Fax3CodecState *sp = EncoderState(tif);
645*3ac0a46fSAndroid Build Coastguard Worker     unsigned int bit = sp->bit;
646*3ac0a46fSAndroid Build Coastguard Worker     int data = sp->data;
647*3ac0a46fSAndroid Build Coastguard Worker 
648*3ac0a46fSAndroid Build Coastguard Worker     _PutBits(tif, bits, length);
649*3ac0a46fSAndroid Build Coastguard Worker 
650*3ac0a46fSAndroid Build Coastguard Worker     sp->data = data;
651*3ac0a46fSAndroid Build Coastguard Worker     sp->bit = bit;
652*3ac0a46fSAndroid Build Coastguard Worker     return 1;
653*3ac0a46fSAndroid Build Coastguard Worker }
654*3ac0a46fSAndroid Build Coastguard Worker 
655*3ac0a46fSAndroid Build Coastguard Worker /*
656*3ac0a46fSAndroid Build Coastguard Worker  * Write a code to the output stream.
657*3ac0a46fSAndroid Build Coastguard Worker  */
658*3ac0a46fSAndroid Build Coastguard Worker #define putcode(tif, te) Fax3PutBits(tif, (te)->code, (te)->length)
659*3ac0a46fSAndroid Build Coastguard Worker 
660*3ac0a46fSAndroid Build Coastguard Worker #ifdef FAX3_DEBUG
661*3ac0a46fSAndroid Build Coastguard Worker #define DEBUG_COLOR(w) (tab == TIFFFaxWhiteCodes ? w "W" : w "B")
662*3ac0a46fSAndroid Build Coastguard Worker #define DEBUG_PRINT(what, len)                                                 \
663*3ac0a46fSAndroid Build Coastguard Worker     {                                                                          \
664*3ac0a46fSAndroid Build Coastguard Worker         int t;                                                                 \
665*3ac0a46fSAndroid Build Coastguard Worker         printf("%08" PRIX32 "/%-2d: %s%5d\t", data, bit, DEBUG_COLOR(what),    \
666*3ac0a46fSAndroid Build Coastguard Worker                len);                                                           \
667*3ac0a46fSAndroid Build Coastguard Worker         for (t = length - 1; t >= 0; t--)                                      \
668*3ac0a46fSAndroid Build Coastguard Worker             putchar(code & (1 << t) ? '1' : '0');                              \
669*3ac0a46fSAndroid Build Coastguard Worker         putchar('\n');                                                         \
670*3ac0a46fSAndroid Build Coastguard Worker     }
671*3ac0a46fSAndroid Build Coastguard Worker #endif
672*3ac0a46fSAndroid Build Coastguard Worker 
673*3ac0a46fSAndroid Build Coastguard Worker /*
674*3ac0a46fSAndroid Build Coastguard Worker  * Write the sequence of codes that describes
675*3ac0a46fSAndroid Build Coastguard Worker  * the specified span of zero's or one's.  The
676*3ac0a46fSAndroid Build Coastguard Worker  * appropriate table that holds the make-up and
677*3ac0a46fSAndroid Build Coastguard Worker  * terminating codes is supplied.
678*3ac0a46fSAndroid Build Coastguard Worker  */
putspan(TIFF * tif,int32_t span,const tableentry * tab)679*3ac0a46fSAndroid Build Coastguard Worker static int putspan(TIFF *tif, int32_t span, const tableentry *tab)
680*3ac0a46fSAndroid Build Coastguard Worker {
681*3ac0a46fSAndroid Build Coastguard Worker     Fax3CodecState *sp = EncoderState(tif);
682*3ac0a46fSAndroid Build Coastguard Worker     unsigned int bit = sp->bit;
683*3ac0a46fSAndroid Build Coastguard Worker     int data = sp->data;
684*3ac0a46fSAndroid Build Coastguard Worker     unsigned int code, length;
685*3ac0a46fSAndroid Build Coastguard Worker 
686*3ac0a46fSAndroid Build Coastguard Worker     while (span >= 2624)
687*3ac0a46fSAndroid Build Coastguard Worker     {
688*3ac0a46fSAndroid Build Coastguard Worker         const tableentry *te = &tab[63 + (2560 >> 6)];
689*3ac0a46fSAndroid Build Coastguard Worker         code = te->code;
690*3ac0a46fSAndroid Build Coastguard Worker         length = te->length;
691*3ac0a46fSAndroid Build Coastguard Worker #ifdef FAX3_DEBUG
692*3ac0a46fSAndroid Build Coastguard Worker         DEBUG_PRINT("MakeUp", te->runlen);
693*3ac0a46fSAndroid Build Coastguard Worker #endif
694*3ac0a46fSAndroid Build Coastguard Worker         _PutBits(tif, code, length);
695*3ac0a46fSAndroid Build Coastguard Worker         span -= te->runlen;
696*3ac0a46fSAndroid Build Coastguard Worker     }
697*3ac0a46fSAndroid Build Coastguard Worker     if (span >= 64)
698*3ac0a46fSAndroid Build Coastguard Worker     {
699*3ac0a46fSAndroid Build Coastguard Worker         const tableentry *te = &tab[63 + (span >> 6)];
700*3ac0a46fSAndroid Build Coastguard Worker         assert(te->runlen == 64 * (span >> 6));
701*3ac0a46fSAndroid Build Coastguard Worker         code = te->code;
702*3ac0a46fSAndroid Build Coastguard Worker         length = te->length;
703*3ac0a46fSAndroid Build Coastguard Worker #ifdef FAX3_DEBUG
704*3ac0a46fSAndroid Build Coastguard Worker         DEBUG_PRINT("MakeUp", te->runlen);
705*3ac0a46fSAndroid Build Coastguard Worker #endif
706*3ac0a46fSAndroid Build Coastguard Worker         _PutBits(tif, code, length);
707*3ac0a46fSAndroid Build Coastguard Worker         span -= te->runlen;
708*3ac0a46fSAndroid Build Coastguard Worker     }
709*3ac0a46fSAndroid Build Coastguard Worker     code = tab[span].code;
710*3ac0a46fSAndroid Build Coastguard Worker     length = tab[span].length;
711*3ac0a46fSAndroid Build Coastguard Worker #ifdef FAX3_DEBUG
712*3ac0a46fSAndroid Build Coastguard Worker     DEBUG_PRINT("  Term", tab[span].runlen);
713*3ac0a46fSAndroid Build Coastguard Worker #endif
714*3ac0a46fSAndroid Build Coastguard Worker     _PutBits(tif, code, length);
715*3ac0a46fSAndroid Build Coastguard Worker 
716*3ac0a46fSAndroid Build Coastguard Worker     sp->data = data;
717*3ac0a46fSAndroid Build Coastguard Worker     sp->bit = bit;
718*3ac0a46fSAndroid Build Coastguard Worker 
719*3ac0a46fSAndroid Build Coastguard Worker     return 1;
720*3ac0a46fSAndroid Build Coastguard Worker }
721*3ac0a46fSAndroid Build Coastguard Worker 
722*3ac0a46fSAndroid Build Coastguard Worker /*
723*3ac0a46fSAndroid Build Coastguard Worker  * Write an EOL code to the output stream.  The zero-fill
724*3ac0a46fSAndroid Build Coastguard Worker  * logic for byte-aligning encoded scanlines is handled
725*3ac0a46fSAndroid Build Coastguard Worker  * here.  We also handle writing the tag bit for the next
726*3ac0a46fSAndroid Build Coastguard Worker  * scanline when doing 2d encoding.
727*3ac0a46fSAndroid Build Coastguard Worker  */
Fax3PutEOL(TIFF * tif)728*3ac0a46fSAndroid Build Coastguard Worker static int Fax3PutEOL(TIFF *tif)
729*3ac0a46fSAndroid Build Coastguard Worker {
730*3ac0a46fSAndroid Build Coastguard Worker     Fax3CodecState *sp = EncoderState(tif);
731*3ac0a46fSAndroid Build Coastguard Worker     unsigned int bit = sp->bit;
732*3ac0a46fSAndroid Build Coastguard Worker     int data = sp->data;
733*3ac0a46fSAndroid Build Coastguard Worker     unsigned int code, length, tparm;
734*3ac0a46fSAndroid Build Coastguard Worker 
735*3ac0a46fSAndroid Build Coastguard Worker     if (sp->b.groupoptions & GROUP3OPT_FILLBITS)
736*3ac0a46fSAndroid Build Coastguard Worker     {
737*3ac0a46fSAndroid Build Coastguard Worker         /*
738*3ac0a46fSAndroid Build Coastguard Worker          * Force bit alignment so EOL will terminate on
739*3ac0a46fSAndroid Build Coastguard Worker          * a byte boundary.  That is, force the bit alignment
740*3ac0a46fSAndroid Build Coastguard Worker          * to 16-12 = 4 before putting out the EOL code.
741*3ac0a46fSAndroid Build Coastguard Worker          */
742*3ac0a46fSAndroid Build Coastguard Worker         int align = 8 - 4;
743*3ac0a46fSAndroid Build Coastguard Worker         if (align != sp->bit)
744*3ac0a46fSAndroid Build Coastguard Worker         {
745*3ac0a46fSAndroid Build Coastguard Worker             if (align > sp->bit)
746*3ac0a46fSAndroid Build Coastguard Worker                 align = sp->bit + (8 - align);
747*3ac0a46fSAndroid Build Coastguard Worker             else
748*3ac0a46fSAndroid Build Coastguard Worker                 align = sp->bit - align;
749*3ac0a46fSAndroid Build Coastguard Worker             tparm = align;
750*3ac0a46fSAndroid Build Coastguard Worker             _PutBits(tif, 0, tparm);
751*3ac0a46fSAndroid Build Coastguard Worker         }
752*3ac0a46fSAndroid Build Coastguard Worker     }
753*3ac0a46fSAndroid Build Coastguard Worker     code = EOL;
754*3ac0a46fSAndroid Build Coastguard Worker     length = 12;
755*3ac0a46fSAndroid Build Coastguard Worker     if (is2DEncoding(sp))
756*3ac0a46fSAndroid Build Coastguard Worker     {
757*3ac0a46fSAndroid Build Coastguard Worker         code = (code << 1) | (sp->tag == G3_1D);
758*3ac0a46fSAndroid Build Coastguard Worker         length++;
759*3ac0a46fSAndroid Build Coastguard Worker     }
760*3ac0a46fSAndroid Build Coastguard Worker     _PutBits(tif, code, length);
761*3ac0a46fSAndroid Build Coastguard Worker 
762*3ac0a46fSAndroid Build Coastguard Worker     sp->data = data;
763*3ac0a46fSAndroid Build Coastguard Worker     sp->bit = bit;
764*3ac0a46fSAndroid Build Coastguard Worker 
765*3ac0a46fSAndroid Build Coastguard Worker     return 1;
766*3ac0a46fSAndroid Build Coastguard Worker }
767*3ac0a46fSAndroid Build Coastguard Worker 
768*3ac0a46fSAndroid Build Coastguard Worker /*
769*3ac0a46fSAndroid Build Coastguard Worker  * Reset encoding state at the start of a strip.
770*3ac0a46fSAndroid Build Coastguard Worker  */
Fax3PreEncode(TIFF * tif,uint16_t s)771*3ac0a46fSAndroid Build Coastguard Worker static int Fax3PreEncode(TIFF *tif, uint16_t s)
772*3ac0a46fSAndroid Build Coastguard Worker {
773*3ac0a46fSAndroid Build Coastguard Worker     Fax3CodecState *sp = EncoderState(tif);
774*3ac0a46fSAndroid Build Coastguard Worker 
775*3ac0a46fSAndroid Build Coastguard Worker     (void)s;
776*3ac0a46fSAndroid Build Coastguard Worker     assert(sp != NULL);
777*3ac0a46fSAndroid Build Coastguard Worker     sp->bit = 8;
778*3ac0a46fSAndroid Build Coastguard Worker     sp->data = 0;
779*3ac0a46fSAndroid Build Coastguard Worker     sp->tag = G3_1D;
780*3ac0a46fSAndroid Build Coastguard Worker     /*
781*3ac0a46fSAndroid Build Coastguard Worker      * This is necessary for Group 4; otherwise it isn't
782*3ac0a46fSAndroid Build Coastguard Worker      * needed because the first scanline of each strip ends
783*3ac0a46fSAndroid Build Coastguard Worker      * up being copied into the refline.
784*3ac0a46fSAndroid Build Coastguard Worker      */
785*3ac0a46fSAndroid Build Coastguard Worker     if (sp->refline)
786*3ac0a46fSAndroid Build Coastguard Worker         _TIFFmemset(sp->refline, 0x00, sp->b.rowbytes);
787*3ac0a46fSAndroid Build Coastguard Worker     if (is2DEncoding(sp))
788*3ac0a46fSAndroid Build Coastguard Worker     {
789*3ac0a46fSAndroid Build Coastguard Worker         float res = tif->tif_dir.td_yresolution;
790*3ac0a46fSAndroid Build Coastguard Worker         /*
791*3ac0a46fSAndroid Build Coastguard Worker          * The CCITT spec says that when doing 2d encoding, you
792*3ac0a46fSAndroid Build Coastguard Worker          * should only do it on K consecutive scanlines, where K
793*3ac0a46fSAndroid Build Coastguard Worker          * depends on the resolution of the image being encoded
794*3ac0a46fSAndroid Build Coastguard Worker          * (2 for <= 200 lpi, 4 for > 200 lpi).  Since the directory
795*3ac0a46fSAndroid Build Coastguard Worker          * code initializes td_yresolution to 0, this code will
796*3ac0a46fSAndroid Build Coastguard Worker          * select a K of 2 unless the YResolution tag is set
797*3ac0a46fSAndroid Build Coastguard Worker          * appropriately.  (Note also that we fudge a little here
798*3ac0a46fSAndroid Build Coastguard Worker          * and use 150 lpi to avoid problems with units conversion.)
799*3ac0a46fSAndroid Build Coastguard Worker          */
800*3ac0a46fSAndroid Build Coastguard Worker         if (tif->tif_dir.td_resolutionunit == RESUNIT_CENTIMETER)
801*3ac0a46fSAndroid Build Coastguard Worker             res *= 2.54f; /* convert to inches */
802*3ac0a46fSAndroid Build Coastguard Worker         sp->maxk = (res > 150 ? 4 : 2);
803*3ac0a46fSAndroid Build Coastguard Worker         sp->k = sp->maxk - 1;
804*3ac0a46fSAndroid Build Coastguard Worker     }
805*3ac0a46fSAndroid Build Coastguard Worker     else
806*3ac0a46fSAndroid Build Coastguard Worker         sp->k = sp->maxk = 0;
807*3ac0a46fSAndroid Build Coastguard Worker     sp->line = 0;
808*3ac0a46fSAndroid Build Coastguard Worker     return (1);
809*3ac0a46fSAndroid Build Coastguard Worker }
810*3ac0a46fSAndroid Build Coastguard Worker 
811*3ac0a46fSAndroid Build Coastguard Worker static const unsigned char zeroruns[256] = {
812*3ac0a46fSAndroid Build Coastguard Worker     8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, /* 0x00 - 0x0f */
813*3ac0a46fSAndroid Build Coastguard Worker     3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 0x10 - 0x1f */
814*3ac0a46fSAndroid Build Coastguard Worker     2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0x20 - 0x2f */
815*3ac0a46fSAndroid Build Coastguard Worker     2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0x30 - 0x3f */
816*3ac0a46fSAndroid Build Coastguard Worker     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x40 - 0x4f */
817*3ac0a46fSAndroid Build Coastguard Worker     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x50 - 0x5f */
818*3ac0a46fSAndroid Build Coastguard Worker     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x60 - 0x6f */
819*3ac0a46fSAndroid Build Coastguard Worker     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x70 - 0x7f */
820*3ac0a46fSAndroid Build Coastguard Worker     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80 - 0x8f */
821*3ac0a46fSAndroid Build Coastguard Worker     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90 - 0x9f */
822*3ac0a46fSAndroid Build Coastguard Worker     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xa0 - 0xaf */
823*3ac0a46fSAndroid Build Coastguard Worker     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xb0 - 0xbf */
824*3ac0a46fSAndroid Build Coastguard Worker     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xc0 - 0xcf */
825*3ac0a46fSAndroid Build Coastguard Worker     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xd0 - 0xdf */
826*3ac0a46fSAndroid Build Coastguard Worker     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xe0 - 0xef */
827*3ac0a46fSAndroid Build Coastguard Worker     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xf0 - 0xff */
828*3ac0a46fSAndroid Build Coastguard Worker };
829*3ac0a46fSAndroid Build Coastguard Worker static const unsigned char oneruns[256] = {
830*3ac0a46fSAndroid Build Coastguard Worker     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00 - 0x0f */
831*3ac0a46fSAndroid Build Coastguard Worker     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10 - 0x1f */
832*3ac0a46fSAndroid Build Coastguard Worker     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20 - 0x2f */
833*3ac0a46fSAndroid Build Coastguard Worker     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x30 - 0x3f */
834*3ac0a46fSAndroid Build Coastguard Worker     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x40 - 0x4f */
835*3ac0a46fSAndroid Build Coastguard Worker     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x50 - 0x5f */
836*3ac0a46fSAndroid Build Coastguard Worker     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60 - 0x6f */
837*3ac0a46fSAndroid Build Coastguard Worker     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70 - 0x7f */
838*3ac0a46fSAndroid Build Coastguard Worker     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x80 - 0x8f */
839*3ac0a46fSAndroid Build Coastguard Worker     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x90 - 0x9f */
840*3ac0a46fSAndroid Build Coastguard Worker     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0xa0 - 0xaf */
841*3ac0a46fSAndroid Build Coastguard Worker     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0xb0 - 0xbf */
842*3ac0a46fSAndroid Build Coastguard Worker     2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0xc0 - 0xcf */
843*3ac0a46fSAndroid Build Coastguard Worker     2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0xd0 - 0xdf */
844*3ac0a46fSAndroid Build Coastguard Worker     3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 0xe0 - 0xef */
845*3ac0a46fSAndroid Build Coastguard Worker     4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 7, 8, /* 0xf0 - 0xff */
846*3ac0a46fSAndroid Build Coastguard Worker };
847*3ac0a46fSAndroid Build Coastguard Worker 
848*3ac0a46fSAndroid Build Coastguard Worker /*
849*3ac0a46fSAndroid Build Coastguard Worker  * Find a span of ones or zeros using the supplied
850*3ac0a46fSAndroid Build Coastguard Worker  * table.  The ``base'' of the bit string is supplied
851*3ac0a46fSAndroid Build Coastguard Worker  * along with the start+end bit indices.
852*3ac0a46fSAndroid Build Coastguard Worker  */
find0span(unsigned char * bp,int32_t bs,int32_t be)853*3ac0a46fSAndroid Build Coastguard Worker static inline int32_t find0span(unsigned char *bp, int32_t bs, int32_t be)
854*3ac0a46fSAndroid Build Coastguard Worker {
855*3ac0a46fSAndroid Build Coastguard Worker     int32_t bits = be - bs;
856*3ac0a46fSAndroid Build Coastguard Worker     int32_t n, span;
857*3ac0a46fSAndroid Build Coastguard Worker 
858*3ac0a46fSAndroid Build Coastguard Worker     bp += bs >> 3;
859*3ac0a46fSAndroid Build Coastguard Worker     /*
860*3ac0a46fSAndroid Build Coastguard Worker      * Check partial byte on lhs.
861*3ac0a46fSAndroid Build Coastguard Worker      */
862*3ac0a46fSAndroid Build Coastguard Worker     if (bits > 0 && (n = (bs & 7)) != 0)
863*3ac0a46fSAndroid Build Coastguard Worker     {
864*3ac0a46fSAndroid Build Coastguard Worker         span = zeroruns[(*bp << n) & 0xff];
865*3ac0a46fSAndroid Build Coastguard Worker         if (span > 8 - n) /* table value too generous */
866*3ac0a46fSAndroid Build Coastguard Worker             span = 8 - n;
867*3ac0a46fSAndroid Build Coastguard Worker         if (span > bits) /* constrain span to bit range */
868*3ac0a46fSAndroid Build Coastguard Worker             span = bits;
869*3ac0a46fSAndroid Build Coastguard Worker         if (n + span < 8) /* doesn't extend to edge of byte */
870*3ac0a46fSAndroid Build Coastguard Worker             return (span);
871*3ac0a46fSAndroid Build Coastguard Worker         bits -= span;
872*3ac0a46fSAndroid Build Coastguard Worker         bp++;
873*3ac0a46fSAndroid Build Coastguard Worker     }
874*3ac0a46fSAndroid Build Coastguard Worker     else
875*3ac0a46fSAndroid Build Coastguard Worker         span = 0;
876*3ac0a46fSAndroid Build Coastguard Worker     if (bits >= (int32_t)(2 * 8 * sizeof(int64_t)))
877*3ac0a46fSAndroid Build Coastguard Worker     {
878*3ac0a46fSAndroid Build Coastguard Worker         int64_t *lp;
879*3ac0a46fSAndroid Build Coastguard Worker         /*
880*3ac0a46fSAndroid Build Coastguard Worker          * Align to int64_t boundary and check int64_t words.
881*3ac0a46fSAndroid Build Coastguard Worker          */
882*3ac0a46fSAndroid Build Coastguard Worker         while (!isAligned(bp, int64_t))
883*3ac0a46fSAndroid Build Coastguard Worker         {
884*3ac0a46fSAndroid Build Coastguard Worker             if (*bp != 0x00)
885*3ac0a46fSAndroid Build Coastguard Worker                 return (span + zeroruns[*bp]);
886*3ac0a46fSAndroid Build Coastguard Worker             span += 8;
887*3ac0a46fSAndroid Build Coastguard Worker             bits -= 8;
888*3ac0a46fSAndroid Build Coastguard Worker             bp++;
889*3ac0a46fSAndroid Build Coastguard Worker         }
890*3ac0a46fSAndroid Build Coastguard Worker         lp = (int64_t *)bp;
891*3ac0a46fSAndroid Build Coastguard Worker         while ((bits >= (int32_t)(8 * sizeof(int64_t))) && (0 == *lp))
892*3ac0a46fSAndroid Build Coastguard Worker         {
893*3ac0a46fSAndroid Build Coastguard Worker             span += 8 * sizeof(int64_t);
894*3ac0a46fSAndroid Build Coastguard Worker             bits -= 8 * sizeof(int64_t);
895*3ac0a46fSAndroid Build Coastguard Worker             lp++;
896*3ac0a46fSAndroid Build Coastguard Worker         }
897*3ac0a46fSAndroid Build Coastguard Worker         bp = (unsigned char *)lp;
898*3ac0a46fSAndroid Build Coastguard Worker     }
899*3ac0a46fSAndroid Build Coastguard Worker     /*
900*3ac0a46fSAndroid Build Coastguard Worker      * Scan full bytes for all 0's.
901*3ac0a46fSAndroid Build Coastguard Worker      */
902*3ac0a46fSAndroid Build Coastguard Worker     while (bits >= 8)
903*3ac0a46fSAndroid Build Coastguard Worker     {
904*3ac0a46fSAndroid Build Coastguard Worker         if (*bp != 0x00) /* end of run */
905*3ac0a46fSAndroid Build Coastguard Worker             return (span + zeroruns[*bp]);
906*3ac0a46fSAndroid Build Coastguard Worker         span += 8;
907*3ac0a46fSAndroid Build Coastguard Worker         bits -= 8;
908*3ac0a46fSAndroid Build Coastguard Worker         bp++;
909*3ac0a46fSAndroid Build Coastguard Worker     }
910*3ac0a46fSAndroid Build Coastguard Worker     /*
911*3ac0a46fSAndroid Build Coastguard Worker      * Check partial byte on rhs.
912*3ac0a46fSAndroid Build Coastguard Worker      */
913*3ac0a46fSAndroid Build Coastguard Worker     if (bits > 0)
914*3ac0a46fSAndroid Build Coastguard Worker     {
915*3ac0a46fSAndroid Build Coastguard Worker         n = zeroruns[*bp];
916*3ac0a46fSAndroid Build Coastguard Worker         span += (n > bits ? bits : n);
917*3ac0a46fSAndroid Build Coastguard Worker     }
918*3ac0a46fSAndroid Build Coastguard Worker     return (span);
919*3ac0a46fSAndroid Build Coastguard Worker }
920*3ac0a46fSAndroid Build Coastguard Worker 
find1span(unsigned char * bp,int32_t bs,int32_t be)921*3ac0a46fSAndroid Build Coastguard Worker static inline int32_t find1span(unsigned char *bp, int32_t bs, int32_t be)
922*3ac0a46fSAndroid Build Coastguard Worker {
923*3ac0a46fSAndroid Build Coastguard Worker     int32_t bits = be - bs;
924*3ac0a46fSAndroid Build Coastguard Worker     int32_t n, span;
925*3ac0a46fSAndroid Build Coastguard Worker 
926*3ac0a46fSAndroid Build Coastguard Worker     bp += bs >> 3;
927*3ac0a46fSAndroid Build Coastguard Worker     /*
928*3ac0a46fSAndroid Build Coastguard Worker      * Check partial byte on lhs.
929*3ac0a46fSAndroid Build Coastguard Worker      */
930*3ac0a46fSAndroid Build Coastguard Worker     if (bits > 0 && (n = (bs & 7)) != 0)
931*3ac0a46fSAndroid Build Coastguard Worker     {
932*3ac0a46fSAndroid Build Coastguard Worker         span = oneruns[(*bp << n) & 0xff];
933*3ac0a46fSAndroid Build Coastguard Worker         if (span > 8 - n) /* table value too generous */
934*3ac0a46fSAndroid Build Coastguard Worker             span = 8 - n;
935*3ac0a46fSAndroid Build Coastguard Worker         if (span > bits) /* constrain span to bit range */
936*3ac0a46fSAndroid Build Coastguard Worker             span = bits;
937*3ac0a46fSAndroid Build Coastguard Worker         if (n + span < 8) /* doesn't extend to edge of byte */
938*3ac0a46fSAndroid Build Coastguard Worker             return (span);
939*3ac0a46fSAndroid Build Coastguard Worker         bits -= span;
940*3ac0a46fSAndroid Build Coastguard Worker         bp++;
941*3ac0a46fSAndroid Build Coastguard Worker     }
942*3ac0a46fSAndroid Build Coastguard Worker     else
943*3ac0a46fSAndroid Build Coastguard Worker         span = 0;
944*3ac0a46fSAndroid Build Coastguard Worker     if (bits >= (int32_t)(2 * 8 * sizeof(int64_t)))
945*3ac0a46fSAndroid Build Coastguard Worker     {
946*3ac0a46fSAndroid Build Coastguard Worker         int64_t *lp;
947*3ac0a46fSAndroid Build Coastguard Worker         /*
948*3ac0a46fSAndroid Build Coastguard Worker          * Align to int64_t boundary and check int64_t words.
949*3ac0a46fSAndroid Build Coastguard Worker          */
950*3ac0a46fSAndroid Build Coastguard Worker         while (!isAligned(bp, int64_t))
951*3ac0a46fSAndroid Build Coastguard Worker         {
952*3ac0a46fSAndroid Build Coastguard Worker             if (*bp != 0xff)
953*3ac0a46fSAndroid Build Coastguard Worker                 return (span + oneruns[*bp]);
954*3ac0a46fSAndroid Build Coastguard Worker             span += 8;
955*3ac0a46fSAndroid Build Coastguard Worker             bits -= 8;
956*3ac0a46fSAndroid Build Coastguard Worker             bp++;
957*3ac0a46fSAndroid Build Coastguard Worker         }
958*3ac0a46fSAndroid Build Coastguard Worker         lp = (int64_t *)bp;
959*3ac0a46fSAndroid Build Coastguard Worker         while ((bits >= (int32_t)(8 * sizeof(int64_t))) &&
960*3ac0a46fSAndroid Build Coastguard Worker                (~((uint64_t)0) == (uint64_t)*lp))
961*3ac0a46fSAndroid Build Coastguard Worker         {
962*3ac0a46fSAndroid Build Coastguard Worker             span += 8 * sizeof(int64_t);
963*3ac0a46fSAndroid Build Coastguard Worker             bits -= 8 * sizeof(int64_t);
964*3ac0a46fSAndroid Build Coastguard Worker             lp++;
965*3ac0a46fSAndroid Build Coastguard Worker         }
966*3ac0a46fSAndroid Build Coastguard Worker         bp = (unsigned char *)lp;
967*3ac0a46fSAndroid Build Coastguard Worker     }
968*3ac0a46fSAndroid Build Coastguard Worker     /*
969*3ac0a46fSAndroid Build Coastguard Worker      * Scan full bytes for all 1's.
970*3ac0a46fSAndroid Build Coastguard Worker      */
971*3ac0a46fSAndroid Build Coastguard Worker     while (bits >= 8)
972*3ac0a46fSAndroid Build Coastguard Worker     {
973*3ac0a46fSAndroid Build Coastguard Worker         if (*bp != 0xff) /* end of run */
974*3ac0a46fSAndroid Build Coastguard Worker             return (span + oneruns[*bp]);
975*3ac0a46fSAndroid Build Coastguard Worker         span += 8;
976*3ac0a46fSAndroid Build Coastguard Worker         bits -= 8;
977*3ac0a46fSAndroid Build Coastguard Worker         bp++;
978*3ac0a46fSAndroid Build Coastguard Worker     }
979*3ac0a46fSAndroid Build Coastguard Worker     /*
980*3ac0a46fSAndroid Build Coastguard Worker      * Check partial byte on rhs.
981*3ac0a46fSAndroid Build Coastguard Worker      */
982*3ac0a46fSAndroid Build Coastguard Worker     if (bits > 0)
983*3ac0a46fSAndroid Build Coastguard Worker     {
984*3ac0a46fSAndroid Build Coastguard Worker         n = oneruns[*bp];
985*3ac0a46fSAndroid Build Coastguard Worker         span += (n > bits ? bits : n);
986*3ac0a46fSAndroid Build Coastguard Worker     }
987*3ac0a46fSAndroid Build Coastguard Worker     return (span);
988*3ac0a46fSAndroid Build Coastguard Worker }
989*3ac0a46fSAndroid Build Coastguard Worker 
990*3ac0a46fSAndroid Build Coastguard Worker /*
991*3ac0a46fSAndroid Build Coastguard Worker  * Return the offset of the next bit in the range
992*3ac0a46fSAndroid Build Coastguard Worker  * [bs..be] that is different from the specified
993*3ac0a46fSAndroid Build Coastguard Worker  * color.  The end, be, is returned if no such bit
994*3ac0a46fSAndroid Build Coastguard Worker  * exists.
995*3ac0a46fSAndroid Build Coastguard Worker  */
996*3ac0a46fSAndroid Build Coastguard Worker #define finddiff(_cp, _bs, _be, _color)                                        \
997*3ac0a46fSAndroid Build Coastguard Worker     (_bs + (_color ? find1span(_cp, _bs, _be) : find0span(_cp, _bs, _be)))
998*3ac0a46fSAndroid Build Coastguard Worker /*
999*3ac0a46fSAndroid Build Coastguard Worker  * Like finddiff, but also check the starting bit
1000*3ac0a46fSAndroid Build Coastguard Worker  * against the end in case start > end.
1001*3ac0a46fSAndroid Build Coastguard Worker  */
1002*3ac0a46fSAndroid Build Coastguard Worker #define finddiff2(_cp, _bs, _be, _color)                                       \
1003*3ac0a46fSAndroid Build Coastguard Worker     (_bs < _be ? finddiff(_cp, _bs, _be, _color) : _be)
1004*3ac0a46fSAndroid Build Coastguard Worker 
1005*3ac0a46fSAndroid Build Coastguard Worker /*
1006*3ac0a46fSAndroid Build Coastguard Worker  * 1d-encode a row of pixels.  The encoding is
1007*3ac0a46fSAndroid Build Coastguard Worker  * a sequence of all-white or all-black spans
1008*3ac0a46fSAndroid Build Coastguard Worker  * of pixels encoded with Huffman codes.
1009*3ac0a46fSAndroid Build Coastguard Worker  */
Fax3Encode1DRow(TIFF * tif,unsigned char * bp,uint32_t bits)1010*3ac0a46fSAndroid Build Coastguard Worker static int Fax3Encode1DRow(TIFF *tif, unsigned char *bp, uint32_t bits)
1011*3ac0a46fSAndroid Build Coastguard Worker {
1012*3ac0a46fSAndroid Build Coastguard Worker     Fax3CodecState *sp = EncoderState(tif);
1013*3ac0a46fSAndroid Build Coastguard Worker     int32_t span;
1014*3ac0a46fSAndroid Build Coastguard Worker     uint32_t bs = 0;
1015*3ac0a46fSAndroid Build Coastguard Worker 
1016*3ac0a46fSAndroid Build Coastguard Worker     for (;;)
1017*3ac0a46fSAndroid Build Coastguard Worker     {
1018*3ac0a46fSAndroid Build Coastguard Worker         span = find0span(bp, bs, bits); /* white span */
1019*3ac0a46fSAndroid Build Coastguard Worker         if (!putspan(tif, span, TIFFFaxWhiteCodes))
1020*3ac0a46fSAndroid Build Coastguard Worker             return 0;
1021*3ac0a46fSAndroid Build Coastguard Worker         bs += span;
1022*3ac0a46fSAndroid Build Coastguard Worker         if (bs >= bits)
1023*3ac0a46fSAndroid Build Coastguard Worker             break;
1024*3ac0a46fSAndroid Build Coastguard Worker         span = find1span(bp, bs, bits); /* black span */
1025*3ac0a46fSAndroid Build Coastguard Worker         if (!putspan(tif, span, TIFFFaxBlackCodes))
1026*3ac0a46fSAndroid Build Coastguard Worker             return 0;
1027*3ac0a46fSAndroid Build Coastguard Worker         bs += span;
1028*3ac0a46fSAndroid Build Coastguard Worker         if (bs >= bits)
1029*3ac0a46fSAndroid Build Coastguard Worker             break;
1030*3ac0a46fSAndroid Build Coastguard Worker     }
1031*3ac0a46fSAndroid Build Coastguard Worker     if (sp->b.mode & (FAXMODE_BYTEALIGN | FAXMODE_WORDALIGN))
1032*3ac0a46fSAndroid Build Coastguard Worker     {
1033*3ac0a46fSAndroid Build Coastguard Worker         if (sp->bit != 8) /* byte-align */
1034*3ac0a46fSAndroid Build Coastguard Worker             Fax3FlushBits(tif, sp);
1035*3ac0a46fSAndroid Build Coastguard Worker         if ((sp->b.mode & FAXMODE_WORDALIGN) &&
1036*3ac0a46fSAndroid Build Coastguard Worker             !isAligned(tif->tif_rawcp, uint16_t))
1037*3ac0a46fSAndroid Build Coastguard Worker             Fax3FlushBits(tif, sp);
1038*3ac0a46fSAndroid Build Coastguard Worker     }
1039*3ac0a46fSAndroid Build Coastguard Worker     return (1);
1040*3ac0a46fSAndroid Build Coastguard Worker }
1041*3ac0a46fSAndroid Build Coastguard Worker 
1042*3ac0a46fSAndroid Build Coastguard Worker static const tableentry horizcode = {3, 0x1, 0}; /* 001 */
1043*3ac0a46fSAndroid Build Coastguard Worker static const tableentry passcode = {4, 0x1, 0};  /* 0001 */
1044*3ac0a46fSAndroid Build Coastguard Worker static const tableentry vcodes[7] = {
1045*3ac0a46fSAndroid Build Coastguard Worker     {7, 0x03, 0}, /* 0000 011 */
1046*3ac0a46fSAndroid Build Coastguard Worker     {6, 0x03, 0}, /* 0000 11 */
1047*3ac0a46fSAndroid Build Coastguard Worker     {3, 0x03, 0}, /* 011 */
1048*3ac0a46fSAndroid Build Coastguard Worker     {1, 0x1, 0},  /* 1 */
1049*3ac0a46fSAndroid Build Coastguard Worker     {3, 0x2, 0},  /* 010 */
1050*3ac0a46fSAndroid Build Coastguard Worker     {6, 0x02, 0}, /* 0000 10 */
1051*3ac0a46fSAndroid Build Coastguard Worker     {7, 0x02, 0}  /* 0000 010 */
1052*3ac0a46fSAndroid Build Coastguard Worker };
1053*3ac0a46fSAndroid Build Coastguard Worker 
1054*3ac0a46fSAndroid Build Coastguard Worker /*
1055*3ac0a46fSAndroid Build Coastguard Worker  * 2d-encode a row of pixels.  Consult the CCITT
1056*3ac0a46fSAndroid Build Coastguard Worker  * documentation for the algorithm.
1057*3ac0a46fSAndroid Build Coastguard Worker  */
Fax3Encode2DRow(TIFF * tif,unsigned char * bp,unsigned char * rp,uint32_t bits)1058*3ac0a46fSAndroid Build Coastguard Worker static int Fax3Encode2DRow(TIFF *tif, unsigned char *bp, unsigned char *rp,
1059*3ac0a46fSAndroid Build Coastguard Worker                            uint32_t bits)
1060*3ac0a46fSAndroid Build Coastguard Worker {
1061*3ac0a46fSAndroid Build Coastguard Worker #define PIXEL(buf, ix) ((((buf)[(ix) >> 3]) >> (7 - ((ix)&7))) & 1)
1062*3ac0a46fSAndroid Build Coastguard Worker     uint32_t a0 = 0;
1063*3ac0a46fSAndroid Build Coastguard Worker     uint32_t a1 = (PIXEL(bp, 0) != 0 ? 0 : finddiff(bp, 0, bits, 0));
1064*3ac0a46fSAndroid Build Coastguard Worker     uint32_t b1 = (PIXEL(rp, 0) != 0 ? 0 : finddiff(rp, 0, bits, 0));
1065*3ac0a46fSAndroid Build Coastguard Worker     uint32_t a2, b2;
1066*3ac0a46fSAndroid Build Coastguard Worker 
1067*3ac0a46fSAndroid Build Coastguard Worker     for (;;)
1068*3ac0a46fSAndroid Build Coastguard Worker     {
1069*3ac0a46fSAndroid Build Coastguard Worker         b2 = finddiff2(rp, b1, bits, PIXEL(rp, b1));
1070*3ac0a46fSAndroid Build Coastguard Worker         if (b2 >= a1)
1071*3ac0a46fSAndroid Build Coastguard Worker         {
1072*3ac0a46fSAndroid Build Coastguard Worker             /* Naive computation triggers
1073*3ac0a46fSAndroid Build Coastguard Worker              * -fsanitize=undefined,unsigned-integer-overflow */
1074*3ac0a46fSAndroid Build Coastguard Worker             /* although it is correct unless the difference between both is < 31
1075*3ac0a46fSAndroid Build Coastguard Worker              * bit */
1076*3ac0a46fSAndroid Build Coastguard Worker             /* int32_t d = b1 - a1; */
1077*3ac0a46fSAndroid Build Coastguard Worker             int32_t d = (b1 >= a1 && b1 - a1 <= 3U)  ? (int32_t)(b1 - a1)
1078*3ac0a46fSAndroid Build Coastguard Worker                         : (b1 < a1 && a1 - b1 <= 3U) ? -(int32_t)(a1 - b1)
1079*3ac0a46fSAndroid Build Coastguard Worker                                                      : 0x7FFFFFFF;
1080*3ac0a46fSAndroid Build Coastguard Worker             if (!(-3 <= d && d <= 3))
1081*3ac0a46fSAndroid Build Coastguard Worker             { /* horizontal mode */
1082*3ac0a46fSAndroid Build Coastguard Worker                 a2 = finddiff2(bp, a1, bits, PIXEL(bp, a1));
1083*3ac0a46fSAndroid Build Coastguard Worker                 if (!putcode(tif, &horizcode))
1084*3ac0a46fSAndroid Build Coastguard Worker                     return 0;
1085*3ac0a46fSAndroid Build Coastguard Worker                 if (a0 + a1 == 0 || PIXEL(bp, a0) == 0)
1086*3ac0a46fSAndroid Build Coastguard Worker                 {
1087*3ac0a46fSAndroid Build Coastguard Worker                     if (!putspan(tif, a1 - a0, TIFFFaxWhiteCodes))
1088*3ac0a46fSAndroid Build Coastguard Worker                         return 0;
1089*3ac0a46fSAndroid Build Coastguard Worker                     if (!putspan(tif, a2 - a1, TIFFFaxBlackCodes))
1090*3ac0a46fSAndroid Build Coastguard Worker                         return 0;
1091*3ac0a46fSAndroid Build Coastguard Worker                 }
1092*3ac0a46fSAndroid Build Coastguard Worker                 else
1093*3ac0a46fSAndroid Build Coastguard Worker                 {
1094*3ac0a46fSAndroid Build Coastguard Worker                     if (!putspan(tif, a1 - a0, TIFFFaxBlackCodes))
1095*3ac0a46fSAndroid Build Coastguard Worker                         return 0;
1096*3ac0a46fSAndroid Build Coastguard Worker                     if (!putspan(tif, a2 - a1, TIFFFaxWhiteCodes))
1097*3ac0a46fSAndroid Build Coastguard Worker                         return 0;
1098*3ac0a46fSAndroid Build Coastguard Worker                 }
1099*3ac0a46fSAndroid Build Coastguard Worker                 a0 = a2;
1100*3ac0a46fSAndroid Build Coastguard Worker             }
1101*3ac0a46fSAndroid Build Coastguard Worker             else
1102*3ac0a46fSAndroid Build Coastguard Worker             { /* vertical mode */
1103*3ac0a46fSAndroid Build Coastguard Worker                 if (!putcode(tif, &vcodes[d + 3]))
1104*3ac0a46fSAndroid Build Coastguard Worker                     return 0;
1105*3ac0a46fSAndroid Build Coastguard Worker                 a0 = a1;
1106*3ac0a46fSAndroid Build Coastguard Worker             }
1107*3ac0a46fSAndroid Build Coastguard Worker         }
1108*3ac0a46fSAndroid Build Coastguard Worker         else
1109*3ac0a46fSAndroid Build Coastguard Worker         { /* pass mode */
1110*3ac0a46fSAndroid Build Coastguard Worker             if (!putcode(tif, &passcode))
1111*3ac0a46fSAndroid Build Coastguard Worker                 return 0;
1112*3ac0a46fSAndroid Build Coastguard Worker             a0 = b2;
1113*3ac0a46fSAndroid Build Coastguard Worker         }
1114*3ac0a46fSAndroid Build Coastguard Worker         if (a0 >= bits)
1115*3ac0a46fSAndroid Build Coastguard Worker             break;
1116*3ac0a46fSAndroid Build Coastguard Worker         a1 = finddiff(bp, a0, bits, PIXEL(bp, a0));
1117*3ac0a46fSAndroid Build Coastguard Worker         b1 = finddiff(rp, a0, bits, !PIXEL(bp, a0));
1118*3ac0a46fSAndroid Build Coastguard Worker         b1 = finddiff(rp, b1, bits, PIXEL(bp, a0));
1119*3ac0a46fSAndroid Build Coastguard Worker     }
1120*3ac0a46fSAndroid Build Coastguard Worker     return (1);
1121*3ac0a46fSAndroid Build Coastguard Worker #undef PIXEL
1122*3ac0a46fSAndroid Build Coastguard Worker }
1123*3ac0a46fSAndroid Build Coastguard Worker 
1124*3ac0a46fSAndroid Build Coastguard Worker /*
1125*3ac0a46fSAndroid Build Coastguard Worker  * Encode a buffer of pixels.
1126*3ac0a46fSAndroid Build Coastguard Worker  */
Fax3Encode(TIFF * tif,uint8_t * bp,tmsize_t cc,uint16_t s)1127*3ac0a46fSAndroid Build Coastguard Worker static int Fax3Encode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
1128*3ac0a46fSAndroid Build Coastguard Worker {
1129*3ac0a46fSAndroid Build Coastguard Worker     static const char module[] = "Fax3Encode";
1130*3ac0a46fSAndroid Build Coastguard Worker     Fax3CodecState *sp = EncoderState(tif);
1131*3ac0a46fSAndroid Build Coastguard Worker     (void)s;
1132*3ac0a46fSAndroid Build Coastguard Worker     if (cc % sp->b.rowbytes)
1133*3ac0a46fSAndroid Build Coastguard Worker     {
1134*3ac0a46fSAndroid Build Coastguard Worker         TIFFErrorExtR(tif, module, "Fractional scanlines cannot be written");
1135*3ac0a46fSAndroid Build Coastguard Worker         return (0);
1136*3ac0a46fSAndroid Build Coastguard Worker     }
1137*3ac0a46fSAndroid Build Coastguard Worker     while (cc > 0)
1138*3ac0a46fSAndroid Build Coastguard Worker     {
1139*3ac0a46fSAndroid Build Coastguard Worker         if ((sp->b.mode & FAXMODE_NOEOL) == 0)
1140*3ac0a46fSAndroid Build Coastguard Worker         {
1141*3ac0a46fSAndroid Build Coastguard Worker             if (!Fax3PutEOL(tif))
1142*3ac0a46fSAndroid Build Coastguard Worker                 return 0;
1143*3ac0a46fSAndroid Build Coastguard Worker         }
1144*3ac0a46fSAndroid Build Coastguard Worker         if (is2DEncoding(sp))
1145*3ac0a46fSAndroid Build Coastguard Worker         {
1146*3ac0a46fSAndroid Build Coastguard Worker             if (sp->tag == G3_1D)
1147*3ac0a46fSAndroid Build Coastguard Worker             {
1148*3ac0a46fSAndroid Build Coastguard Worker                 if (!Fax3Encode1DRow(tif, bp, sp->b.rowpixels))
1149*3ac0a46fSAndroid Build Coastguard Worker                     return (0);
1150*3ac0a46fSAndroid Build Coastguard Worker                 sp->tag = G3_2D;
1151*3ac0a46fSAndroid Build Coastguard Worker             }
1152*3ac0a46fSAndroid Build Coastguard Worker             else
1153*3ac0a46fSAndroid Build Coastguard Worker             {
1154*3ac0a46fSAndroid Build Coastguard Worker                 if (!Fax3Encode2DRow(tif, bp, sp->refline, sp->b.rowpixels))
1155*3ac0a46fSAndroid Build Coastguard Worker                     return (0);
1156*3ac0a46fSAndroid Build Coastguard Worker                 sp->k--;
1157*3ac0a46fSAndroid Build Coastguard Worker             }
1158*3ac0a46fSAndroid Build Coastguard Worker             if (sp->k == 0)
1159*3ac0a46fSAndroid Build Coastguard Worker             {
1160*3ac0a46fSAndroid Build Coastguard Worker                 sp->tag = G3_1D;
1161*3ac0a46fSAndroid Build Coastguard Worker                 sp->k = sp->maxk - 1;
1162*3ac0a46fSAndroid Build Coastguard Worker             }
1163*3ac0a46fSAndroid Build Coastguard Worker             else
1164*3ac0a46fSAndroid Build Coastguard Worker                 _TIFFmemcpy(sp->refline, bp, sp->b.rowbytes);
1165*3ac0a46fSAndroid Build Coastguard Worker         }
1166*3ac0a46fSAndroid Build Coastguard Worker         else
1167*3ac0a46fSAndroid Build Coastguard Worker         {
1168*3ac0a46fSAndroid Build Coastguard Worker             if (!Fax3Encode1DRow(tif, bp, sp->b.rowpixels))
1169*3ac0a46fSAndroid Build Coastguard Worker                 return (0);
1170*3ac0a46fSAndroid Build Coastguard Worker         }
1171*3ac0a46fSAndroid Build Coastguard Worker         bp += sp->b.rowbytes;
1172*3ac0a46fSAndroid Build Coastguard Worker         cc -= sp->b.rowbytes;
1173*3ac0a46fSAndroid Build Coastguard Worker     }
1174*3ac0a46fSAndroid Build Coastguard Worker     return (1);
1175*3ac0a46fSAndroid Build Coastguard Worker }
1176*3ac0a46fSAndroid Build Coastguard Worker 
Fax3PostEncode(TIFF * tif)1177*3ac0a46fSAndroid Build Coastguard Worker static int Fax3PostEncode(TIFF *tif)
1178*3ac0a46fSAndroid Build Coastguard Worker {
1179*3ac0a46fSAndroid Build Coastguard Worker     Fax3CodecState *sp = EncoderState(tif);
1180*3ac0a46fSAndroid Build Coastguard Worker 
1181*3ac0a46fSAndroid Build Coastguard Worker     if (sp->bit != 8)
1182*3ac0a46fSAndroid Build Coastguard Worker         Fax3FlushBits(tif, sp);
1183*3ac0a46fSAndroid Build Coastguard Worker     return (1);
1184*3ac0a46fSAndroid Build Coastguard Worker }
1185*3ac0a46fSAndroid Build Coastguard Worker 
_Fax3Close(TIFF * tif)1186*3ac0a46fSAndroid Build Coastguard Worker static int _Fax3Close(TIFF *tif)
1187*3ac0a46fSAndroid Build Coastguard Worker {
1188*3ac0a46fSAndroid Build Coastguard Worker     if ((Fax3State(tif)->mode & FAXMODE_NORTC) == 0 && tif->tif_rawcp)
1189*3ac0a46fSAndroid Build Coastguard Worker     {
1190*3ac0a46fSAndroid Build Coastguard Worker         Fax3CodecState *sp = EncoderState(tif);
1191*3ac0a46fSAndroid Build Coastguard Worker         unsigned int code = EOL;
1192*3ac0a46fSAndroid Build Coastguard Worker         unsigned int length = 12;
1193*3ac0a46fSAndroid Build Coastguard Worker         int i;
1194*3ac0a46fSAndroid Build Coastguard Worker 
1195*3ac0a46fSAndroid Build Coastguard Worker         if (is2DEncoding(sp))
1196*3ac0a46fSAndroid Build Coastguard Worker         {
1197*3ac0a46fSAndroid Build Coastguard Worker             code = (code << 1) | (sp->tag == G3_1D);
1198*3ac0a46fSAndroid Build Coastguard Worker             length++;
1199*3ac0a46fSAndroid Build Coastguard Worker         }
1200*3ac0a46fSAndroid Build Coastguard Worker         for (i = 0; i < 6; i++)
1201*3ac0a46fSAndroid Build Coastguard Worker             Fax3PutBits(tif, code, length);
1202*3ac0a46fSAndroid Build Coastguard Worker         Fax3FlushBits(tif, sp);
1203*3ac0a46fSAndroid Build Coastguard Worker     }
1204*3ac0a46fSAndroid Build Coastguard Worker     return 1;
1205*3ac0a46fSAndroid Build Coastguard Worker }
1206*3ac0a46fSAndroid Build Coastguard Worker 
Fax3Close(TIFF * tif)1207*3ac0a46fSAndroid Build Coastguard Worker static void Fax3Close(TIFF *tif) { _Fax3Close(tif); }
1208*3ac0a46fSAndroid Build Coastguard Worker 
Fax3Cleanup(TIFF * tif)1209*3ac0a46fSAndroid Build Coastguard Worker static void Fax3Cleanup(TIFF *tif)
1210*3ac0a46fSAndroid Build Coastguard Worker {
1211*3ac0a46fSAndroid Build Coastguard Worker     Fax3CodecState *sp = DecoderState(tif);
1212*3ac0a46fSAndroid Build Coastguard Worker 
1213*3ac0a46fSAndroid Build Coastguard Worker     assert(sp != 0);
1214*3ac0a46fSAndroid Build Coastguard Worker 
1215*3ac0a46fSAndroid Build Coastguard Worker     tif->tif_tagmethods.vgetfield = sp->b.vgetparent;
1216*3ac0a46fSAndroid Build Coastguard Worker     tif->tif_tagmethods.vsetfield = sp->b.vsetparent;
1217*3ac0a46fSAndroid Build Coastguard Worker     tif->tif_tagmethods.printdir = sp->b.printdir;
1218*3ac0a46fSAndroid Build Coastguard Worker 
1219*3ac0a46fSAndroid Build Coastguard Worker     if (sp->runs)
1220*3ac0a46fSAndroid Build Coastguard Worker         _TIFFfreeExt(tif, sp->runs);
1221*3ac0a46fSAndroid Build Coastguard Worker     if (sp->refline)
1222*3ac0a46fSAndroid Build Coastguard Worker         _TIFFfreeExt(tif, sp->refline);
1223*3ac0a46fSAndroid Build Coastguard Worker 
1224*3ac0a46fSAndroid Build Coastguard Worker     _TIFFfreeExt(tif, tif->tif_data);
1225*3ac0a46fSAndroid Build Coastguard Worker     tif->tif_data = NULL;
1226*3ac0a46fSAndroid Build Coastguard Worker 
1227*3ac0a46fSAndroid Build Coastguard Worker     _TIFFSetDefaultCompressionState(tif);
1228*3ac0a46fSAndroid Build Coastguard Worker }
1229*3ac0a46fSAndroid Build Coastguard Worker 
1230*3ac0a46fSAndroid Build Coastguard Worker #define FIELD_BADFAXLINES (FIELD_CODEC + 0)
1231*3ac0a46fSAndroid Build Coastguard Worker #define FIELD_CLEANFAXDATA (FIELD_CODEC + 1)
1232*3ac0a46fSAndroid Build Coastguard Worker #define FIELD_BADFAXRUN (FIELD_CODEC + 2)
1233*3ac0a46fSAndroid Build Coastguard Worker 
1234*3ac0a46fSAndroid Build Coastguard Worker #define FIELD_OPTIONS (FIELD_CODEC + 7)
1235*3ac0a46fSAndroid Build Coastguard Worker 
1236*3ac0a46fSAndroid Build Coastguard Worker static const TIFFField faxFields[] = {
1237*3ac0a46fSAndroid Build Coastguard Worker     {TIFFTAG_FAXMODE, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED,
1238*3ac0a46fSAndroid Build Coastguard Worker      FIELD_PSEUDO, FALSE, FALSE, "FaxMode", NULL},
1239*3ac0a46fSAndroid Build Coastguard Worker     {TIFFTAG_FAXFILLFUNC, 0, 0, TIFF_ANY, 0, TIFF_SETGET_OTHER,
1240*3ac0a46fSAndroid Build Coastguard Worker      TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "FaxFillFunc", NULL},
1241*3ac0a46fSAndroid Build Coastguard Worker     {TIFFTAG_BADFAXLINES, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32,
1242*3ac0a46fSAndroid Build Coastguard Worker      TIFF_SETGET_UINT32, FIELD_BADFAXLINES, TRUE, FALSE, "BadFaxLines", NULL},
1243*3ac0a46fSAndroid Build Coastguard Worker     {TIFFTAG_CLEANFAXDATA, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16,
1244*3ac0a46fSAndroid Build Coastguard Worker      TIFF_SETGET_UINT16, FIELD_CLEANFAXDATA, TRUE, FALSE, "CleanFaxData", NULL},
1245*3ac0a46fSAndroid Build Coastguard Worker     {TIFFTAG_CONSECUTIVEBADFAXLINES, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32,
1246*3ac0a46fSAndroid Build Coastguard Worker      TIFF_SETGET_UINT32, FIELD_BADFAXRUN, TRUE, FALSE, "ConsecutiveBadFaxLines",
1247*3ac0a46fSAndroid Build Coastguard Worker      NULL}};
1248*3ac0a46fSAndroid Build Coastguard Worker static const TIFFField fax3Fields[] = {
1249*3ac0a46fSAndroid Build Coastguard Worker     {TIFFTAG_GROUP3OPTIONS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32,
1250*3ac0a46fSAndroid Build Coastguard Worker      TIFF_SETGET_UINT32, FIELD_OPTIONS, FALSE, FALSE, "Group3Options", NULL},
1251*3ac0a46fSAndroid Build Coastguard Worker };
1252*3ac0a46fSAndroid Build Coastguard Worker static const TIFFField fax4Fields[] = {
1253*3ac0a46fSAndroid Build Coastguard Worker     {TIFFTAG_GROUP4OPTIONS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32,
1254*3ac0a46fSAndroid Build Coastguard Worker      TIFF_SETGET_UINT32, FIELD_OPTIONS, FALSE, FALSE, "Group4Options", NULL},
1255*3ac0a46fSAndroid Build Coastguard Worker };
1256*3ac0a46fSAndroid Build Coastguard Worker 
Fax3VSetField(TIFF * tif,uint32_t tag,va_list ap)1257*3ac0a46fSAndroid Build Coastguard Worker static int Fax3VSetField(TIFF *tif, uint32_t tag, va_list ap)
1258*3ac0a46fSAndroid Build Coastguard Worker {
1259*3ac0a46fSAndroid Build Coastguard Worker     Fax3BaseState *sp = Fax3State(tif);
1260*3ac0a46fSAndroid Build Coastguard Worker     const TIFFField *fip;
1261*3ac0a46fSAndroid Build Coastguard Worker 
1262*3ac0a46fSAndroid Build Coastguard Worker     assert(sp != 0);
1263*3ac0a46fSAndroid Build Coastguard Worker     assert(sp->vsetparent != 0);
1264*3ac0a46fSAndroid Build Coastguard Worker 
1265*3ac0a46fSAndroid Build Coastguard Worker     switch (tag)
1266*3ac0a46fSAndroid Build Coastguard Worker     {
1267*3ac0a46fSAndroid Build Coastguard Worker         case TIFFTAG_FAXMODE:
1268*3ac0a46fSAndroid Build Coastguard Worker             sp->mode = (int)va_arg(ap, int);
1269*3ac0a46fSAndroid Build Coastguard Worker             return 1; /* NB: pseudo tag */
1270*3ac0a46fSAndroid Build Coastguard Worker         case TIFFTAG_FAXFILLFUNC:
1271*3ac0a46fSAndroid Build Coastguard Worker             DecoderState(tif)->fill = va_arg(ap, TIFFFaxFillFunc);
1272*3ac0a46fSAndroid Build Coastguard Worker             return 1; /* NB: pseudo tag */
1273*3ac0a46fSAndroid Build Coastguard Worker         case TIFFTAG_GROUP3OPTIONS:
1274*3ac0a46fSAndroid Build Coastguard Worker             /* XXX: avoid reading options if compression mismatches. */
1275*3ac0a46fSAndroid Build Coastguard Worker             if (tif->tif_dir.td_compression == COMPRESSION_CCITTFAX3)
1276*3ac0a46fSAndroid Build Coastguard Worker                 sp->groupoptions = (uint32_t)va_arg(ap, uint32_t);
1277*3ac0a46fSAndroid Build Coastguard Worker             break;
1278*3ac0a46fSAndroid Build Coastguard Worker         case TIFFTAG_GROUP4OPTIONS:
1279*3ac0a46fSAndroid Build Coastguard Worker             /* XXX: avoid reading options if compression mismatches. */
1280*3ac0a46fSAndroid Build Coastguard Worker             if (tif->tif_dir.td_compression == COMPRESSION_CCITTFAX4)
1281*3ac0a46fSAndroid Build Coastguard Worker                 sp->groupoptions = (uint32_t)va_arg(ap, uint32_t);
1282*3ac0a46fSAndroid Build Coastguard Worker             break;
1283*3ac0a46fSAndroid Build Coastguard Worker         case TIFFTAG_BADFAXLINES:
1284*3ac0a46fSAndroid Build Coastguard Worker             sp->badfaxlines = (uint32_t)va_arg(ap, uint32_t);
1285*3ac0a46fSAndroid Build Coastguard Worker             break;
1286*3ac0a46fSAndroid Build Coastguard Worker         case TIFFTAG_CLEANFAXDATA:
1287*3ac0a46fSAndroid Build Coastguard Worker             sp->cleanfaxdata = (uint16_t)va_arg(ap, uint16_vap);
1288*3ac0a46fSAndroid Build Coastguard Worker             break;
1289*3ac0a46fSAndroid Build Coastguard Worker         case TIFFTAG_CONSECUTIVEBADFAXLINES:
1290*3ac0a46fSAndroid Build Coastguard Worker             sp->badfaxrun = (uint32_t)va_arg(ap, uint32_t);
1291*3ac0a46fSAndroid Build Coastguard Worker             break;
1292*3ac0a46fSAndroid Build Coastguard Worker         default:
1293*3ac0a46fSAndroid Build Coastguard Worker             return (*sp->vsetparent)(tif, tag, ap);
1294*3ac0a46fSAndroid Build Coastguard Worker     }
1295*3ac0a46fSAndroid Build Coastguard Worker 
1296*3ac0a46fSAndroid Build Coastguard Worker     if ((fip = TIFFFieldWithTag(tif, tag)) != NULL)
1297*3ac0a46fSAndroid Build Coastguard Worker         TIFFSetFieldBit(tif, fip->field_bit);
1298*3ac0a46fSAndroid Build Coastguard Worker     else
1299*3ac0a46fSAndroid Build Coastguard Worker         return 0;
1300*3ac0a46fSAndroid Build Coastguard Worker 
1301*3ac0a46fSAndroid Build Coastguard Worker     tif->tif_flags |= TIFF_DIRTYDIRECT;
1302*3ac0a46fSAndroid Build Coastguard Worker     return 1;
1303*3ac0a46fSAndroid Build Coastguard Worker }
1304*3ac0a46fSAndroid Build Coastguard Worker 
Fax3VGetField(TIFF * tif,uint32_t tag,va_list ap)1305*3ac0a46fSAndroid Build Coastguard Worker static int Fax3VGetField(TIFF *tif, uint32_t tag, va_list ap)
1306*3ac0a46fSAndroid Build Coastguard Worker {
1307*3ac0a46fSAndroid Build Coastguard Worker     Fax3BaseState *sp = Fax3State(tif);
1308*3ac0a46fSAndroid Build Coastguard Worker 
1309*3ac0a46fSAndroid Build Coastguard Worker     assert(sp != 0);
1310*3ac0a46fSAndroid Build Coastguard Worker 
1311*3ac0a46fSAndroid Build Coastguard Worker     switch (tag)
1312*3ac0a46fSAndroid Build Coastguard Worker     {
1313*3ac0a46fSAndroid Build Coastguard Worker         case TIFFTAG_FAXMODE:
1314*3ac0a46fSAndroid Build Coastguard Worker             *va_arg(ap, int *) = sp->mode;
1315*3ac0a46fSAndroid Build Coastguard Worker             break;
1316*3ac0a46fSAndroid Build Coastguard Worker         case TIFFTAG_FAXFILLFUNC:
1317*3ac0a46fSAndroid Build Coastguard Worker             *va_arg(ap, TIFFFaxFillFunc *) = DecoderState(tif)->fill;
1318*3ac0a46fSAndroid Build Coastguard Worker             break;
1319*3ac0a46fSAndroid Build Coastguard Worker         case TIFFTAG_GROUP3OPTIONS:
1320*3ac0a46fSAndroid Build Coastguard Worker         case TIFFTAG_GROUP4OPTIONS:
1321*3ac0a46fSAndroid Build Coastguard Worker             *va_arg(ap, uint32_t *) = sp->groupoptions;
1322*3ac0a46fSAndroid Build Coastguard Worker             break;
1323*3ac0a46fSAndroid Build Coastguard Worker         case TIFFTAG_BADFAXLINES:
1324*3ac0a46fSAndroid Build Coastguard Worker             *va_arg(ap, uint32_t *) = sp->badfaxlines;
1325*3ac0a46fSAndroid Build Coastguard Worker             break;
1326*3ac0a46fSAndroid Build Coastguard Worker         case TIFFTAG_CLEANFAXDATA:
1327*3ac0a46fSAndroid Build Coastguard Worker             *va_arg(ap, uint16_t *) = sp->cleanfaxdata;
1328*3ac0a46fSAndroid Build Coastguard Worker             break;
1329*3ac0a46fSAndroid Build Coastguard Worker         case TIFFTAG_CONSECUTIVEBADFAXLINES:
1330*3ac0a46fSAndroid Build Coastguard Worker             *va_arg(ap, uint32_t *) = sp->badfaxrun;
1331*3ac0a46fSAndroid Build Coastguard Worker             break;
1332*3ac0a46fSAndroid Build Coastguard Worker         default:
1333*3ac0a46fSAndroid Build Coastguard Worker             return (*sp->vgetparent)(tif, tag, ap);
1334*3ac0a46fSAndroid Build Coastguard Worker     }
1335*3ac0a46fSAndroid Build Coastguard Worker     return (1);
1336*3ac0a46fSAndroid Build Coastguard Worker }
1337*3ac0a46fSAndroid Build Coastguard Worker 
Fax3PrintDir(TIFF * tif,FILE * fd,long flags)1338*3ac0a46fSAndroid Build Coastguard Worker static void Fax3PrintDir(TIFF *tif, FILE *fd, long flags)
1339*3ac0a46fSAndroid Build Coastguard Worker {
1340*3ac0a46fSAndroid Build Coastguard Worker     Fax3BaseState *sp = Fax3State(tif);
1341*3ac0a46fSAndroid Build Coastguard Worker 
1342*3ac0a46fSAndroid Build Coastguard Worker     assert(sp != 0);
1343*3ac0a46fSAndroid Build Coastguard Worker 
1344*3ac0a46fSAndroid Build Coastguard Worker     (void)flags;
1345*3ac0a46fSAndroid Build Coastguard Worker     if (TIFFFieldSet(tif, FIELD_OPTIONS))
1346*3ac0a46fSAndroid Build Coastguard Worker     {
1347*3ac0a46fSAndroid Build Coastguard Worker         const char *sep = " ";
1348*3ac0a46fSAndroid Build Coastguard Worker         if (tif->tif_dir.td_compression == COMPRESSION_CCITTFAX4)
1349*3ac0a46fSAndroid Build Coastguard Worker         {
1350*3ac0a46fSAndroid Build Coastguard Worker             fprintf(fd, "  Group 4 Options:");
1351*3ac0a46fSAndroid Build Coastguard Worker             if (sp->groupoptions & GROUP4OPT_UNCOMPRESSED)
1352*3ac0a46fSAndroid Build Coastguard Worker                 fprintf(fd, "%suncompressed data", sep);
1353*3ac0a46fSAndroid Build Coastguard Worker         }
1354*3ac0a46fSAndroid Build Coastguard Worker         else
1355*3ac0a46fSAndroid Build Coastguard Worker         {
1356*3ac0a46fSAndroid Build Coastguard Worker 
1357*3ac0a46fSAndroid Build Coastguard Worker             fprintf(fd, "  Group 3 Options:");
1358*3ac0a46fSAndroid Build Coastguard Worker             if (sp->groupoptions & GROUP3OPT_2DENCODING)
1359*3ac0a46fSAndroid Build Coastguard Worker             {
1360*3ac0a46fSAndroid Build Coastguard Worker                 fprintf(fd, "%s2-d encoding", sep);
1361*3ac0a46fSAndroid Build Coastguard Worker                 sep = "+";
1362*3ac0a46fSAndroid Build Coastguard Worker             }
1363*3ac0a46fSAndroid Build Coastguard Worker             if (sp->groupoptions & GROUP3OPT_FILLBITS)
1364*3ac0a46fSAndroid Build Coastguard Worker             {
1365*3ac0a46fSAndroid Build Coastguard Worker                 fprintf(fd, "%sEOL padding", sep);
1366*3ac0a46fSAndroid Build Coastguard Worker                 sep = "+";
1367*3ac0a46fSAndroid Build Coastguard Worker             }
1368*3ac0a46fSAndroid Build Coastguard Worker             if (sp->groupoptions & GROUP3OPT_UNCOMPRESSED)
1369*3ac0a46fSAndroid Build Coastguard Worker                 fprintf(fd, "%suncompressed data", sep);
1370*3ac0a46fSAndroid Build Coastguard Worker         }
1371*3ac0a46fSAndroid Build Coastguard Worker         fprintf(fd, " (%" PRIu32 " = 0x%" PRIx32 ")\n", sp->groupoptions,
1372*3ac0a46fSAndroid Build Coastguard Worker                 sp->groupoptions);
1373*3ac0a46fSAndroid Build Coastguard Worker     }
1374*3ac0a46fSAndroid Build Coastguard Worker     if (TIFFFieldSet(tif, FIELD_CLEANFAXDATA))
1375*3ac0a46fSAndroid Build Coastguard Worker     {
1376*3ac0a46fSAndroid Build Coastguard Worker         fprintf(fd, "  Fax Data:");
1377*3ac0a46fSAndroid Build Coastguard Worker         switch (sp->cleanfaxdata)
1378*3ac0a46fSAndroid Build Coastguard Worker         {
1379*3ac0a46fSAndroid Build Coastguard Worker             case CLEANFAXDATA_CLEAN:
1380*3ac0a46fSAndroid Build Coastguard Worker                 fprintf(fd, " clean");
1381*3ac0a46fSAndroid Build Coastguard Worker                 break;
1382*3ac0a46fSAndroid Build Coastguard Worker             case CLEANFAXDATA_REGENERATED:
1383*3ac0a46fSAndroid Build Coastguard Worker                 fprintf(fd, " receiver regenerated");
1384*3ac0a46fSAndroid Build Coastguard Worker                 break;
1385*3ac0a46fSAndroid Build Coastguard Worker             case CLEANFAXDATA_UNCLEAN:
1386*3ac0a46fSAndroid Build Coastguard Worker                 fprintf(fd, " uncorrected errors");
1387*3ac0a46fSAndroid Build Coastguard Worker                 break;
1388*3ac0a46fSAndroid Build Coastguard Worker         }
1389*3ac0a46fSAndroid Build Coastguard Worker         fprintf(fd, " (%" PRIu16 " = 0x%" PRIx16 ")\n", sp->cleanfaxdata,
1390*3ac0a46fSAndroid Build Coastguard Worker                 sp->cleanfaxdata);
1391*3ac0a46fSAndroid Build Coastguard Worker     }
1392*3ac0a46fSAndroid Build Coastguard Worker     if (TIFFFieldSet(tif, FIELD_BADFAXLINES))
1393*3ac0a46fSAndroid Build Coastguard Worker         fprintf(fd, "  Bad Fax Lines: %" PRIu32 "\n", sp->badfaxlines);
1394*3ac0a46fSAndroid Build Coastguard Worker     if (TIFFFieldSet(tif, FIELD_BADFAXRUN))
1395*3ac0a46fSAndroid Build Coastguard Worker         fprintf(fd, "  Consecutive Bad Fax Lines: %" PRIu32 "\n",
1396*3ac0a46fSAndroid Build Coastguard Worker                 sp->badfaxrun);
1397*3ac0a46fSAndroid Build Coastguard Worker     if (sp->printdir)
1398*3ac0a46fSAndroid Build Coastguard Worker         (*sp->printdir)(tif, fd, flags);
1399*3ac0a46fSAndroid Build Coastguard Worker }
1400*3ac0a46fSAndroid Build Coastguard Worker 
InitCCITTFax3(TIFF * tif)1401*3ac0a46fSAndroid Build Coastguard Worker static int InitCCITTFax3(TIFF *tif)
1402*3ac0a46fSAndroid Build Coastguard Worker {
1403*3ac0a46fSAndroid Build Coastguard Worker     static const char module[] = "InitCCITTFax3";
1404*3ac0a46fSAndroid Build Coastguard Worker     Fax3BaseState *sp;
1405*3ac0a46fSAndroid Build Coastguard Worker 
1406*3ac0a46fSAndroid Build Coastguard Worker     /*
1407*3ac0a46fSAndroid Build Coastguard Worker      * Merge codec-specific tag information.
1408*3ac0a46fSAndroid Build Coastguard Worker      */
1409*3ac0a46fSAndroid Build Coastguard Worker     if (!_TIFFMergeFields(tif, faxFields, TIFFArrayCount(faxFields)))
1410*3ac0a46fSAndroid Build Coastguard Worker     {
1411*3ac0a46fSAndroid Build Coastguard Worker         TIFFErrorExtR(tif, "InitCCITTFax3",
1412*3ac0a46fSAndroid Build Coastguard Worker                       "Merging common CCITT Fax codec-specific tags failed");
1413*3ac0a46fSAndroid Build Coastguard Worker         return 0;
1414*3ac0a46fSAndroid Build Coastguard Worker     }
1415*3ac0a46fSAndroid Build Coastguard Worker 
1416*3ac0a46fSAndroid Build Coastguard Worker     /*
1417*3ac0a46fSAndroid Build Coastguard Worker      * Allocate state block so tag methods have storage to record values.
1418*3ac0a46fSAndroid Build Coastguard Worker      */
1419*3ac0a46fSAndroid Build Coastguard Worker     tif->tif_data = (uint8_t *)_TIFFmallocExt(tif, sizeof(Fax3CodecState));
1420*3ac0a46fSAndroid Build Coastguard Worker 
1421*3ac0a46fSAndroid Build Coastguard Worker     if (tif->tif_data == NULL)
1422*3ac0a46fSAndroid Build Coastguard Worker     {
1423*3ac0a46fSAndroid Build Coastguard Worker         TIFFErrorExtR(tif, module, "No space for state block");
1424*3ac0a46fSAndroid Build Coastguard Worker         return (0);
1425*3ac0a46fSAndroid Build Coastguard Worker     }
1426*3ac0a46fSAndroid Build Coastguard Worker     _TIFFmemset(tif->tif_data, 0, sizeof(Fax3CodecState));
1427*3ac0a46fSAndroid Build Coastguard Worker 
1428*3ac0a46fSAndroid Build Coastguard Worker     sp = Fax3State(tif);
1429*3ac0a46fSAndroid Build Coastguard Worker     sp->rw_mode = tif->tif_mode;
1430*3ac0a46fSAndroid Build Coastguard Worker 
1431*3ac0a46fSAndroid Build Coastguard Worker     /*
1432*3ac0a46fSAndroid Build Coastguard Worker      * Override parent get/set field methods.
1433*3ac0a46fSAndroid Build Coastguard Worker      */
1434*3ac0a46fSAndroid Build Coastguard Worker     sp->vgetparent = tif->tif_tagmethods.vgetfield;
1435*3ac0a46fSAndroid Build Coastguard Worker     tif->tif_tagmethods.vgetfield = Fax3VGetField; /* hook for codec tags */
1436*3ac0a46fSAndroid Build Coastguard Worker     sp->vsetparent = tif->tif_tagmethods.vsetfield;
1437*3ac0a46fSAndroid Build Coastguard Worker     tif->tif_tagmethods.vsetfield = Fax3VSetField; /* hook for codec tags */
1438*3ac0a46fSAndroid Build Coastguard Worker     sp->printdir = tif->tif_tagmethods.printdir;
1439*3ac0a46fSAndroid Build Coastguard Worker     tif->tif_tagmethods.printdir = Fax3PrintDir; /* hook for codec tags */
1440*3ac0a46fSAndroid Build Coastguard Worker     sp->groupoptions = 0;
1441*3ac0a46fSAndroid Build Coastguard Worker 
1442*3ac0a46fSAndroid Build Coastguard Worker     if (sp->rw_mode == O_RDONLY) /* FIXME: improve for in place update */
1443*3ac0a46fSAndroid Build Coastguard Worker         tif->tif_flags |= TIFF_NOBITREV; /* decoder does bit reversal */
1444*3ac0a46fSAndroid Build Coastguard Worker     DecoderState(tif)->runs = NULL;
1445*3ac0a46fSAndroid Build Coastguard Worker     TIFFSetField(tif, TIFFTAG_FAXFILLFUNC, _TIFFFax3fillruns);
1446*3ac0a46fSAndroid Build Coastguard Worker     EncoderState(tif)->refline = NULL;
1447*3ac0a46fSAndroid Build Coastguard Worker 
1448*3ac0a46fSAndroid Build Coastguard Worker     /*
1449*3ac0a46fSAndroid Build Coastguard Worker      * Install codec methods.
1450*3ac0a46fSAndroid Build Coastguard Worker      */
1451*3ac0a46fSAndroid Build Coastguard Worker     tif->tif_fixuptags = Fax3FixupTags;
1452*3ac0a46fSAndroid Build Coastguard Worker     tif->tif_setupdecode = Fax3SetupState;
1453*3ac0a46fSAndroid Build Coastguard Worker     tif->tif_predecode = Fax3PreDecode;
1454*3ac0a46fSAndroid Build Coastguard Worker     tif->tif_decoderow = Fax3Decode1D;
1455*3ac0a46fSAndroid Build Coastguard Worker     tif->tif_decodestrip = Fax3Decode1D;
1456*3ac0a46fSAndroid Build Coastguard Worker     tif->tif_decodetile = Fax3Decode1D;
1457*3ac0a46fSAndroid Build Coastguard Worker     tif->tif_setupencode = Fax3SetupState;
1458*3ac0a46fSAndroid Build Coastguard Worker     tif->tif_preencode = Fax3PreEncode;
1459*3ac0a46fSAndroid Build Coastguard Worker     tif->tif_postencode = Fax3PostEncode;
1460*3ac0a46fSAndroid Build Coastguard Worker     tif->tif_encoderow = Fax3Encode;
1461*3ac0a46fSAndroid Build Coastguard Worker     tif->tif_encodestrip = Fax3Encode;
1462*3ac0a46fSAndroid Build Coastguard Worker     tif->tif_encodetile = Fax3Encode;
1463*3ac0a46fSAndroid Build Coastguard Worker     tif->tif_close = Fax3Close;
1464*3ac0a46fSAndroid Build Coastguard Worker     tif->tif_cleanup = Fax3Cleanup;
1465*3ac0a46fSAndroid Build Coastguard Worker 
1466*3ac0a46fSAndroid Build Coastguard Worker     return (1);
1467*3ac0a46fSAndroid Build Coastguard Worker }
1468*3ac0a46fSAndroid Build Coastguard Worker 
TIFFInitCCITTFax3(TIFF * tif,int scheme)1469*3ac0a46fSAndroid Build Coastguard Worker int TIFFInitCCITTFax3(TIFF *tif, int scheme)
1470*3ac0a46fSAndroid Build Coastguard Worker {
1471*3ac0a46fSAndroid Build Coastguard Worker     (void)scheme;
1472*3ac0a46fSAndroid Build Coastguard Worker     if (InitCCITTFax3(tif))
1473*3ac0a46fSAndroid Build Coastguard Worker     {
1474*3ac0a46fSAndroid Build Coastguard Worker         /*
1475*3ac0a46fSAndroid Build Coastguard Worker          * Merge codec-specific tag information.
1476*3ac0a46fSAndroid Build Coastguard Worker          */
1477*3ac0a46fSAndroid Build Coastguard Worker         if (!_TIFFMergeFields(tif, fax3Fields, TIFFArrayCount(fax3Fields)))
1478*3ac0a46fSAndroid Build Coastguard Worker         {
1479*3ac0a46fSAndroid Build Coastguard Worker             TIFFErrorExtR(tif, "TIFFInitCCITTFax3",
1480*3ac0a46fSAndroid Build Coastguard Worker                           "Merging CCITT Fax 3 codec-specific tags failed");
1481*3ac0a46fSAndroid Build Coastguard Worker             return 0;
1482*3ac0a46fSAndroid Build Coastguard Worker         }
1483*3ac0a46fSAndroid Build Coastguard Worker 
1484*3ac0a46fSAndroid Build Coastguard Worker         /*
1485*3ac0a46fSAndroid Build Coastguard Worker          * The default format is Class/F-style w/o RTC.
1486*3ac0a46fSAndroid Build Coastguard Worker          */
1487*3ac0a46fSAndroid Build Coastguard Worker         return TIFFSetField(tif, TIFFTAG_FAXMODE, FAXMODE_CLASSF);
1488*3ac0a46fSAndroid Build Coastguard Worker     }
1489*3ac0a46fSAndroid Build Coastguard Worker     else
1490*3ac0a46fSAndroid Build Coastguard Worker         return 01;
1491*3ac0a46fSAndroid Build Coastguard Worker }
1492*3ac0a46fSAndroid Build Coastguard Worker 
1493*3ac0a46fSAndroid Build Coastguard Worker /*
1494*3ac0a46fSAndroid Build Coastguard Worker  * CCITT Group 4 (T.6) Facsimile-compatible
1495*3ac0a46fSAndroid Build Coastguard Worker  * Compression Scheme Support.
1496*3ac0a46fSAndroid Build Coastguard Worker  */
1497*3ac0a46fSAndroid Build Coastguard Worker 
1498*3ac0a46fSAndroid Build Coastguard Worker #define SWAP(t, a, b)                                                          \
1499*3ac0a46fSAndroid Build Coastguard Worker     {                                                                          \
1500*3ac0a46fSAndroid Build Coastguard Worker         t x;                                                                   \
1501*3ac0a46fSAndroid Build Coastguard Worker         x = (a);                                                               \
1502*3ac0a46fSAndroid Build Coastguard Worker         (a) = (b);                                                             \
1503*3ac0a46fSAndroid Build Coastguard Worker         (b) = x;                                                               \
1504*3ac0a46fSAndroid Build Coastguard Worker     }
1505*3ac0a46fSAndroid Build Coastguard Worker /*
1506*3ac0a46fSAndroid Build Coastguard Worker  * Decode the requested amount of G4-encoded data.
1507*3ac0a46fSAndroid Build Coastguard Worker  */
Fax4Decode(TIFF * tif,uint8_t * buf,tmsize_t occ,uint16_t s)1508*3ac0a46fSAndroid Build Coastguard Worker static int Fax4Decode(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s)
1509*3ac0a46fSAndroid Build Coastguard Worker {
1510*3ac0a46fSAndroid Build Coastguard Worker     DECLARE_STATE_2D(tif, sp, "Fax4Decode");
1511*3ac0a46fSAndroid Build Coastguard Worker     (void)s;
1512*3ac0a46fSAndroid Build Coastguard Worker     if (occ % sp->b.rowbytes)
1513*3ac0a46fSAndroid Build Coastguard Worker     {
1514*3ac0a46fSAndroid Build Coastguard Worker         TIFFErrorExtR(tif, module, "Fractional scanlines cannot be read");
1515*3ac0a46fSAndroid Build Coastguard Worker         return (-1);
1516*3ac0a46fSAndroid Build Coastguard Worker     }
1517*3ac0a46fSAndroid Build Coastguard Worker     CACHE_STATE(tif, sp);
1518*3ac0a46fSAndroid Build Coastguard Worker     while (occ > 0)
1519*3ac0a46fSAndroid Build Coastguard Worker     {
1520*3ac0a46fSAndroid Build Coastguard Worker         a0 = 0;
1521*3ac0a46fSAndroid Build Coastguard Worker         RunLength = 0;
1522*3ac0a46fSAndroid Build Coastguard Worker         pa = thisrun = sp->curruns;
1523*3ac0a46fSAndroid Build Coastguard Worker         pb = sp->refruns;
1524*3ac0a46fSAndroid Build Coastguard Worker         b1 = *pb++;
1525*3ac0a46fSAndroid Build Coastguard Worker #ifdef FAX3_DEBUG
1526*3ac0a46fSAndroid Build Coastguard Worker         printf("\nBitAcc=%08" PRIX32 ", BitsAvail = %d\n", BitAcc, BitsAvail);
1527*3ac0a46fSAndroid Build Coastguard Worker         printf("-------------------- %d\n", tif->tif_row);
1528*3ac0a46fSAndroid Build Coastguard Worker         fflush(stdout);
1529*3ac0a46fSAndroid Build Coastguard Worker #endif
1530*3ac0a46fSAndroid Build Coastguard Worker         EXPAND2D(EOFG4);
1531*3ac0a46fSAndroid Build Coastguard Worker         if (EOLcnt)
1532*3ac0a46fSAndroid Build Coastguard Worker             goto EOFG4;
1533*3ac0a46fSAndroid Build Coastguard Worker         if (((lastx + 7) >> 3) > (int)occ) /* check for buffer overrun */
1534*3ac0a46fSAndroid Build Coastguard Worker         {
1535*3ac0a46fSAndroid Build Coastguard Worker             TIFFErrorExtR(tif, module,
1536*3ac0a46fSAndroid Build Coastguard Worker                           "Buffer overrun detected : %" TIFF_SSIZE_FORMAT
1537*3ac0a46fSAndroid Build Coastguard Worker                           " bytes available, %d bits needed",
1538*3ac0a46fSAndroid Build Coastguard Worker                           occ, lastx);
1539*3ac0a46fSAndroid Build Coastguard Worker             return -1;
1540*3ac0a46fSAndroid Build Coastguard Worker         }
1541*3ac0a46fSAndroid Build Coastguard Worker         (*sp->fill)(buf, thisrun, pa, lastx);
1542*3ac0a46fSAndroid Build Coastguard Worker         SETVALUE(0); /* imaginary change for reference */
1543*3ac0a46fSAndroid Build Coastguard Worker         SWAP(uint32_t *, sp->curruns, sp->refruns);
1544*3ac0a46fSAndroid Build Coastguard Worker         buf += sp->b.rowbytes;
1545*3ac0a46fSAndroid Build Coastguard Worker         occ -= sp->b.rowbytes;
1546*3ac0a46fSAndroid Build Coastguard Worker         sp->line++;
1547*3ac0a46fSAndroid Build Coastguard Worker         continue;
1548*3ac0a46fSAndroid Build Coastguard Worker     EOFG4:
1549*3ac0a46fSAndroid Build Coastguard Worker         NeedBits16(13, BADG4);
1550*3ac0a46fSAndroid Build Coastguard Worker     BADG4:
1551*3ac0a46fSAndroid Build Coastguard Worker #ifdef FAX3_DEBUG
1552*3ac0a46fSAndroid Build Coastguard Worker         if (GetBits(13) != 0x1001)
1553*3ac0a46fSAndroid Build Coastguard Worker             fputs("Bad EOFB\n", stderr);
1554*3ac0a46fSAndroid Build Coastguard Worker #endif
1555*3ac0a46fSAndroid Build Coastguard Worker         ClrBits(13);
1556*3ac0a46fSAndroid Build Coastguard Worker         if (((lastx + 7) >> 3) > (int)occ) /* check for buffer overrun */
1557*3ac0a46fSAndroid Build Coastguard Worker         {
1558*3ac0a46fSAndroid Build Coastguard Worker             TIFFErrorExtR(tif, module,
1559*3ac0a46fSAndroid Build Coastguard Worker                           "Buffer overrun detected : %" TIFF_SSIZE_FORMAT
1560*3ac0a46fSAndroid Build Coastguard Worker                           " bytes available, %d bits needed",
1561*3ac0a46fSAndroid Build Coastguard Worker                           occ, lastx);
1562*3ac0a46fSAndroid Build Coastguard Worker             return -1;
1563*3ac0a46fSAndroid Build Coastguard Worker         }
1564*3ac0a46fSAndroid Build Coastguard Worker         (*sp->fill)(buf, thisrun, pa, lastx);
1565*3ac0a46fSAndroid Build Coastguard Worker         UNCACHE_STATE(tif, sp);
1566*3ac0a46fSAndroid Build Coastguard Worker         return (sp->line ? 1 : -1); /* don't error on badly-terminated strips */
1567*3ac0a46fSAndroid Build Coastguard Worker     }
1568*3ac0a46fSAndroid Build Coastguard Worker     UNCACHE_STATE(tif, sp);
1569*3ac0a46fSAndroid Build Coastguard Worker     return (1);
1570*3ac0a46fSAndroid Build Coastguard Worker }
1571*3ac0a46fSAndroid Build Coastguard Worker #undef SWAP
1572*3ac0a46fSAndroid Build Coastguard Worker 
1573*3ac0a46fSAndroid Build Coastguard Worker /*
1574*3ac0a46fSAndroid Build Coastguard Worker  * Encode the requested amount of data.
1575*3ac0a46fSAndroid Build Coastguard Worker  */
Fax4Encode(TIFF * tif,uint8_t * bp,tmsize_t cc,uint16_t s)1576*3ac0a46fSAndroid Build Coastguard Worker static int Fax4Encode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
1577*3ac0a46fSAndroid Build Coastguard Worker {
1578*3ac0a46fSAndroid Build Coastguard Worker     static const char module[] = "Fax4Encode";
1579*3ac0a46fSAndroid Build Coastguard Worker     Fax3CodecState *sp = EncoderState(tif);
1580*3ac0a46fSAndroid Build Coastguard Worker     (void)s;
1581*3ac0a46fSAndroid Build Coastguard Worker     if (cc % sp->b.rowbytes)
1582*3ac0a46fSAndroid Build Coastguard Worker     {
1583*3ac0a46fSAndroid Build Coastguard Worker         TIFFErrorExtR(tif, module, "Fractional scanlines cannot be written");
1584*3ac0a46fSAndroid Build Coastguard Worker         return (0);
1585*3ac0a46fSAndroid Build Coastguard Worker     }
1586*3ac0a46fSAndroid Build Coastguard Worker     while (cc > 0)
1587*3ac0a46fSAndroid Build Coastguard Worker     {
1588*3ac0a46fSAndroid Build Coastguard Worker         if (!Fax3Encode2DRow(tif, bp, sp->refline, sp->b.rowpixels))
1589*3ac0a46fSAndroid Build Coastguard Worker             return (0);
1590*3ac0a46fSAndroid Build Coastguard Worker         _TIFFmemcpy(sp->refline, bp, sp->b.rowbytes);
1591*3ac0a46fSAndroid Build Coastguard Worker         bp += sp->b.rowbytes;
1592*3ac0a46fSAndroid Build Coastguard Worker         cc -= sp->b.rowbytes;
1593*3ac0a46fSAndroid Build Coastguard Worker     }
1594*3ac0a46fSAndroid Build Coastguard Worker     return (1);
1595*3ac0a46fSAndroid Build Coastguard Worker }
1596*3ac0a46fSAndroid Build Coastguard Worker 
Fax4PostEncode(TIFF * tif)1597*3ac0a46fSAndroid Build Coastguard Worker static int Fax4PostEncode(TIFF *tif)
1598*3ac0a46fSAndroid Build Coastguard Worker {
1599*3ac0a46fSAndroid Build Coastguard Worker     Fax3CodecState *sp = EncoderState(tif);
1600*3ac0a46fSAndroid Build Coastguard Worker 
1601*3ac0a46fSAndroid Build Coastguard Worker     /* terminate strip w/ EOFB */
1602*3ac0a46fSAndroid Build Coastguard Worker     Fax3PutBits(tif, EOL, 12);
1603*3ac0a46fSAndroid Build Coastguard Worker     Fax3PutBits(tif, EOL, 12);
1604*3ac0a46fSAndroid Build Coastguard Worker     if (sp->bit != 8)
1605*3ac0a46fSAndroid Build Coastguard Worker         Fax3FlushBits(tif, sp);
1606*3ac0a46fSAndroid Build Coastguard Worker     return (1);
1607*3ac0a46fSAndroid Build Coastguard Worker }
1608*3ac0a46fSAndroid Build Coastguard Worker 
TIFFInitCCITTFax4(TIFF * tif,int scheme)1609*3ac0a46fSAndroid Build Coastguard Worker int TIFFInitCCITTFax4(TIFF *tif, int scheme)
1610*3ac0a46fSAndroid Build Coastguard Worker {
1611*3ac0a46fSAndroid Build Coastguard Worker     (void)scheme;
1612*3ac0a46fSAndroid Build Coastguard Worker     if (InitCCITTFax3(tif))
1613*3ac0a46fSAndroid Build Coastguard Worker     { /* reuse G3 support */
1614*3ac0a46fSAndroid Build Coastguard Worker         /*
1615*3ac0a46fSAndroid Build Coastguard Worker          * Merge codec-specific tag information.
1616*3ac0a46fSAndroid Build Coastguard Worker          */
1617*3ac0a46fSAndroid Build Coastguard Worker         if (!_TIFFMergeFields(tif, fax4Fields, TIFFArrayCount(fax4Fields)))
1618*3ac0a46fSAndroid Build Coastguard Worker         {
1619*3ac0a46fSAndroid Build Coastguard Worker             TIFFErrorExtR(tif, "TIFFInitCCITTFax4",
1620*3ac0a46fSAndroid Build Coastguard Worker                           "Merging CCITT Fax 4 codec-specific tags failed");
1621*3ac0a46fSAndroid Build Coastguard Worker             return 0;
1622*3ac0a46fSAndroid Build Coastguard Worker         }
1623*3ac0a46fSAndroid Build Coastguard Worker 
1624*3ac0a46fSAndroid Build Coastguard Worker         tif->tif_decoderow = Fax4Decode;
1625*3ac0a46fSAndroid Build Coastguard Worker         tif->tif_decodestrip = Fax4Decode;
1626*3ac0a46fSAndroid Build Coastguard Worker         tif->tif_decodetile = Fax4Decode;
1627*3ac0a46fSAndroid Build Coastguard Worker         tif->tif_encoderow = Fax4Encode;
1628*3ac0a46fSAndroid Build Coastguard Worker         tif->tif_encodestrip = Fax4Encode;
1629*3ac0a46fSAndroid Build Coastguard Worker         tif->tif_encodetile = Fax4Encode;
1630*3ac0a46fSAndroid Build Coastguard Worker         tif->tif_postencode = Fax4PostEncode;
1631*3ac0a46fSAndroid Build Coastguard Worker         /*
1632*3ac0a46fSAndroid Build Coastguard Worker          * Suppress RTC at the end of each strip.
1633*3ac0a46fSAndroid Build Coastguard Worker          */
1634*3ac0a46fSAndroid Build Coastguard Worker         return TIFFSetField(tif, TIFFTAG_FAXMODE, FAXMODE_NORTC);
1635*3ac0a46fSAndroid Build Coastguard Worker     }
1636*3ac0a46fSAndroid Build Coastguard Worker     else
1637*3ac0a46fSAndroid Build Coastguard Worker         return (0);
1638*3ac0a46fSAndroid Build Coastguard Worker }
1639*3ac0a46fSAndroid Build Coastguard Worker 
1640*3ac0a46fSAndroid Build Coastguard Worker /*
1641*3ac0a46fSAndroid Build Coastguard Worker  * CCITT Group 3 1-D Modified Huffman RLE Compression Support.
1642*3ac0a46fSAndroid Build Coastguard Worker  * (Compression algorithms 2 and 32771)
1643*3ac0a46fSAndroid Build Coastguard Worker  */
1644*3ac0a46fSAndroid Build Coastguard Worker 
1645*3ac0a46fSAndroid Build Coastguard Worker /*
1646*3ac0a46fSAndroid Build Coastguard Worker  * Decode the requested amount of RLE-encoded data.
1647*3ac0a46fSAndroid Build Coastguard Worker  */
Fax3DecodeRLE(TIFF * tif,uint8_t * buf,tmsize_t occ,uint16_t s)1648*3ac0a46fSAndroid Build Coastguard Worker static int Fax3DecodeRLE(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s)
1649*3ac0a46fSAndroid Build Coastguard Worker {
1650*3ac0a46fSAndroid Build Coastguard Worker     DECLARE_STATE(tif, sp, "Fax3DecodeRLE");
1651*3ac0a46fSAndroid Build Coastguard Worker     int mode = sp->b.mode;
1652*3ac0a46fSAndroid Build Coastguard Worker     (void)s;
1653*3ac0a46fSAndroid Build Coastguard Worker     if (occ % sp->b.rowbytes)
1654*3ac0a46fSAndroid Build Coastguard Worker     {
1655*3ac0a46fSAndroid Build Coastguard Worker         TIFFErrorExtR(tif, module, "Fractional scanlines cannot be read");
1656*3ac0a46fSAndroid Build Coastguard Worker         return (-1);
1657*3ac0a46fSAndroid Build Coastguard Worker     }
1658*3ac0a46fSAndroid Build Coastguard Worker     CACHE_STATE(tif, sp);
1659*3ac0a46fSAndroid Build Coastguard Worker     thisrun = sp->curruns;
1660*3ac0a46fSAndroid Build Coastguard Worker     while (occ > 0)
1661*3ac0a46fSAndroid Build Coastguard Worker     {
1662*3ac0a46fSAndroid Build Coastguard Worker         a0 = 0;
1663*3ac0a46fSAndroid Build Coastguard Worker         RunLength = 0;
1664*3ac0a46fSAndroid Build Coastguard Worker         pa = thisrun;
1665*3ac0a46fSAndroid Build Coastguard Worker #ifdef FAX3_DEBUG
1666*3ac0a46fSAndroid Build Coastguard Worker         printf("\nBitAcc=%08" PRIX32 ", BitsAvail = %d\n", BitAcc, BitsAvail);
1667*3ac0a46fSAndroid Build Coastguard Worker         printf("-------------------- %" PRIu32 "\n", tif->tif_row);
1668*3ac0a46fSAndroid Build Coastguard Worker         fflush(stdout);
1669*3ac0a46fSAndroid Build Coastguard Worker #endif
1670*3ac0a46fSAndroid Build Coastguard Worker         EXPAND1D(EOFRLE);
1671*3ac0a46fSAndroid Build Coastguard Worker         (*sp->fill)(buf, thisrun, pa, lastx);
1672*3ac0a46fSAndroid Build Coastguard Worker         /*
1673*3ac0a46fSAndroid Build Coastguard Worker          * Cleanup at the end of the row.
1674*3ac0a46fSAndroid Build Coastguard Worker          */
1675*3ac0a46fSAndroid Build Coastguard Worker         if (mode & FAXMODE_BYTEALIGN)
1676*3ac0a46fSAndroid Build Coastguard Worker         {
1677*3ac0a46fSAndroid Build Coastguard Worker             int n = BitsAvail - (BitsAvail & ~7);
1678*3ac0a46fSAndroid Build Coastguard Worker             ClrBits(n);
1679*3ac0a46fSAndroid Build Coastguard Worker         }
1680*3ac0a46fSAndroid Build Coastguard Worker         else if (mode & FAXMODE_WORDALIGN)
1681*3ac0a46fSAndroid Build Coastguard Worker         {
1682*3ac0a46fSAndroid Build Coastguard Worker             int n = BitsAvail - (BitsAvail & ~15);
1683*3ac0a46fSAndroid Build Coastguard Worker             ClrBits(n);
1684*3ac0a46fSAndroid Build Coastguard Worker             if (BitsAvail == 0 && !isAligned(cp, uint16_t))
1685*3ac0a46fSAndroid Build Coastguard Worker                 cp++;
1686*3ac0a46fSAndroid Build Coastguard Worker         }
1687*3ac0a46fSAndroid Build Coastguard Worker         buf += sp->b.rowbytes;
1688*3ac0a46fSAndroid Build Coastguard Worker         occ -= sp->b.rowbytes;
1689*3ac0a46fSAndroid Build Coastguard Worker         sp->line++;
1690*3ac0a46fSAndroid Build Coastguard Worker         continue;
1691*3ac0a46fSAndroid Build Coastguard Worker     EOFRLE: /* premature EOF */
1692*3ac0a46fSAndroid Build Coastguard Worker         (*sp->fill)(buf, thisrun, pa, lastx);
1693*3ac0a46fSAndroid Build Coastguard Worker         UNCACHE_STATE(tif, sp);
1694*3ac0a46fSAndroid Build Coastguard Worker         return (-1);
1695*3ac0a46fSAndroid Build Coastguard Worker     }
1696*3ac0a46fSAndroid Build Coastguard Worker     UNCACHE_STATE(tif, sp);
1697*3ac0a46fSAndroid Build Coastguard Worker     return (1);
1698*3ac0a46fSAndroid Build Coastguard Worker }
1699*3ac0a46fSAndroid Build Coastguard Worker 
TIFFInitCCITTRLE(TIFF * tif,int scheme)1700*3ac0a46fSAndroid Build Coastguard Worker int TIFFInitCCITTRLE(TIFF *tif, int scheme)
1701*3ac0a46fSAndroid Build Coastguard Worker {
1702*3ac0a46fSAndroid Build Coastguard Worker     (void)scheme;
1703*3ac0a46fSAndroid Build Coastguard Worker     if (InitCCITTFax3(tif))
1704*3ac0a46fSAndroid Build Coastguard Worker     { /* reuse G3 support */
1705*3ac0a46fSAndroid Build Coastguard Worker         tif->tif_decoderow = Fax3DecodeRLE;
1706*3ac0a46fSAndroid Build Coastguard Worker         tif->tif_decodestrip = Fax3DecodeRLE;
1707*3ac0a46fSAndroid Build Coastguard Worker         tif->tif_decodetile = Fax3DecodeRLE;
1708*3ac0a46fSAndroid Build Coastguard Worker         /*
1709*3ac0a46fSAndroid Build Coastguard Worker          * Suppress RTC+EOLs when encoding and byte-align data.
1710*3ac0a46fSAndroid Build Coastguard Worker          */
1711*3ac0a46fSAndroid Build Coastguard Worker         return TIFFSetField(tif, TIFFTAG_FAXMODE,
1712*3ac0a46fSAndroid Build Coastguard Worker                             FAXMODE_NORTC | FAXMODE_NOEOL | FAXMODE_BYTEALIGN);
1713*3ac0a46fSAndroid Build Coastguard Worker     }
1714*3ac0a46fSAndroid Build Coastguard Worker     else
1715*3ac0a46fSAndroid Build Coastguard Worker         return (0);
1716*3ac0a46fSAndroid Build Coastguard Worker }
1717*3ac0a46fSAndroid Build Coastguard Worker 
TIFFInitCCITTRLEW(TIFF * tif,int scheme)1718*3ac0a46fSAndroid Build Coastguard Worker int TIFFInitCCITTRLEW(TIFF *tif, int scheme)
1719*3ac0a46fSAndroid Build Coastguard Worker {
1720*3ac0a46fSAndroid Build Coastguard Worker     (void)scheme;
1721*3ac0a46fSAndroid Build Coastguard Worker     if (InitCCITTFax3(tif))
1722*3ac0a46fSAndroid Build Coastguard Worker     { /* reuse G3 support */
1723*3ac0a46fSAndroid Build Coastguard Worker         tif->tif_decoderow = Fax3DecodeRLE;
1724*3ac0a46fSAndroid Build Coastguard Worker         tif->tif_decodestrip = Fax3DecodeRLE;
1725*3ac0a46fSAndroid Build Coastguard Worker         tif->tif_decodetile = Fax3DecodeRLE;
1726*3ac0a46fSAndroid Build Coastguard Worker         /*
1727*3ac0a46fSAndroid Build Coastguard Worker          * Suppress RTC+EOLs when encoding and word-align data.
1728*3ac0a46fSAndroid Build Coastguard Worker          */
1729*3ac0a46fSAndroid Build Coastguard Worker         return TIFFSetField(tif, TIFFTAG_FAXMODE,
1730*3ac0a46fSAndroid Build Coastguard Worker                             FAXMODE_NORTC | FAXMODE_NOEOL | FAXMODE_WORDALIGN);
1731*3ac0a46fSAndroid Build Coastguard Worker     }
1732*3ac0a46fSAndroid Build Coastguard Worker     else
1733*3ac0a46fSAndroid Build Coastguard Worker         return (0);
1734*3ac0a46fSAndroid Build Coastguard Worker }
1735*3ac0a46fSAndroid Build Coastguard Worker #endif /* CCITT_SUPPORT */
1736