ilcomplzw.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441
  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: ilcomplzw.c /main/3 1995/10/23 15:42:35 rswiston $ */
  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 "ilint.h"
  40. #include "ilpipelem.h"
  41. #include "ilcompress.h"
  42. #include "ilerrors.h"
  43. #define CLEAR_CODE 256 /* LZW codes */
  44. #define END_OF_INFORMATION 257
  45. #define MAX_NODES 0x1000 /* 4k */
  46. #define LZW_MAX_BUFFER_WRITE 8 /* max # of dst bytes written after buffer check */
  47. typedef struct {
  48. unsigned short value; /* byte value of node */
  49. short left; /* nodes less than this nodes value */
  50. short right; /* nodes greater than this nodes value */
  51. short next; /* next character node */
  52. } ilEnnodeRec, *ilEnnodePtr;
  53. typedef struct {
  54. ilEnnodePtr ennodes; /* ptr to encode table */
  55. ilPtr pString; /* ptr to byte string table */
  56. unsigned int nextNode; /* next node to be used */
  57. unsigned int bitCount; /* # of bits waiting to be output */
  58. /* compatibility problem with long or unsigned long data fields */
  59. CARD32 bits; /* bits waiting to be output */
  60. long nSrcLineBytes; /* used width of src in bytes */
  61. ilPtr pDst; /* ptr to spot for next byte in output buffer */
  62. ilPtr pDstBufferEnd; /* ptr _past_ last available spot in buffer */
  63. ilImageInfo *pDstImage; /* ptr to dst image structure */
  64. } ilCompLZWPrivRec, *ilCompLZWPrivPtr;
  65. /* ------------------------- ilCompLZWInit ------------------------------ */
  66. /* Allocate the string and encode node table memory.
  67. */
  68. static ilError ilCompLZWInit (
  69. ilCompLZWPrivPtr pPriv,
  70. ilImageInfo *pSrcImage,
  71. ilImageInfo *pDstImage
  72. )
  73. {
  74. pPriv->ennodes = (ilEnnodePtr)NULL;
  75. pPriv->pString = (ilPtr)IL_MALLOC (MAX_NODES);
  76. if (!pPriv->pString)
  77. return IL_ERROR_MALLOC;
  78. pPriv->ennodes = (ilEnnodePtr)IL_MALLOC (sizeof(ilEnnodeRec) * MAX_NODES);
  79. if (!pPriv->ennodes) {
  80. IL_FREE (pPriv->pString);
  81. pPriv->pString = (ilPtr)NULL;
  82. return IL_ERROR_MALLOC;
  83. }
  84. return IL_OK;
  85. }
  86. /* ------------------------- ilCompLZWCleanup ---------------------------- */
  87. /* Deallocate those things allocated in Init().
  88. */
  89. static ilError ilCompLZWCleanup (
  90. ilCompLZWPrivPtr pPriv,
  91. ilBool aborting
  92. )
  93. {
  94. if (pPriv->pString)
  95. IL_FREE (pPriv->pString);
  96. if (pPriv->ennodes)
  97. IL_FREE (pPriv->ennodes);
  98. return IL_OK;
  99. }
  100. /* ------------------------ ilLZWReallocBuffer ------------------------ */
  101. /* Reallocate the output (compressed) buffer and reset pPriv->pDst(BufferEnd).
  102. */
  103. static ilBool ilLZWReallocBuffer (
  104. ilCompLZWPrivPtr pPriv
  105. )
  106. {
  107. unsigned long offset;
  108. offset = pPriv->pDst - pPriv->pDstImage->plane[0].pPixels;
  109. if (!_ilReallocCompressedBuffer (pPriv->pDstImage, 0, offset + LZW_MAX_BUFFER_WRITE))
  110. return FALSE;
  111. pPriv->pDst = pPriv->pDstImage->plane[0].pPixels + offset;
  112. pPriv->pDstBufferEnd = pPriv->pDstImage->plane[0].pPixels +
  113. (pPriv->pDstImage->plane[0].bufferSize - LZW_MAX_BUFFER_WRITE);
  114. return TRUE;
  115. }
  116. /* ------------------- LZW Compression Utility Functions ------------------ */
  117. /* ------------------------ ilNewEnnode --------------------------------- */
  118. /* Initialize "node" in the given encoding table "ennode" to "value".
  119. */
  120. static void NewEnnode (
  121. ilEnnodePtr ennodes,
  122. unsigned int node,
  123. unsigned int value
  124. )
  125. {
  126. ennodes[node].value = value;
  127. ennodes[node].left = -1;
  128. ennodes[node].right = -1;
  129. ennodes[node].next = -1;
  130. }
  131. /* ------------------------- ilInitEncodeTable -------------------------- */
  132. /* Allocate the encode table the first time called.
  133. Initializes the encode table with the first 256 strings (i.e. 0-ff).
  134. */
  135. static void ilInitEncodeTable (
  136. ilCompLZWPrivPtr pPriv
  137. )
  138. {
  139. int i;
  140. for (i = 0; i < 256; i++) {
  141. pPriv->ennodes[i].value = i;
  142. pPriv->ennodes[i].left = -1;
  143. pPriv->ennodes[i].right = -1;
  144. pPriv->ennodes[i].next = -1;
  145. }
  146. pPriv->nextNode = 256;
  147. for (i = 256; i < MAX_NODES; i++) {
  148. pPriv->ennodes[i].value = 0;
  149. pPriv->ennodes[i].left = -1;
  150. pPriv->ennodes[i].right = -1;
  151. pPriv->ennodes[i].next = -1;
  152. }
  153. }
  154. /* ------------------------- ilStringInTable -------------------------- */
  155. /* Operation:
  156. If this is the first character in the string the current node is set
  157. to the top level of the tree. Otherwise we will transition to the next
  158. level in the tree and search for an occurrence of the character there.
  159. if one is found we return with TRUE. If not the new node will be
  160. added to the tree and FALSE will be returned.
  161. Return:
  162. result TRUE if string was already in table.
  163. FALSE if string had to be added to table.
  164. */
  165. static ilBool ilStringInTable (
  166. ilCompLZWPrivPtr pPriv,
  167. ilPtr string,
  168. unsigned int count,
  169. unsigned int *pCurrentNode
  170. )
  171. {
  172. unsigned int byte; /* current character in string */
  173. ilEnnodePtr ennodes;
  174. ennodes = pPriv->ennodes;
  175. byte = string[count-1];
  176. if (count == 1) { /* single character string, always first 256 entries in table */
  177. *pCurrentNode = byte;
  178. return TRUE;
  179. }
  180. else {
  181. if (ennodes[*pCurrentNode].next == -1) { /* if no next char entry */
  182. ennodes[*pCurrentNode].next = pPriv->nextNode;
  183. *pCurrentNode = pPriv->nextNode;
  184. NewEnnode (ennodes, *pCurrentNode, byte); /* pPriv->nextNode is always>255 */
  185. pPriv->nextNode++;
  186. return FALSE;
  187. }
  188. else {
  189. *pCurrentNode = ennodes[*pCurrentNode].next;
  190. while (TRUE) {
  191. if (byte == ennodes[*pCurrentNode].value)
  192. return TRUE;
  193. else if (byte < ennodes[*pCurrentNode].value) {
  194. if (ennodes[*pCurrentNode].left != -1)
  195. *pCurrentNode = ennodes[*pCurrentNode].left;
  196. else { /* create new left node */
  197. ennodes[*pCurrentNode].left = pPriv->nextNode;
  198. *pCurrentNode = pPriv->nextNode;
  199. NewEnnode (ennodes, *pCurrentNode, byte);
  200. pPriv->nextNode++;
  201. return FALSE;
  202. }
  203. }
  204. else { /* byte must be greater than the current value */
  205. if (ennodes[*pCurrentNode].right != -1)
  206. *pCurrentNode = ennodes[*pCurrentNode].right;
  207. else { /* create new right node */
  208. ennodes[*pCurrentNode].right = pPriv->nextNode;
  209. *pCurrentNode = pPriv->nextNode;
  210. NewEnnode (ennodes, *pCurrentNode, byte);
  211. pPriv->nextNode++;
  212. return FALSE;
  213. }
  214. }
  215. }
  216. }
  217. }
  218. }
  219. /* ----------------------- ilWriteCode ---------------------------------- */
  220. /* Adds "code" to the output stream, outputting bytes as necessary.
  221. If the bit stream is longer than 16 bits, two bytes will be written.
  222. */
  223. static ilError ilWriteCode (
  224. ilCompLZWPrivPtr pPriv,
  225. unsigned int code
  226. )
  227. {
  228. CARD32 newBits, nBits;
  229. if (pPriv->nextNode <= (512-2)) nBits = 9;
  230. else if (pPriv->nextNode <= (1024-2)) nBits = 10;
  231. else if (pPriv->nextNode <= (2048-2)) nBits = 11;
  232. else nBits = 12;
  233. newBits = (CARD32)code << (16 - nBits);
  234. pPriv->bits |= newBits << (16 - pPriv->bitCount);
  235. pPriv->bitCount += nBits;
  236. if (pPriv->bitCount > 16) {
  237. /* Output 2 bytes; check for room in buffer; realloc if not room.
  238. */
  239. if (pPriv->pDst >= pPriv->pDstBufferEnd)
  240. if (!ilLZWReallocBuffer (pPriv))
  241. return IL_ERROR_MALLOC;
  242. *pPriv->pDst++ = (pPriv->bits >> 24) & 0xff;
  243. *pPriv->pDst++ = (pPriv->bits >> 16) & 0xff;
  244. pPriv->bits <<= 16;
  245. pPriv->bitCount -= 16;
  246. }
  247. return IL_OK;
  248. }
  249. /* ------------------------- ilCompLZWExecute ---------------------------- */
  250. /* Compress one strip of LZW compressed data.
  251. */
  252. static ilError ilCompLZWExecute (
  253. ilExecuteData *pData,
  254. unsigned long dstLine,
  255. unsigned long *pNLines
  256. )
  257. {
  258. ilCompLZWPrivPtr pPriv;
  259. ilPtr pSrcLine, pSrc;
  260. ilByte srcByte;
  261. long nLines, srcRowBytes, nSrcBytes;
  262. ilImagePlaneInfo *pPlane;
  263. ilError error;
  264. ilPtr string;
  265. unsigned int currentNode, stringCount, codeIndex, lastNode;
  266. pPriv = (ilCompLZWPrivPtr)pData->pPrivate;
  267. nLines = *pNLines;
  268. if (nLines <= 0)
  269. return IL_OK;
  270. pPlane = &pData->pSrcImage->plane[0];
  271. srcRowBytes = pPlane->nBytesPerRow;
  272. pSrcLine = pPlane->pPixels + pData->srcLine * srcRowBytes;
  273. /* Make sure dst compressed bufferSize is min # writes in size.
  274. Set pDst to beginning of dst buffer + dst offset (= 0 unless writing
  275. to an image, in which case = byte past where last strip was written).
  276. Set pDstBufferEnd to begin of buffer + bufferSize - max # bytes written,
  277. so that pDst <= pDstBufferEnd can check for room for writing max # bytes.
  278. */
  279. pPriv->pDstImage = pData->pDstImage;
  280. if (pPriv->pDstImage->plane[0].bufferSize < LZW_MAX_BUFFER_WRITE)
  281. if (!_ilReallocCompressedBuffer (pPriv->pDstImage, 0, LZW_MAX_BUFFER_WRITE))
  282. return IL_ERROR_MALLOC;
  283. pPriv->pDst = pPriv->pDstImage->plane[0].pPixels + *pData->compressed.pDstOffset;
  284. pPriv->pDstBufferEnd = pPriv->pDstImage->plane[0].pPixels +
  285. (pPriv->pDstImage->plane[0].bufferSize - LZW_MAX_BUFFER_WRITE);
  286. string = pPriv->pString;
  287. ilInitEncodeTable (pPriv);
  288. pPriv->bits = 0;
  289. pPriv->bitCount = 0;
  290. if (error = ilWriteCode (pPriv, CLEAR_CODE))
  291. return error;
  292. stringCount = 0;
  293. while (nLines-- > 0) {
  294. pSrc = pSrcLine;
  295. pSrcLine += srcRowBytes;
  296. nSrcBytes = pPriv->nSrcLineBytes;
  297. while (nSrcBytes-- > 0) {
  298. srcByte = *pSrc++;
  299. string[stringCount++] = srcByte;
  300. lastNode = currentNode;
  301. if (!ilStringInTable (pPriv, string, stringCount, &currentNode)) {
  302. codeIndex = (lastNode < 256) ? lastNode : lastNode + 2;
  303. if (error = ilWriteCode (pPriv, codeIndex))
  304. return error;
  305. string[0] = srcByte;
  306. currentNode = srcByte;
  307. stringCount = 1;
  308. }
  309. if (pPriv->nextNode > (MAX_NODES-3)) {
  310. codeIndex = (currentNode < 256) ? currentNode : currentNode + 2;
  311. if ( (error = ilWriteCode (pPriv, codeIndex)) ||
  312. (error = ilWriteCode (pPriv, CLEAR_CODE)) )
  313. return error;
  314. ilInitEncodeTable (pPriv);
  315. stringCount = 0;
  316. currentNode = 0;
  317. lastNode = 0;
  318. }
  319. }
  320. }
  321. /* terminate output buffer */
  322. if (stringCount != 0) {
  323. codeIndex = (currentNode < 256) ? currentNode : currentNode + 2;
  324. if (error = ilWriteCode (pPriv, codeIndex))
  325. return error;
  326. }
  327. if (error = ilWriteCode (pPriv, END_OF_INFORMATION))
  328. return error;
  329. /* Check for room for bytes; write out any remaining bits.
  330. */
  331. if (pPriv->pDst >= pPriv->pDstBufferEnd)
  332. if (!ilLZWReallocBuffer (pPriv))
  333. return IL_ERROR_MALLOC;
  334. if (pPriv->bitCount > 0)
  335. *pPriv->pDst++ = (pPriv->bits >> 24) & 0xff;
  336. if (pPriv->bitCount > 8)
  337. *pPriv->pDst++ = (pPriv->bits >> 16) & 0xff;
  338. /* Pass the number of bytes written (ptr to next byte - start) to next filter.
  339. */
  340. *pData->compressed.pNBytesWritten = pPriv->pDst -
  341. (pPriv->pDstImage->plane[0].pPixels + *pData->compressed.pDstOffset);
  342. return IL_OK;
  343. }
  344. /* ------------------------- ilCompressLZW ---------------------------------- */
  345. /* Called by ilCompress() in /ilc/ilcodec.c .
  346. Compresses each strip coming down the pipe using LZW compression.
  347. */
  348. IL_PRIVATE ilBool _ilCompressLZW (
  349. ilPipe pipe,
  350. ilPipeInfo *pInfo,
  351. ilImageDes *pDes,
  352. ilImageFormat *pFormat,
  353. ilSrcElementData *pSrcData
  354. )
  355. {
  356. long bytesPerRow [IL_MAX_SAMPLES];
  357. ilImageDes des;
  358. ilImageFormat format;
  359. ilDstElementData dstData;
  360. ilCompLZWPrivPtr pPriv;
  361. /* Only pixel order supported - if planar order, try to convert to pixel order.
  362. */
  363. des = *pDes;
  364. format = *pFormat;
  365. if ((pDes->nSamplesPerPixel > 1) && (pFormat->sampleOrder != IL_SAMPLE_PIXELS)) {
  366. format.sampleOrder = IL_SAMPLE_PIXELS;
  367. if (!ilConvert (pipe, (ilImageDes *)NULL, &format, 0, (ilPtr)NULL))
  368. return FALSE;
  369. ilGetPipeInfo (pipe, FALSE, pInfo, &des, &format);
  370. }
  371. /* Add pipe element: no change to des except now compressed; same format.
  372. NOTE: pSrcData->constantStrip should be TRUE, from ilCompress().
  373. */
  374. dstData.producerObject = (ilObject)NULL;
  375. des.compression = IL_LZW;
  376. dstData.pDes = &des;
  377. dstData.pFormat = (ilImageFormat *)NULL;
  378. dstData.width = pInfo->width;
  379. dstData.height = pInfo->height;
  380. dstData.stripHeight = pSrcData->stripHeight;
  381. dstData.constantStrip = pSrcData->constantStrip;
  382. dstData.pPalette = pInfo->pPalette;
  383. dstData.pCompData = (ilPtr)NULL;
  384. pPriv = (ilCompLZWPrivPtr)ilAddPipeElement (pipe, IL_FILTER, sizeof (ilCompLZWPrivRec),
  385. 0, pSrcData, &dstData,
  386. ilCompLZWInit, ilCompLZWCleanup, IL_NPF, ilCompLZWExecute, 0);
  387. if (!pPriv)
  388. return FALSE;
  389. /* Store info in *pPriv. For nSrcLineBytes, need minimum # of bytes uncompressed
  390. dst data would take - get bytes/row using rowBitAlign of 8 (packed).
  391. */
  392. format.rowBitAlign = 8;
  393. ilGetBytesPerRow (pDes, &format, pInfo->width, bytesPerRow);
  394. pPriv->nSrcLineBytes = bytesPerRow[0];
  395. return TRUE;
  396. }