ildecompg4.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645
  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 libraries 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. #include <math.h>
  40. #include <stdio.h>
  41. #include <stdlib.h>
  42. #include "ilint.h"
  43. #include "ilpipelem.h"
  44. #include "ilerrors.h"
  45. #include "ildecomp.h"
  46. #include "ildecompg4.h"
  47. #include "ildecompg4table.h"
  48. /* Table containing (array) the number of consecutive zeros
  49. from the start (msb first), in chars for 0x00 to 0xff
  50. for e.g number of consecutive zeros in 0x00 = 8
  51. in 0x0f = 4 */
  52. static unsigned char zeroruns[256] = {
  53. 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, /* 0x00 - 0x0f */
  54. 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 0x10 - 0x1f */
  55. 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0x20 - 0x2f */
  56. 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0x30 - 0x3f */
  57. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x40 - 0x4f */
  58. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x50 - 0x5f */
  59. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x60 - 0x6f */
  60. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x70 - 0x7f */
  61. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80 - 0x8f */
  62. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90 - 0x9f */
  63. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xa0 - 0xaf */
  64. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xb0 - 0xbf */
  65. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xc0 - 0xcf */
  66. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xd0 - 0xdf */
  67. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xe0 - 0xef */
  68. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xf0 - 0xff */
  69. };
  70. /* Table containing (array) the number of consecutive ones
  71. from the start (msb first), in chars for 0x00 to 0xff
  72. for e.g number of consecutive ones in 0x00 = 0
  73. in 0xff = 8 */
  74. static unsigned char oneruns[256] = {
  75. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00 - 0x0f */
  76. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10 - 0x1f */
  77. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20 - 0x2f */
  78. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x30 - 0x3f */
  79. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x40 - 0x4f */
  80. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x50 - 0x5f */
  81. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60 - 0x6f */
  82. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70 - 0x7f */
  83. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x80 - 0x8f */
  84. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x90 - 0x9f */
  85. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0xa0 - 0xaf */
  86. 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0xb0 - 0xbf */
  87. 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0xc0 - 0xcf */
  88. 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0xd0 - 0xdf */
  89. 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 0xe0 - 0xef */
  90. 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 7, 8, /* 0xf0 - 0xff */
  91. };
  92. /* This module G4 Decompression has been totally rewritten ...
  93. Earlier module handled images with LSB first only,
  94. and failing while handling images Compressed in Strips.
  95. The present implementation uses the same tables, and takes care of the
  96. above issues. Additionally, it has been designed in such a way as that
  97. these decompression can be used for G3 - 2D decompression also.
  98. */
  99. /* ========================================================================
  100. -------------------- _ilPutOnes(). --------------------
  101. Input : pointer to the current Image Destination line (*sByte)
  102. startPixel - from which position 1's are to be put
  103. no_of_ones - how many pixels are to be put with ones
  104. Does :
  105. Utility function to put 1's (no_of_ones) in the string, pointed by
  106. *sByte, from the position startPixel; Used to fill the Destination
  107. image while De-Compressing. Initially the Destination image is filled
  108. with Zeros 0's ; While De-Compressing, 1's are filled appropriately
  109. to construct the Image..
  110. ** used in G3 & G4 Decompression
  111. ======================================================================== */
  112. IL_PRIVATE void
  113. _ilPutOnes(
  114. char *sByte,
  115. int startPixel,
  116. int no_of_ones )
  117. {
  118. static const unsigned char masks[] =
  119. {
  120. 0, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff };
  121. /* fill 1's in the current Byte */
  122. sByte += startPixel>>3;
  123. if (startPixel &= 7) { /* align to byte boundary */
  124. if (no_of_ones < 8 - startPixel) {
  125. *sByte++ |= masks[no_of_ones] >> startPixel;
  126. return;
  127. }
  128. *sByte++ |= 0xff >> startPixel;
  129. no_of_ones -= 8 - startPixel;
  130. }
  131. /* fill 1's in the consecutive Full Bytes */
  132. memset(sByte,0xff,(no_of_ones >> 3));
  133. sByte += (no_of_ones >> 3 );
  134. no_of_ones = no_of_ones & 7 ;
  135. /* fill 1's in the last partial Byte */
  136. *sByte |= masks[no_of_ones];
  137. }
  138. /* ========================================================================
  139. -------------------- _ilGetAbsDiff(). --------------------
  140. Input : the pointer to the pointer to the strings (image Line)
  141. startPixel from which the diff. is to be found
  142. endPixel i.e upto which the diff can be checked.
  143. color of the current pixel (startPixel)
  144. nTimes - no. of times the counting is to be repeated i.e for
  145. how many changing elements, the operation is to be
  146. performed.
  147. Does :
  148. Calculates the count of pixels of the same color and returns the absolute
  149. position of the next changing element and Returns the Absolute Position
  150. of the element
  151. ** used for G4,G3-2d compression and de-comression
  152. ======================================================================== */
  153. static int
  154. _ilGetAbsDiff( unsigned char *sByte,
  155. int startPixel,
  156. int endPixel,
  157. int color,
  158. int nTimes)
  159. {
  160. unsigned char *bp;
  161. int ini_diff;
  162. int n, fin_diff;
  163. unsigned char *table ;
  164. bp = sByte;
  165. bp += startPixel>> 3; /* adjust byte offset */
  166. do {
  167. if ((startPixel == -1) ) {
  168. fin_diff = 1;
  169. bp = sByte;
  170. goto done;
  171. }
  172. else {
  173. table = (color ? oneruns : zeroruns );
  174. ini_diff = endPixel- startPixel;
  175. /* Find difference in the partial byte on the current Byte */
  176. if (ini_diff > 0 && (n = (startPixel & 7))) {
  177. fin_diff = table[(*bp << n) & 0xff];
  178. if (fin_diff > 8-n) /* Consecutive bits extend beyond the current byte */
  179. fin_diff = 8-n;
  180. /* return the initial differece, if the current byte happens
  181. to be the last byte of the Imageline and cosecutive bits
  182. extend beyound that. */
  183. if (fin_diff > ini_diff)
  184. fin_diff = ini_diff;
  185. if (n + fin_diff < 8 ) /* Consecutive bits does not go upto the edge, so return the diff */
  186. goto done;
  187. ini_diff -= fin_diff;
  188. bp++;
  189. } else
  190. fin_diff = 0;
  191. /* Count in the bytes, till opp. color is found
  192. i.e while the diff >= 8 */
  193. while (ini_diff >= 8) {
  194. n = table[*bp];
  195. fin_diff += n;
  196. ini_diff -= n;
  197. if (n < 8) /* end of run */
  198. goto done;
  199. bp++;
  200. }
  201. /* Find difference in the partial byte on RHS */
  202. if (ini_diff > 0) {
  203. n = table[*bp];
  204. fin_diff += (n > ini_diff ? ini_diff : n);
  205. }
  206. }
  207. done:
  208. startPixel += fin_diff;
  209. color = !color;
  210. } while (--nTimes > 0 );
  211. return(startPixel);
  212. }
  213. /* --------------- End of _ilGetAbsDiff() ---------------- */
  214. /* ========================================================================
  215. -------------------- _ilDeCompressG4Init -------------------
  216. Routine defined in ilDeCompG4 for initializing CCITT Group3
  217. compression when the pipe gets executed.
  218. ======================================================================== */
  219. static ilError _ilDecompG4Init(
  220. ilDecompG3G4PrivPtr pPriv,
  221. ilImageInfo *pSrcImage,
  222. ilImageInfo *pDstImage
  223. )
  224. {
  225. /* Allocate space for Reference line, needed for 2 dimensional coding */
  226. pPriv->gpRefLine = (ilPtr)IL_MALLOC(pPriv->nDstLineBytes );
  227. if (!pPriv->gpRefLine)
  228. return IL_ERROR_MALLOC;
  229. return IL_OK;
  230. }
  231. /* ========================================================================
  232. -------------------- _ilDeCompressG4Cleanup -------------------
  233. ======================================================================== */
  234. static ilError _ilDecompG4Cleanup(
  235. ilDecompG3G4PrivPtr pPriv,
  236. ilImageInfo *pSrcImage,
  237. ilImageInfo *pDstImage
  238. )
  239. {
  240. /* De-Allocate the space for Reference line */
  241. if (pPriv->gpRefLine)
  242. IL_FREE( (ilPtr)pPriv->gpRefLine);
  243. return IL_OK;
  244. }
  245. /* Macros used in _ilDecompG4Line() */
  246. /* Macros for Getting the Number of White Runs */
  247. #define G4_GET_WHITE_RUN(whiteRun) { \
  248. whiteRun = 0; \
  249. do { \
  250. if ( Is_Lsb_First ) \
  251. GET_VALUE_LSB(bits,ImageP, srcpos, G4M_WhiteRun) \
  252. else \
  253. GET_VALUE_MSB(bits,ImageP, srcpos, G4M_WhiteRun) \
  254. pDecodeTemp = pDecodeWhite+bits; \
  255. srcpos += pDecodeTemp->length; \
  256. whiteRun += pDecodeTemp->value; \
  257. } while (pDecodeTemp->type != G4K_CodetypeTerminator) ; \
  258. }
  259. /* Macros for Getting the Number of Black Runs */
  260. #define G4_GET_BLACK_RUN(blackRun) { \
  261. blackRun = 0; \
  262. do { \
  263. if ( Is_Lsb_First ) \
  264. GET_VALUE_LSB(bits,ImageP, srcpos, G4M_BlackRun) \
  265. else \
  266. GET_VALUE_MSB(bits,ImageP, srcpos, G4M_BlackRun) \
  267. pDecodeTemp = pDecodeBlack+bits; \
  268. srcpos += pDecodeTemp->length; \
  269. blackRun += pDecodeTemp->value; \
  270. } while (pDecodeTemp->type != G4K_CodetypeTerminator) ; \
  271. }
  272. /* ========================================================================
  273. -------------------- _ilDecompG4Line -------------------
  274. Input : pointer to the Private data record or decompG3G4
  275. pointer to the Reference line
  276. pointer to the Destination image
  277. Does : Reading the Source Image, De-Compresses One line for the destn.
  278. image by Two dimensional coding.
  279. ======================================================================== */
  280. ilError _ilDecompG4Line(
  281. ilDecompG3G4PrivPtr pPriv,
  282. ilPtr pRefLine,
  283. ilPtr dstImageP
  284. )
  285. {
  286. int a0,b1,b2; /* changing elements used while decomressing */
  287. short color; /* color of the pixel */
  288. int firstRun; /* no. of consecutive pixels for M(a0a1) in Horiz mode */
  289. int secondRun; /* no. of consecutive pixels for M(a1a2) in Horiz mode */
  290. long bits ;
  291. long width;
  292. ilBool Is_Lsb_First ;
  293. ilPtr ImageP;
  294. int srcpos;
  295. ilDecompG4HuffTablePtrConst pDecodeWhite = ilArFax1DDecodeWhite;
  296. ilDecompG4HuffTablePtrConst pDecodeTemp;
  297. ilDecompG4HuffTablePtrConst pDecodeBlack = ilArFax1DDecodeBlack;
  298. /* Deccompression Procedure ....
  299. From the compressed data from Source Image .. retrieve a long bit; use this as
  300. index to determine the 2d coded mode (Pass or Horiz or Vert(-3 to 3) );
  301. Depending upon the mode, calculate the changing elements b1,b2 and adjust a0;
  302. If 1's have to filled to the destination image, call _ilPutOnes(..);
  303. If Horiz. mode is identified, call macros G4_GET_WHITERUN(..) & G4_GETBLACKRUN(..)
  304. to estimate the first and second runs and fill 1's;
  305. This loop will have to repeated until the value of a0 reaches the ImageWidth.
  306. See ilcompressg4.c for more infn. on G4 compression .
  307. */
  308. width = pPriv->width;
  309. a0 = -1;
  310. color = pPriv->white;
  311. Is_Lsb_First = pPriv->Is_Lsb_First;
  312. srcpos = pPriv->srcpos;
  313. ImageP = pPriv->ImageP;
  314. do { /* till a complete Image line is DeCompressed */
  315. if ( Is_Lsb_First )
  316. GET_VALUE_LSB(bits,ImageP, srcpos, G4M_Codeword)
  317. else
  318. GET_VALUE_MSB(bits,ImageP, srcpos, G4M_Codeword)
  319. if (ilArFax2DDecodeTable[bits].type != G4K_CodetypeTerminator)
  320. return IL_ERROR_COMPRESSED_DATA ;
  321. srcpos += ilArFax2DDecodeTable[bits].length;
  322. switch (ilArFax2DDecodeTable[bits].value) {
  323. /* State mode is codeword, codeword type is TERMINATOR,
  324. codeword value is PASS */
  325. case G4K_CodevaluePass:
  326. b2 = _ilGetAbsDiff(pRefLine, a0, width, !color,3);
  327. if (color) {
  328. if (a0 < 0) a0 = 0;
  329. if ( (b2-a0) > 0 )
  330. _ilPutOnes((char *)dstImageP, a0, b2 - a0);
  331. }
  332. a0 = b2;
  333. break;
  334. /* State mode is Codeword, codeword type is TERMINATOR,
  335. codeword value is HORIZONTAL */
  336. case G4K_CodevalueHoriz:
  337. if (color == pPriv->white) {
  338. G4_GET_WHITE_RUN(firstRun) ;
  339. G4_GET_BLACK_RUN(secondRun);
  340. }
  341. else {
  342. G4_GET_BLACK_RUN(firstRun);
  343. G4_GET_WHITE_RUN(secondRun) ;
  344. }
  345. if (a0 < 0) a0 = 0;
  346. if (a0 + firstRun > width)
  347. firstRun = width - a0;
  348. if ( (color) && ( firstRun > 0 ) )
  349. _ilPutOnes((char *)dstImageP, a0, firstRun);
  350. a0 += firstRun;
  351. if (a0 + secondRun > width)
  352. secondRun = width - a0;
  353. if ( (!color) && ( secondRun > 0 ) )
  354. _ilPutOnes((char *)dstImageP, a0, secondRun);
  355. a0 += secondRun;
  356. break;
  357. /* State mode is codeword, codeword type is TERMINATOR,
  358. codeword value is VERTICAL */
  359. case G4K_CodevalueV0:
  360. case G4K_CodevalueVR1:
  361. case G4K_CodevalueVL1:
  362. case G4K_CodevalueVR2:
  363. case G4K_CodevalueVL2:
  364. case G4K_CodevalueVR3:
  365. case G4K_CodevalueVL3:
  366. b1 = _ilGetAbsDiff(pRefLine, a0, width, !color,2);
  367. b1 += ilArFax2DDecodeTable[bits].value;
  368. if (b1 > width)
  369. b1 = width;
  370. if (color) {
  371. if (a0 < 0) a0 = 0;
  372. if ( (b1-a0) > 0 )
  373. _ilPutOnes((char *)dstImageP, a0, b1 - a0);
  374. }
  375. color = !color;
  376. a0 = b1;
  377. break;
  378. default:
  379. /* found invalid codeword values, return error */
  380. return IL_ERROR_COMPRESSED_DATA ;
  381. }
  382. } while (a0 < width); /* End of Image line is reached */
  383. pPriv->srcpos = srcpos;
  384. return IL_OK ;
  385. }
  386. /* ========================================================================
  387. -------------------- ilDecompG4Execute -------------------
  388. Routine defined in ilDecompG4 for executing CCITT Group4
  389. decompression when the pipe gets executed.
  390. ======================================================================== */
  391. static ilError _ilDecompG4Execute(
  392. ilExecuteData *pData,
  393. unsigned long dstLine,
  394. unsigned long *pNLines
  395. )
  396. {
  397. /* ========================================================================
  398. ilDecompG4Execute() definitions
  399. ======================================================================== */
  400. ilImagePlaneInfo *pSrcPlane; /* Pointer to the Source Image Plane */
  401. ilImagePlaneInfo *pDstPlane; /* Pointer to the Source Image Plane */
  402. ilPtr pSrcLine; /* Pointer to the Source Image FirstLine */
  403. ilDecompG3G4PrivPtr pPriv; /* Pointer to private image data */
  404. ilPtr dstImageP; /* Pointer to the Destn. Image */
  405. ilPtr pRefLine; /* Pointer to the Reference line */
  406. ilError error; /* Returned error */
  407. int dstBytesPerRow; /* no.of byte per Row in the dest image */
  408. long nLines; /* no. of lines in the current strip */
  409. /* ========================================================================
  410. ilDecompG4Execute() set up for decompression algorithm code
  411. ======================================================================== */
  412. pPriv = (ilDecompG3G4PrivPtr) pData->pPrivate;
  413. if ( *pNLines <= 0 ) return IL_OK ;
  414. if ( pData->compressed.nBytesToRead <= 0 ) return IL_OK ;
  415. nLines = *pNLines;
  416. /* Exit if pointer to pPixels is NULL */
  417. pSrcPlane = &pData->pSrcImage->plane[0];
  418. if (!pSrcPlane->pPixels) return IL_ERROR_NULL_COMPRESSED_IMAGE;
  419. pSrcLine = pSrcPlane->pPixels + pData->compressed.srcOffset; /* image location pointer */
  420. pDstPlane = &pData->pDstImage->plane[0];
  421. /* The destination image line pointer gets updated at the beginning of each strip */
  422. dstImageP = (pDstPlane->pPixels + (dstLine * pDstPlane->nBytesPerRow));
  423. dstBytesPerRow = pDstPlane->nBytesPerRow ;
  424. /* ========================================================================
  425. Zero the output (dst) buffer. _ilPutOnes() writes only ones, and expects
  426. that the dst lines have already been zeroed.
  427. ======================================================================== */
  428. bzero ((char *)dstImageP, (pDstPlane->nBytesPerRow * *pNLines) );
  429. /* Allocate space for the Reference line and set to zero Or 1's */
  430. if (pPriv->white)
  431. memset(pPriv->gpRefLine,0xff,(pDstPlane->nBytesPerRow ));
  432. else
  433. memset(pPriv->gpRefLine,0x00,(pDstPlane->nBytesPerRow ));
  434. pRefLine = pPriv->gpRefLine;
  435. pPriv->srcpos = 0;
  436. pPriv->ImageP = pSrcLine;
  437. pPriv->Is_Lsb_First = ( ( pPriv->compFlags & IL_G4M_LSB_FIRST) ? 1 : 0 );
  438. /* this pPriv->maxSrcPos is set to the bits that could be read, to prevent the
  439. program from reading beyond the compressed bytes; this check is done by
  440. the macro Get_value_msb & lsb */
  441. pPriv->maxSrcPos = pData->compressed.nBytesToRead * 8 ;
  442. /* till the Destination Image is filled up , call the decompress from the
  443. source line by line.. If any error in reading the compressed data, i.e
  444. invalid Code words or invalid Modes are found will retrun the error
  445. IL_ERROR_COMPRESSED_DATA .
  446. After decompressing each line, the decompressed line is set as reference
  447. line for the next line to be decompressed.
  448. Destination image size and Pointer are suitably decremented & incremented.
  449. */
  450. while ( nLines-- > 0 )
  451. {
  452. if ((error = _ilDecompG4Line(pPriv,pRefLine,dstImageP)) )
  453. return error;
  454. pRefLine = dstImageP;
  455. dstImageP += dstBytesPerRow;
  456. }
  457. return IL_OK;
  458. }
  459. /* End ilDecompG4Execute() */
  460. /* ========================================================================
  461. -------------------- ilDecompG4() -------------------
  462. Entry point of code for CCITT Group4 decompression. This
  463. includes image descriptor parameter error checking and function calls
  464. for: strip handler initialization, adding the filter element to the
  465. pipe, pipe initialization and execution, decompression algorithm,
  466. along with cleanup and destruction of allocated memory.....
  467. ======================================================================== */
  468. IL_PRIVATE
  469. ilBool _ilDecompG4 (
  470. ilPipe pipe,
  471. ilPipeInfo *pinfo,
  472. ilImageDes *pimdes
  473. )
  474. {
  475. ilDstElementData dstdata;
  476. ilDecompG3G4PrivPtr pPriv;
  477. ilImageDes des;
  478. /* Validate that image is bitonal */
  479. if (pimdes->type != IL_BITONAL)
  480. return ilDeclarePipeInvalid (pipe, IL_ERROR_IMAGE_TYPE);
  481. /*
  482. Check for Group4, uncompressed, or any undefined bits on. These
  483. are not supported!
  484. */
  485. if (pimdes->compInfo.g4.flags & IL_G4M_UNCOMPRESSED )
  486. return ilDeclarePipeInvalid (pipe, IL_ERROR_NOT_IMPLEMENTED);
  487. /* dstdata describes strips being output to next pipe element */
  488. dstdata.producerObject = (ilObject) NULL;
  489. des = *pimdes;
  490. des.compression = IL_UNCOMPRESSED;
  491. des.compInfo.g4.flags = 0;
  492. dstdata.pDes = &des;
  493. dstdata.pFormat = IL_FORMAT_BIT;
  494. dstdata.width = pinfo->width;
  495. dstdata.height = pinfo->height;
  496. dstdata.pPalette = (unsigned short *)NULL;
  497. /* set output strip height */
  498. dstdata.stripHeight = pinfo->stripHeight;
  499. dstdata.constantStrip = pinfo->constantStrip;
  500. dstdata.pCompData = (ilPtr)NULL;
  501. pPriv = (ilDecompG3G4PrivPtr) ilAddPipeElement(pipe, IL_FILTER,
  502. sizeof(ilDecompG3G4PrivRec), 0,
  503. (ilSrcElementData *)NULL,
  504. &dstdata, _ilDecompG4Init,_ilDecompG4Cleanup,
  505. IL_NPF, _ilDecompG4Execute, NULL, 0);
  506. if (!pPriv) return FALSE; /* EXIT */
  507. /* save private data */
  508. pPriv->width = pinfo->width;
  509. pPriv->white = ( des.blackIsZero ? 1 : 0 );
  510. pPriv->compFlags = pimdes->compInfo.g4.flags;
  511. pPriv->nDstLineBytes = (pPriv->width + 7) / 8;
  512. return TRUE;
  513. }