ildecompjpeg.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  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: ildecompjpeg.c /main/5 1996/06/19 12:23:41 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 "ilerrors.h"
  42. #include "ildecomp.h"
  43. #include "iljpgdecode.h"
  44. #include "ilutiljpeg.h"
  45. /* Private data when decompressing JPEG data */
  46. typedef struct {
  47. iljpgDataRec jpgData; /* data for iljpg?() functions */
  48. ilBool firstStrip; /* set true by Init(): this is first strip */
  49. long nLinesWritten; /* inited to 0 by Init() */
  50. long stripHeight; /* height of strips being written */
  51. iljpgPtr pJPEGPriv; /* iljpg private data */
  52. iljpgDataPtr pJPEGData; /* JIF only: ptr to JPEG data */
  53. ilJPEGDecodeStream streamRec; /* JIF only: src decoding stream */
  54. } ilJPEGPrivRec, *ilJPEGPrivPtr;
  55. /* -------------------- ilDecompInit -------------------------- */
  56. /* Init() function for decompressing JPEG.
  57. */
  58. static ilError ilDecompInit (
  59. ilJPEGPrivPtr pPriv,
  60. ilImageInfo *pSrcImage,
  61. ilImageInfo *pDstImage
  62. )
  63. {
  64. pPriv->firstStrip = TRUE;
  65. pPriv->nLinesWritten = 0;
  66. pPriv->pJPEGData = (iljpgDataPtr)NULL;
  67. pPriv->pJPEGPriv = (iljpgPtr)NULL;
  68. return IL_OK;
  69. }
  70. /* -------------------- ilDecompCleanup -------------------------- */
  71. /* Cleanup() function for decompressing JPEG.
  72. */
  73. static ilError ilDecompCleanup (
  74. ilJPEGPrivPtr pPriv,
  75. ilBool aborting
  76. )
  77. {
  78. ilError error;
  79. /* Cleanup from JPEG decode, but only if firstStrip setup done */
  80. if (!pPriv->firstStrip) {
  81. if (pPriv->pJPEGPriv)
  82. if ((error = iljpgDecodeCleanup (pPriv->pJPEGPriv)))
  83. return error;
  84. if (pPriv->pJPEGData)
  85. return iljpgFreeData (pPriv->pJPEGData);
  86. }
  87. return IL_OK;
  88. }
  89. /* -------------------- ilDecompRawExecute -------------------------- */
  90. /* Execute() function for decompressing "raw" (non-JIF) JPEG: handle strips.
  91. */
  92. static ilError ilDecompRawExecute (
  93. ilExecuteData *pData,
  94. unsigned long dstLine,
  95. unsigned long *pNLines
  96. )
  97. {
  98. register ilJPEGPrivPtr pPriv;
  99. ilJPEGDecodeStream streamRec;
  100. ilError error;
  101. iljpgPtr pPixels[ILJPG_MAX_COMPS];
  102. long nBytesPerRow[ILJPG_MAX_COMPS];
  103. int i;
  104. ilImagePlaneInfo *pPlane;
  105. register ilImageInfo *pSrcImage, *pDstImage;
  106. pPriv = (ilJPEGPrivPtr)pData->pPrivate;
  107. pSrcImage = pData->pSrcImage;
  108. pDstImage = pData->pDstImage;
  109. /* If first strip, setup iljpg data and call iljpg Init() function */
  110. if (pPriv->firstStrip) {
  111. _ilJPEGTablesIn ((ilJPEGData *)pSrcImage->pCompData, &pPriv->jpgData);
  112. if ((error = iljpgDecodeInit (&pPriv->jpgData, &pPriv->pJPEGPriv)))
  113. return error;
  114. pPriv->firstStrip = FALSE;
  115. }
  116. /* Decode one strip into dst pixels */
  117. streamRec.pData = pSrcImage->plane[0].pPixels + pData->compressed.srcOffset;
  118. streamRec.nBytesLeft = pData->compressed.nBytesToRead;
  119. for (i = 0, pPlane = pData->pDstImage->plane;
  120. i < pData->pDstImage->pDes->nSamplesPerPixel; i++, pPlane++) {
  121. pPixels[i] = pPlane->pPixels +
  122. (dstLine * pPriv->jpgData.comp[i].vertFactor / pPriv->jpgData.maxVertFactor) *
  123. pPlane->nBytesPerRow;
  124. nBytesPerRow[i] = pPlane->nBytesPerRow;
  125. }
  126. return iljpgDecodeExecute (pPriv->pJPEGPriv, &streamRec, TRUE, *pNLines,
  127. pPixels, nBytesPerRow);
  128. }
  129. /* -------------------- ilDecompJIFExecute -------------------------- */
  130. /* Execute() function for decompressing JIF: a single strip.
  131. */
  132. static ilError ilDecompJIFExecute (
  133. ilExecuteData *pData,
  134. unsigned long dstLine,
  135. unsigned long *pNLines
  136. )
  137. {
  138. register ilJPEGPrivPtr pPriv;
  139. ilError error;
  140. int i;
  141. iljpgPtr pPixels[ILJPG_MAX_COMPS];
  142. long nBytesPerRow[ILJPG_MAX_COMPS];
  143. ilImagePlaneInfo *pPlane;
  144. ilBool firstStrip;
  145. pPriv = (ilJPEGPrivPtr)pData->pPrivate;
  146. /* If firstStrip decode header, determine # of strips and init for decode */
  147. firstStrip = pPriv->firstStrip;
  148. pPriv->firstStrip = FALSE;
  149. if (firstStrip) {
  150. pPriv->streamRec.pData = pData->pSrcImage->plane[0].pPixels;
  151. pPriv->streamRec.nBytesLeft = pData->compressed.nBytesToRead;
  152. if ((error = iljpgDecodeJIF (&pPriv->streamRec, &pPriv->pJPEGData)))
  153. return error;
  154. if ((error = iljpgDecodeInit (pPriv->pJPEGData, &pPriv->pJPEGPriv)))
  155. return error;
  156. }
  157. /* Decode one strip into dst pixels, or remaining lines if last strip */
  158. for (i = 0, pPlane = pData->pDstImage->plane;
  159. i < pData->pDstImage->pDes->nSamplesPerPixel; i++, pPlane++) {
  160. pPixels[i] = pPlane->pPixels +
  161. (dstLine * pPriv->jpgData.comp[i].vertFactor / pPriv->jpgData.maxVertFactor) *
  162. pPlane->nBytesPerRow;
  163. nBytesPerRow[i] = pPlane->nBytesPerRow;
  164. }
  165. if ((pPriv->nLinesWritten + pPriv->stripHeight) > pPriv->jpgData.height)
  166. *pNLines = pPriv->jpgData.height - pPriv->nLinesWritten;
  167. else *pNLines = pPriv->stripHeight;
  168. if ((error = iljpgDecodeExecute (pPriv->pJPEGPriv, &pPriv->streamRec, FALSE, *pNLines,
  169. pPixels, nBytesPerRow)))
  170. return error;
  171. /* Handle based on whether firstStrip and/or last strip:
  172. first? last?
  173. YES YES normal return; image is one strip, no call backs needed.
  174. YES NO return "call back" error code: want this filter to
  175. be called again until another return cancels it
  176. NO YES cancel call back; don't want to be called again
  177. NO NO normal return; more strips to decompress
  178. */
  179. pPriv->nLinesWritten += pPriv->stripHeight;
  180. if (firstStrip)
  181. if (pPriv->nLinesWritten >= pPriv->jpgData.height) /* last strip */
  182. return IL_OK;
  183. else return IL_ERROR_ELEMENT_AGAIN;
  184. else
  185. if (pPriv->nLinesWritten >= pPriv->jpgData.height)
  186. return IL_ERROR_ELEMENT_COMPLETE;
  187. else return IL_OK;
  188. }
  189. /* -------------------- _ilDecompJPEG -------------------------- */
  190. /* Called by ilDecompress() when pipe image is JPEG compressed. Add a filter to
  191. decompress the pipe image.
  192. */
  193. ilBool _ilDecompJPEG (
  194. ilPipe pipe,
  195. ilPipeInfo *pInfo,
  196. ilImageDes *pDes
  197. )
  198. {
  199. ilDstElementData dstData;
  200. ilImageDes des;
  201. ilImageFormat format;
  202. ilJPEGPrivPtr pPriv;
  203. iljpgDataRec jpgData;
  204. /* Define decompressed output from this filter: planar format unless
  205. a single component image (e.g. gray).
  206. */
  207. dstData.producerObject = (ilObject)NULL;
  208. des = *pDes;
  209. des.compression = IL_UNCOMPRESSED;
  210. dstData.pDes = &des;
  211. if (pDes->nSamplesPerPixel == 1)
  212. dstData.pFormat = IL_FORMAT_BYTE;
  213. else {
  214. IL_INIT_IMAGE_FORMAT (&format);
  215. format.sampleOrder = IL_SAMPLE_PLANES;
  216. format.byteOrder = IL_MSB_FIRST;
  217. format.rowBitAlign = 8;
  218. format.nBitsPerSample[0] =
  219. format.nBitsPerSample[1] =
  220. format.nBitsPerSample[2] = 8;
  221. dstData.pFormat = &format;
  222. }
  223. dstData.width = pInfo->width;
  224. dstData.height = pInfo->height;
  225. dstData.pPalette = (unsigned short *)NULL;
  226. dstData.pCompData = (ilPtr)NULL;
  227. /* Init iljpg package data */
  228. _ilJPEGDataIn (&des, pInfo->width, pInfo->height, &jpgData);
  229. /* If "raw" JPEG, decode in strips, the size of those presented to this filter */
  230. if (pDes->compInfo.JPEG.reserved & IL_JPEGM_RAW) {
  231. dstData.stripHeight = pInfo->stripHeight; /* decode strips as they come in */
  232. dstData.constantStrip = pInfo->constantStrip;
  233. pPriv = (ilJPEGPrivPtr)ilAddPipeElement(pipe, IL_FILTER,
  234. sizeof(ilJPEGPrivRec), 0, (ilSrcElementData *)NULL, &dstData,
  235. ilDecompInit, ilDecompCleanup, IL_NPF, ilDecompRawExecute, NULL, 0);
  236. }
  237. else {
  238. /* JIF: a single data stream (strip) with tables in the stream: decompress
  239. in IL's default strip size for this image, made a multiple of MCUs.
  240. */
  241. long stripHeight, mcuHeight;
  242. stripHeight = ilRecommendedStripHeight (dstData.pDes, dstData.pFormat,
  243. dstData.width, dstData.height);
  244. mcuHeight = 8 * jpgData.maxVertFactor;
  245. if (mcuHeight == 0)
  246. mcuHeight = 32; /* ? error, default to max possible */
  247. stripHeight = ((stripHeight + mcuHeight - 1) / mcuHeight) * mcuHeight;
  248. if (stripHeight > dstData.height)
  249. stripHeight = dstData.height;
  250. dstData.stripHeight = stripHeight;
  251. dstData.constantStrip = TRUE;
  252. pPriv = (ilJPEGPrivPtr)ilAddPipeElement(pipe, IL_FILTER,
  253. sizeof(ilJPEGPrivRec), 0, (ilSrcElementData *)NULL, &dstData,
  254. ilDecompInit, ilDecompCleanup, IL_NPF, ilDecompJIFExecute, NULL, 0);
  255. }
  256. /* Fill in data into private; copy jpgData */
  257. if (!pPriv)
  258. return FALSE;
  259. pPriv->jpgData = jpgData;
  260. pPriv->stripHeight = dstData.stripHeight;
  261. return TRUE;
  262. }