Add GNU LGPL headers to all .c .C and .h files
[oweals/cde.git] / cde / lib / DtHelp / il / ildecompg4.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* $XConsortium: ildecompg4.c /main/6 1996/06/19 12:23:48 ageorge $ */
24 /**---------------------------------------------------------------------
25 ***     
26 ***    (c)Copyright 1991 Hewlett-Packard Co.
27 ***    
28 ***                             RESTRICTED RIGHTS LEGEND
29 ***    Use, duplication, or disclosure by the U.S. Government is subject to
30 ***    restrictions as set forth in sub-paragraph (c)(1)(ii) of the Rights in
31 ***    Technical Data and Computer Software clause in DFARS 252.227-7013.
32 ***                             Hewlett-Packard Company
33 ***                             3000 Hanover Street
34 ***                             Palo Alto, CA 94304 U.S.A.
35 ***    Rights for non-DOD U.S. Government Departments and Agencies are as set
36 ***    forth in FAR 52.227-19(c)(1,2).
37 ***
38 ***-------------------------------------------------------------------*/
39
40
41 #include <math.h>
42 #include <stdio.h>       
43
44 #include "ilint.h"
45 #include "ilpipelem.h"
46 #include "ilerrors.h"
47 #include "ildecomp.h"
48 #include "ildecompg4.h"
49 #include "ildecompg4table.h"
50
51 /*  Table containing (array) the number of consecutive zeros 
52     from the start (msb first), in chars  for 0x00 to 0xff 
53     for e.g  number of consecutive zeros in 0x00 = 8 
54                                          in 0x0f = 4               */
55
56 static unsigned char zeroruns[256] = {
57         8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, /* 0x00 - 0x0f */
58         3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 0x10 - 0x1f */
59         2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0x20 - 0x2f */
60         2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0x30 - 0x3f */
61         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x40 - 0x4f */
62         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x50 - 0x5f */
63         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x60 - 0x6f */
64         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x70 - 0x7f */
65         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80 - 0x8f */
66         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90 - 0x9f */
67         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xa0 - 0xaf */
68         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xb0 - 0xbf */
69         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xc0 - 0xcf */
70         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xd0 - 0xdf */
71         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xe0 - 0xef */
72         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xf0 - 0xff */
73 };
74
75
76 /*  Table containing (array) the number of consecutive ones 
77     from the start (msb first), in chars  for 0x00 to 0xff         
78     for e.g  number of consecutive ones  in 0x00 = 0 
79                                          in 0xff = 8               */
80
81
82 static unsigned char oneruns[256] = {
83         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00 - 0x0f */
84         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10 - 0x1f */
85         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20 - 0x2f */
86         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x30 - 0x3f */
87         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x40 - 0x4f */
88         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x50 - 0x5f */
89         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60 - 0x6f */
90         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70 - 0x7f */
91         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x80 - 0x8f */
92         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x90 - 0x9f */
93         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0xa0 - 0xaf */
94         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0xb0 - 0xbf */
95         2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0xc0 - 0xcf */
96         2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0xd0 - 0xdf */
97         3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 0xe0 - 0xef */
98         4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 7, 8, /* 0xf0 - 0xff */
99 };
100
101
102 /*  This module G4 Decompression has been totally rewritten ...  
103      Earlier module handled images with LSB first only,
104      and failing while handling  images Compressed in Strips.
105      
106      The present implementation uses the same tables, and takes care of the
107      above issues. Additionally, it has been designed in such a way as that
108      these decompression can be used for G3 - 2D decompression also.
109                                                                              */
110
111 /* ========================================================================
112
113         --------------------  _ilPutOnes(). --------------------
114    Input : pointer to the current Image Destination line  (*sByte)
115            startPixel - from which position 1's are to be put
116            no_of_ones - how many pixels are to be put with ones
117    Does  :
118
119    Utility function to put 1's (no_of_ones) in the string, pointed by
120    *sByte, from the position startPixel; Used to fill the Destination
121    image while De-Compressing. Initially the Destination image is filled
122    with Zeros 0's ; While De-Compressing,  1's are filled appropriately
123    to construct the Image..                              
124  
125      ** used in G3 & G4 Decompression
126
127    ======================================================================== */
128
129 IL_PRIVATE  void
130 _ilPutOnes(
131 register char *sByte,
132 register int startPixel,
133 register int  no_of_ones )
134
135 {
136         static const unsigned char masks[] =
137         { 
138                 0, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff       };
139
140         /* fill 1's in  the current  Byte */
141
142         sByte += startPixel>>3;
143         if (startPixel &= 7) {                  /* align to byte boundary */
144                 if (no_of_ones < 8 - startPixel) {
145                         *sByte++ |= masks[no_of_ones] >> startPixel;
146                         return;
147                 }
148                 *sByte++ |= 0xff >> startPixel;
149                 no_of_ones -= 8 - startPixel;
150         }
151
152         /* fill 1's in  the consecutive  Full Bytes */
153         memset(sByte,0xff,(no_of_ones >> 3));
154         sByte += (no_of_ones >> 3 );
155         no_of_ones = no_of_ones & 7 ;
156
157         /* fill 1's in  the last partial  Byte */
158         *sByte |= masks[no_of_ones];
159 }
160
161 /* ========================================================================
162
163         --------------------  _ilGetAbsDiff(). --------------------
164   Input : the pointer to the pointer to the strings (image Line)
165           startPixel from which the diff. is to be found
166           endPixel i.e upto which the diff can be checked.
167           color of the current pixel (startPixel)
168           nTimes - no. of times the counting is to be repeated i.e for 
169                    how many changing elements, the operation is to be
170                    performed.
171
172   Does : 
173     Calculates the count of pixels of the same color  and returns the absolute
174     position of the next    changing element and Returns the Absolute Position 
175     of the element
176
177       **  used for G4,G3-2d compression and de-comression    
178    ======================================================================== */
179
180 static int
181 _ilGetAbsDiff(  unsigned char *sByte,
182 int startPixel,
183 int endPixel,
184 int color,
185 int nTimes)
186 {
187
188         register unsigned char *bp;
189         register int ini_diff;
190         register int n, fin_diff;
191         register unsigned char *table ;
192
193         bp = sByte;
194
195         bp += startPixel>> 3;                   /* adjust byte offset */
196
197         do {
198
199                 if ((startPixel == -1) ) {
200                         fin_diff = 1;
201                         bp       = sByte;
202                         goto done;
203                 }
204                 else {
205
206                         table = (color ? oneruns : zeroruns );
207                         ini_diff = endPixel- startPixel;
208
209                         /*  Find difference in the partial byte on the current Byte */
210
211                         if (ini_diff > 0 && (n = (startPixel & 7))) {
212                                 fin_diff = table[(*bp << n) & 0xff];
213
214                                 if (fin_diff > 8-n)             /* Consecutive bits extend beyond the current byte */
215                                         fin_diff = 8-n;
216
217
218                                 /* return the initial differece, if the current byte happens
219                    to be the last byte of the Imageline and cosecutive bits
220                    extend beyound that.                                      */
221
222                                 if (fin_diff > ini_diff)
223                                         fin_diff = ini_diff;
224
225                                 if (n + fin_diff < 8 )  /* Consecutive bits does not  go upto the edge, so return the diff */
226                                         goto done;
227                                 ini_diff -= fin_diff;
228                                 bp++;
229                         } else
230                                 fin_diff = 0;
231
232                         /*  Count in the bytes, till opp. color is found
233                 i.e while the diff >= 8                          */
234
235                         while (ini_diff >= 8) {
236                                 n = table[*bp];
237                                 fin_diff += n;
238                                 ini_diff -= n;
239                                 if (n < 8)              /* end of run */
240                                         goto done;
241
242                                 bp++;
243                         }
244
245                         /*  Find difference in the partial byte on RHS */
246
247                         if (ini_diff > 0) {
248                                 n = table[*bp];
249                                 fin_diff += (n > ini_diff ? ini_diff : n);
250                         }
251                 }
252 done:
253                 startPixel +=  fin_diff;
254                 color       = !color;
255
256         } while (--nTimes > 0 );
257
258         return(startPixel);
259
260 }
261 /* --------------- End of  _ilGetAbsDiff()  ---------------- */
262
263 /* ========================================================================
264        -------------------- _ilDeCompressG4Init -------------------
265    Routine defined in ilDeCompG4 for initializing CCITT Group3  
266    compression when the pipe gets executed.
267
268    ======================================================================== */
269
270 static ilError _ilDecompG4Init(
271 ilDecompG3G4PrivPtr     pPriv,
272 ilImageInfo            *pSrcImage,
273 ilImageInfo            *pDstImage
274 )
275 {
276         /* Allocate space for Reference line, needed for 2 dimensional coding */
277
278         pPriv->gpRefLine = (ilPtr)IL_MALLOC(pPriv->nDstLineBytes );
279         if (!pPriv->gpRefLine)
280                 return IL_ERROR_MALLOC;
281         return IL_OK;
282
283 }
284 /* ========================================================================
285        -------------------- _ilDeCompressG4Cleanup -------------------
286    ======================================================================== */
287
288 static ilError _ilDecompG4Cleanup(
289 ilDecompG3G4PrivPtr     pPriv,
290 ilImageInfo            *pSrcImage,
291 ilImageInfo            *pDstImage
292 )
293 {
294         /* De-Allocate the space for Reference line */
295         if (pPriv->gpRefLine)
296                 IL_FREE( (ilPtr)pPriv->gpRefLine);
297         return IL_OK;
298
299 }
300
301
302 /* Macros used in _ilDecompG4Line()            */
303 /* Macros for Getting the Number of White Runs */
304
305 #define G4_GET_WHITE_RUN(whiteRun) {                            \
306   whiteRun = 0;                                                 \
307    do {                                                         \
308         if ( Is_Lsb_First )                                     \
309            GET_VALUE_LSB(bits,ImageP, srcpos,  G4M_WhiteRun)    \
310         else                                                    \
311            GET_VALUE_MSB(bits,ImageP, srcpos,  G4M_WhiteRun)    \
312         pDecodeTemp = pDecodeWhite+bits;                        \
313         srcpos += pDecodeTemp->length;                          \
314         whiteRun += pDecodeTemp->value;                         \
315     } while (pDecodeTemp->type != G4K_CodetypeTerminator) ;     \
316 }
317
318 /* Macros for Getting the Number of Black Runs */
319
320 #define G4_GET_BLACK_RUN(blackRun) {                            \
321   blackRun = 0;                                                 \
322    do {                                                         \
323         if ( Is_Lsb_First )                                     \
324            GET_VALUE_LSB(bits,ImageP, srcpos,  G4M_BlackRun)    \
325         else                                                    \
326            GET_VALUE_MSB(bits,ImageP, srcpos,  G4M_BlackRun)    \
327         pDecodeTemp = pDecodeBlack+bits;                        \
328         srcpos += pDecodeTemp->length;                          \
329         blackRun += pDecodeTemp->value;                         \
330     } while (pDecodeTemp->type != G4K_CodetypeTerminator) ;     \
331 }
332
333 /* ========================================================================    
334     -------------------- _ilDecompG4Line -------------------
335    Input : pointer to the Private data record or decompG3G4
336            pointer to the Reference line
337            pointer to the Destination image
338    Does  : Reading the Source Image, De-Compresses One line for the destn.
339            image by Two dimensional coding.
340    ======================================================================== */
341 ilError   _ilDecompG4Line(
342 register ilDecompG3G4PrivPtr  pPriv,
343 ilPtr          pRefLine,
344 ilPtr          dstImageP
345 )
346 {
347
348         int a0,b1,b2;            /* changing elements used  while decomressing */
349         short color;             /* color of the pixel                         */
350         int firstRun;            /* no. of consecutive pixels for M(a0a1) in  Horiz mode */
351         int secondRun;           /* no. of consecutive pixels for M(a1a2) in  Horiz mode */
352
353         long bits ;
354         long width;
355         ilBool Is_Lsb_First ;
356         ilPtr ImageP;
357         int srcpos;
358
359         register ilDecompG4HuffTablePtrConst pDecodeWhite = ilArFax1DDecodeWhite;
360         register ilDecompG4HuffTablePtrConst pDecodeTemp;
361         register ilDecompG4HuffTablePtrConst pDecodeBlack = ilArFax1DDecodeBlack;
362
363
364         /*  Deccompression Procedure  ....
365
366     From the compressed data from Source Image .. retrieve a long bit; use this as
367     index to determine the 2d coded mode (Pass or Horiz or Vert(-3 to 3) );
368     Depending upon the mode, calculate the changing elements b1,b2 and adjust a0;
369     If 1's have to filled to the destination image, call _ilPutOnes(..);
370     If Horiz. mode is identified, call macros G4_GET_WHITERUN(..) & G4_GETBLACKRUN(..)
371     to estimate the first and second runs and fill 1's;
372     This loop will have to repeated until the value of a0 reaches the ImageWidth.
373     See ilcompressg4.c for more infn. on G4 compression .
374
375    */
376
377         width = pPriv->width;
378
379         a0    = -1;
380         color = pPriv->white;
381         Is_Lsb_First =  pPriv->Is_Lsb_First;
382         srcpos       =  pPriv->srcpos;
383         ImageP       =  pPriv->ImageP;
384
385         do {                  /* till a complete Image line is DeCompressed */
386
387                 if ( Is_Lsb_First )
388                     GET_VALUE_LSB(bits,ImageP, srcpos, G4M_Codeword)
389                 else
390                         GET_VALUE_MSB(bits,ImageP, srcpos, G4M_Codeword)
391
392                 if (ilArFax2DDecodeTable[bits].type != G4K_CodetypeTerminator)
393                         return  IL_ERROR_COMPRESSED_DATA ;
394
395                 srcpos += ilArFax2DDecodeTable[bits].length;
396
397                 switch (ilArFax2DDecodeTable[bits].value) {
398
399                         /* State mode is codeword, codeword type is TERMINATOR,
400                      codeword value is PASS */
401
402                 case G4K_CodevaluePass:
403
404                         b2 = _ilGetAbsDiff(pRefLine, a0, width, !color,3);
405                         if (color) {
406                                 if (a0 < 0)     a0 = 0;
407                                 if ( (b2-a0) > 0 )
408                                         _ilPutOnes((char *)dstImageP, a0, b2 - a0);
409                         }
410                         a0 = b2;
411                         break;
412
413                         /* State mode is Codeword, codeword type is TERMINATOR,
414                     codeword value is HORIZONTAL */
415
416                 case G4K_CodevalueHoriz:
417
418                         if (color == pPriv->white) {
419                                 G4_GET_WHITE_RUN(firstRun) ;
420                                 G4_GET_BLACK_RUN(secondRun);
421                         }
422                         else {
423                                 G4_GET_BLACK_RUN(firstRun);
424                                 G4_GET_WHITE_RUN(secondRun) ;
425                         }
426
427                         if (a0 < 0)     a0 = 0;
428                         if (a0 + firstRun > width)
429                                 firstRun = width - a0;
430                         if ( (color) && ( firstRun > 0 ) )
431                                 _ilPutOnes((char *)dstImageP, a0, firstRun);
432
433                         a0 += firstRun;
434
435                         if (a0 + secondRun > width)
436                                 secondRun = width - a0;
437                         if ( (!color) && ( secondRun > 0 ) )
438                                 _ilPutOnes((char *)dstImageP, a0, secondRun);
439                         a0 += secondRun;
440                         break;
441
442
443                         /* State mode is codeword, codeword type is TERMINATOR, 
444                      codeword value is VERTICAL */
445
446                 case G4K_CodevalueV0:
447                 case G4K_CodevalueVR1:
448                 case G4K_CodevalueVL1:
449                 case G4K_CodevalueVR2:
450                 case G4K_CodevalueVL2:
451                 case G4K_CodevalueVR3:
452                 case G4K_CodevalueVL3:
453
454                         b1 = _ilGetAbsDiff(pRefLine, a0, width, !color,2);
455                         b1 += ilArFax2DDecodeTable[bits].value;
456                         if (b1 > width)
457                b1 = width;
458                         if (color) {
459                                 if (a0 < 0)  a0 = 0;
460                                 if ( (b1-a0) > 0 )
461                                         _ilPutOnes((char *)dstImageP, a0, b1 - a0);
462                         }
463                         color = !color;
464                         a0 = b1;
465                         break;
466
467                 default:
468                         /* found invalid codeword values, return error  */
469                         return  IL_ERROR_COMPRESSED_DATA ;
470                 }
471
472         } while (a0 < width);       /* End of Image line is reached */
473
474         pPriv->srcpos =   srcpos;
475         return IL_OK ;
476
477 }
478
479 /* ========================================================================    
480           
481     -------------------- ilDecompG4Execute -------------------
482     Routine defined in ilDecompG4 for executing CCITT Group4
483     decompression when the pipe gets executed.
484
485    ======================================================================== */
486
487 static ilError _ilDecompG4Execute(
488 ilExecuteData      *pData,
489 unsigned long       dstLine,
490 unsigned long      *pNLines
491 )
492 {
493         /* ========================================================================
494    ilDecompG4Execute() definitions
495    ======================================================================== */
496
497         ilImagePlaneInfo   *pSrcPlane;         /* Pointer to the Source Image Plane     */
498         ilImagePlaneInfo   *pDstPlane;         /* Pointer to the Source Image Plane     */
499         ilPtr               pSrcLine;          /* Pointer to the Source Image FirstLine */
500         ilDecompG3G4PrivPtr pPriv;             /* Pointer to private image data         */
501
502         ilPtr               dstImageP;         /* Pointer to the Destn. Image           */
503         ilPtr               pRefLine;          /* Pointer to the Reference line         */
504         ilError             error;             /* Returned error                        */
505         int                 dstBytesPerRow;    /* no.of byte per Row in the dest image  */
506     long                nLines;            /* no. of lines in the current strip     */
507
508         /* ========================================================================
509    ilDecompG4Execute() set up for decompression algorithm code
510    ======================================================================== */
511
512         pPriv   = (ilDecompG3G4PrivPtr) pData->pPrivate;
513
514         if ( *pNLines <= 0 ) return IL_OK ;
515         if ( pData->compressed.nBytesToRead <= 0 ) return IL_OK ;                         
516     nLines  = *pNLines;
517
518         /* Exit if pointer to pPixels is NULL */
519         pSrcPlane           = &pData->pSrcImage->plane[0];
520         if (!pSrcPlane->pPixels) return IL_ERROR_NULL_COMPRESSED_IMAGE;
521         pSrcLine            =  pSrcPlane->pPixels + pData->compressed.srcOffset; /* image location pointer */
522
523         pDstPlane           = &pData->pDstImage->plane[0];
524
525         /* The destination image line pointer gets updated at the beginning of each strip */
526         dstImageP          = (pDstPlane->pPixels + (dstLine * pDstPlane->nBytesPerRow));
527         dstBytesPerRow     = pDstPlane->nBytesPerRow ;
528
529         /* ========================================================================
530     Zero the output (dst) buffer.  _ilPutOnes()  writes only ones, and expects 
531     that    the dst lines have already been zeroed. 
532     ======================================================================== */
533         bzero ((char *)dstImageP, (pDstPlane->nBytesPerRow * *pNLines) );
534
535         /* Allocate space for the Reference line and set to zero Or 1's         */
536
537         if (pPriv->white)
538                 memset(pPriv->gpRefLine,0xff,(pDstPlane->nBytesPerRow ));
539         else
540                 memset(pPriv->gpRefLine,0x00,(pDstPlane->nBytesPerRow ));
541
542         pRefLine = pPriv->gpRefLine;
543
544         pPriv->srcpos        =  0;
545         pPriv->ImageP        = pSrcLine;
546         pPriv->Is_Lsb_First  =  ( ( pPriv->compFlags  & IL_G4M_LSB_FIRST) ? 1 : 0 );
547
548     /* this pPriv->maxSrcPos is set to the bits that could be read, to prevent the
549        program from reading beyond the compressed bytes; this check is done by
550        the macro Get_value_msb & lsb                                              */
551
552     pPriv->maxSrcPos     =  pData->compressed.nBytesToRead * 8 ;
553
554         /* till the Destination Image is filled up , call the decompress from the
555        source line by line.. If any error in reading the compressed data, i.e
556        invalid Code words or invalid Modes are found will retrun the error
557        IL_ERROR_COMPRESSED_DATA .
558        After decompressing each line, the decompressed line is set as reference
559        line for the next line to be decompressed.
560        Destination image size and Pointer are suitably decremented & incremented.
561     */
562
563         while ( nLines-- > 0 )
564         {
565
566                 if (error = _ilDecompG4Line(pPriv,pRefLine,dstImageP) )
567                         return error;
568
569                 pRefLine       =   dstImageP;
570                 dstImageP     +=   dstBytesPerRow;
571
572         }
573
574         return IL_OK;
575 }
576 /* End ilDecompG4Execute() */
577
578 /* ========================================================================
579
580           -------------------- ilDecompG4() -------------------
581     Entry point of code for CCITT Group4 decompression.  This
582     includes image descriptor parameter error checking and function calls
583     for: strip handler initialization, adding the filter element to the
584     pipe, pipe initialization and execution, decompression algorithm,
585     along with cleanup and destruction of allocated memory.....
586
587    ======================================================================== */
588
589 IL_PRIVATE
590 ilBool _ilDecompG4 (
591 ilPipe              pipe,
592 ilPipeInfo         *pinfo,                              
593 ilImageDes         *pimdes
594 )
595 {
596
597         ilDstElementData    dstdata;
598         ilDecompG3G4PrivPtr       pPriv;
599         ilImageDes          des;
600
601         /*  Validate that image is bitonal */
602         if (pimdes->type != IL_BITONAL)
603                 return ilDeclarePipeInvalid (pipe, IL_ERROR_IMAGE_TYPE);
604
605         /*
606         Check for Group4, uncompressed, or any undefined bits on.  These
607         are not supported!
608     */
609         if (pimdes->compInfo.g4.flags & IL_G4M_UNCOMPRESSED )
610                 return ilDeclarePipeInvalid (pipe, IL_ERROR_NOT_IMPLEMENTED);
611
612
613         /* dstdata describes strips being output to next pipe element */
614         dstdata.producerObject  =  (ilObject) NULL;
615         des                     = *pimdes;
616         des.compression         =  IL_UNCOMPRESSED;
617         des.compInfo.g4.flags   =  NULL;
618         dstdata.pDes            =  &des;
619         dstdata.pFormat         =  IL_FORMAT_BIT;
620         dstdata.width           =  pinfo->width;
621         dstdata.height          =  pinfo->height;
622         dstdata.pPalette        =  (unsigned short *)NULL;
623
624         /* set output strip height */
625         dstdata.stripHeight     =  pinfo->stripHeight;
626         dstdata.constantStrip   =  pinfo->constantStrip;
627
628         dstdata.pCompData       =  (ilPtr)NULL;
629
630         pPriv = (ilDecompG3G4PrivPtr) ilAddPipeElement(pipe, IL_FILTER, 
631             sizeof(ilDecompG3G4PrivRec), 0,
632             (ilSrcElementData *)NULL,
633             &dstdata, _ilDecompG4Init,_ilDecompG4Cleanup,
634             IL_NPF, _ilDecompG4Execute, NULL, 0);
635
636         if (!pPriv) return FALSE; /* EXIT */
637
638         /* save private data */
639         pPriv->width         = pinfo->width;
640         pPriv->white         =  ( des.blackIsZero ? 1 : 0 );
641         pPriv->compFlags     = pimdes->compInfo.g4.flags;
642         pPriv->nDstLineBytes = (pPriv->width + 7) / 8;
643         return TRUE;
644 }