ildecomppackbits.c 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  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: ildecomppackbits.c /main/5 1996/06/19 12:23:29 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 "ilint.h"
  40. #include "ilpipelem.h"
  41. #include "ildecomp.h"
  42. #include "ilerrors.h"
  43. /* ========================================================================
  44. Decompression private data structure definition
  45. ======================================================================== */
  46. typedef struct {
  47. long height;
  48. long width;
  49. long nDstLineBytes;
  50. } ilDecompPBPrivRec, *ilDecompPBPrivPtr;
  51. /* =============================================================================================================================
  52. -------------------- ilDecompPackbitsExecute() -------------------
  53. Routine defined in ilDecompPackbits for executing Packbits
  54. decompression when the pipe gets executed.
  55. ============================================================================================================================= */
  56. static ilError ilDecompPackbitsExecute(
  57. ilExecuteData *pData,
  58. unsigned long dstLine,
  59. unsigned long *pNLines
  60. )
  61. {
  62. unsigned long dstNBytes; /* Number of destination image bytes per row */
  63. long nLines; /* Number of lines per source image strip */
  64. register long nBytesToGo; /* Number of source image bytes left to unpack for current strip */
  65. register long nDstLineBytesToGo; /* Number of bytes left to write to this line of destination */
  66. register ilPtr pSrcByte; /* Pointer to source image data */
  67. register ilPtr pDstByte; /* Pointer to destination image data first byte */
  68. ilPtr pSrcLine; /* Pointer to source image data first byte of each scanline */
  69. ilPtr pDstLine; /* Pointer to destination image data first byte of each scanline */
  70. ilDecompPBPrivPtr pPriv; /* Pointer to private image data */
  71. ilImagePlaneInfo *pPlane;
  72. register int count; /* run-length code value */
  73. register ilByte repeatbyte; /* repeated data */
  74. /* ========================================================================
  75. ilDecompPackbitsExecute() set up for decompression algorithm code
  76. ======================================================================== */
  77. pPriv = (ilDecompPBPrivPtr) pData->pPrivate;
  78. nLines = *pNLines;
  79. if (nLines <= 0) return IL_OK;
  80. nBytesToGo = pData->compressed.nBytesToRead;
  81. if (nBytesToGo <= 0) return IL_OK;
  82. pPlane = &pData->pSrcImage->plane[0];
  83. if (!pPlane->pPixels) return IL_ERROR_NULL_COMPRESSED_IMAGE;
  84. pSrcLine = pPlane->pPixels + pData->compressed.srcOffset;
  85. pPlane = &pData->pDstImage->plane[0];
  86. if (!pPlane->pPixels) return IL_ERROR_NULL_COMPRESSED_IMAGE;
  87. dstNBytes = pPlane->nBytesPerRow;
  88. pDstLine = pPlane->pPixels + dstLine * dstNBytes;
  89. pSrcByte = pSrcLine;
  90. /* decode each line of compressed data into the destination image */
  91. while (nLines-- > 0) {
  92. pDstByte = pDstLine;
  93. nDstLineBytesToGo = pPriv->nDstLineBytes;
  94. while (nDstLineBytesToGo > 0) {
  95. if (--nBytesToGo < 0)
  96. return IL_ERROR_COMPRESSED_DATA;
  97. count = (signed char)*pSrcByte++;
  98. if (count >= 0) {
  99. count++;
  100. nDstLineBytesToGo -= count;
  101. nBytesToGo -= count;
  102. if ((nDstLineBytesToGo < 0) || (nBytesToGo < 0))
  103. return IL_ERROR_COMPRESSED_DATA;
  104. count--;
  105. do {
  106. *pDstByte++ = *pSrcByte++;
  107. } while (--count >= 0);
  108. }
  109. else if (count != 128) { /* 128 is a noop for Packbits */
  110. count = -count; /* count is now -1 of real count */
  111. nDstLineBytesToGo -= (count + 1);
  112. nBytesToGo--;
  113. if ((nDstLineBytesToGo < 0) || (nBytesToGo < 0))
  114. return IL_ERROR_COMPRESSED_DATA;
  115. repeatbyte = *pSrcByte++;
  116. do {
  117. *pDstByte++ = repeatbyte;
  118. } while (--count >= 0);
  119. }
  120. } /* end row */
  121. pDstLine += dstNBytes;
  122. } /* end strip */
  123. return IL_OK;
  124. }
  125. /* =============================================================================================================================
  126. -------------------- ilDecompPackbits() --------------------
  127. Main body of code for Packbits decompression. This includes image descriptor parameter error checking
  128. and function calls for: strip handler initialization, adding the filter element to the pipe, pipe initialization
  129. and execution, decompression algorithm.....
  130. ============================================================================================================================= */
  131. IL_PRIVATE ilBool _ilDecompPackbits (
  132. ilPipe pipe,
  133. ilPipeInfo *pinfo,
  134. ilImageDes *pimdes,
  135. ilImageFormat *pimformat
  136. )
  137. {
  138. ilDstElementData dstdata;
  139. ilDecompPBPrivPtr pPriv;
  140. ilImageDes des;
  141. ilBool bitPerPixel;
  142. /* If image has more than one sample/pixel or is not bit or byte/pixel, error */
  143. bitPerPixel = (pimformat->nBitsPerSample[0] == 1);
  144. if ((pimdes->nSamplesPerPixel != 1)
  145. || (!bitPerPixel && (pimformat->nBitsPerSample[0] != 8)))
  146. return ilDeclarePipeInvalid (pipe, IL_ERROR_IMAGE_TYPE);
  147. dstdata.producerObject = (ilObject) NULL;
  148. des = *pimdes;
  149. des.compression = IL_UNCOMPRESSED;
  150. dstdata.pDes = &des;
  151. dstdata.width = pinfo->width;
  152. dstdata.height = pinfo->height;
  153. dstdata.pPalette = pinfo->pPalette;
  154. dstdata.pCompData = (ilPtr)NULL;
  155. dstdata.stripHeight = pinfo->stripHeight;
  156. dstdata.constantStrip = pinfo->constantStrip;
  157. dstdata.pFormat = (bitPerPixel) ? IL_FORMAT_BIT : IL_FORMAT_BYTE;
  158. pPriv = (ilDecompPBPrivPtr) ilAddPipeElement(pipe, IL_FILTER, sizeof(ilDecompPBPrivRec), 0,
  159. (ilSrcElementData *)NULL, &dstdata,
  160. IL_NPF, IL_NPF, IL_NPF, ilDecompPackbitsExecute, NULL, 0);
  161. if (!pPriv)
  162. return FALSE;
  163. pPriv->height = pinfo->height;
  164. pPriv->width = pinfo->width;
  165. pPriv->nDstLineBytes = (bitPerPixel) ? (pPriv->width + 7) / 8 : pPriv->width;
  166. return TRUE;
  167. }