iljpgdecode.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  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: iljpgdecode.c /main/3 1995/10/23 15:54:14 rswiston $ */
  24. /**---------------------------------------------------------------------
  25. ***
  26. *** (c)Copyright 1992 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 <stdlib.h>
  40. #include "iljpgdecodeint.h"
  41. /* -------------------- iljpgDecodeInit -------------------------- */
  42. /* Init for JPEG decoding and return ptr to private block.
  43. */
  44. ILJPG_PUBLIC_EXTERN
  45. iljpgError iljpgDecodeInit (
  46. iljpgDataPtr pData,
  47. iljpgPtr *pPrivate /* RETURNED */
  48. )
  49. {
  50. iljpgDecodePrivPtr pPriv;
  51. iljpgCompPtr pComp;
  52. int comp;
  53. iljpgCompDataPtr pCompData;
  54. iljpgError error;
  55. /* Validate *pData: valid hori/vertFactor, tables present, etc. */
  56. if (!_iljpgValidPars (pData))
  57. return ILJPG_ERROR_DECODE_PARS;
  58. /* Allocate and return private block */
  59. pPriv = (iljpgDecodePrivPtr)ILJPG_MALLOC_ZERO (sizeof (iljpgDecodePrivRec));
  60. if (!pPriv)
  61. return ILJPG_ERROR_DECODE_MALLOC;
  62. pPriv->pData = pData;
  63. *pPrivate = (iljpgPtr)pPriv;
  64. pPriv->mcuRestartCount = 0;
  65. /* Init Huffman and DCT decoders */
  66. if ((error = _iljpgDehuffInit (pPriv))
  67. || (error = _iljpgDeDCTInit (pPriv))) {
  68. ILJPG_FREE (pPriv);
  69. return error;
  70. }
  71. /* Setup static part of per-comp data; copy from other places */
  72. for (comp = 0, pCompData = pData->comp, pComp = pPriv->compData;
  73. comp < pData->nComps; comp++, pCompData++, pComp++) {
  74. pComp->pRevScale = pPriv->DCTRevScaleTables[pCompData->QTableIndex];
  75. pComp->horiFactor = pCompData->horiFactor;
  76. pComp->vertFactor = pCompData->vertFactor;
  77. pComp->width = pData->width * pCompData->horiFactor / pData->maxHoriFactor;
  78. pComp->mcuXInc = 8 * pCompData->horiFactor;
  79. pComp->mcuYInc = 8 * pCompData->vertFactor;
  80. }
  81. return 0;
  82. }
  83. /* -------------------- iljpgDecodeCleanup -------------------------- */
  84. /* Cleanup after JPEG decoding.
  85. */
  86. ILJPG_PUBLIC_EXTERN
  87. iljpgError iljpgDecodeCleanup (
  88. iljpgPtr pPrivate
  89. )
  90. {
  91. iljpgError error1, error2;
  92. /* Call the Huffman and DCT cleanup functions.
  93. */
  94. error1 = _iljpgDehuffCleanup ((iljpgDecodePrivPtr)pPrivate);
  95. error2 = _iljpgDeDCTCleanup ((iljpgDecodePrivPtr)pPrivate);
  96. /* Free the given private data. Note that pPrivate->pData is not
  97. freed; that is done when the caller calls iljpgFreeData().
  98. */
  99. ILJPG_FREE (pPrivate);
  100. /* Return first error code or success if neither an error */
  101. if (error1)
  102. return error1;
  103. if (error2)
  104. return error2;
  105. return 0;
  106. }
  107. /* -------------------- iljpgDecodeExecute -------------------------- */
  108. /* Decode (decompress) the JPEG data read using "stream", into the per-plane
  109. buffers pointed to by "pPixels": one ptr per component (# of components =
  110. "nComps" in the iljpgData passed to iljpgDecodeInit()).
  111. "nBytesPerRow" is length of each row in the corresponding buffers
  112. in "pPixels". "pPrivate" is the ptr returned by iljpgDecodeInit().
  113. "nDstLines" is the # of lines to write; decoding stops when nDstLines
  114. scan lines have been decoded. "nDstLines" should be a multiple of the MCU
  115. height, except at the last strip where it should be the # of lines remaining
  116. to be decoded; this function will clip.
  117. "doReset" is true if an implicit reset should be done at the beginning
  118. of this function, i.e. if an implicit restart is assumed before each strip.
  119. */
  120. ILJPG_PUBLIC_EXTERN
  121. iljpgError iljpgDecodeExecute (
  122. iljpgPtr pPrivate,
  123. ILJPG_DECODE_STREAM stream,
  124. int doReset,
  125. long nDstLines,
  126. iljpgPtr pDstPixels[],
  127. long nDstBytesPerRow[]
  128. )
  129. {
  130. iljpgDecodePrivPtr pPriv;
  131. iljpgDataPtr pData;
  132. int comp, v, h, mcuWidth, mcuHeight;
  133. unsigned int blockType;
  134. iljpgPtr pPixels;
  135. iljpgError error;
  136. long nBytesPerRow, mcuMaxX, mcuMaxY, bX, bY;
  137. int outHuff[64];
  138. iljpgByte outDCT[64];
  139. int restartInterval;
  140. iljpgCompPtr pComp;
  141. int nBytesInit;
  142. int nLines, dc;
  143. iljpgPtr pDstLine;
  144. pPriv = (iljpgDecodePrivPtr)pPrivate;
  145. pData = pPriv->pData;
  146. /* Decode "interleaved" JPEG data, where all components are grouped together
  147. in Minimum Coded Unit (MCU) size, = 8 * max hori(width) or vert(height)
  148. factor. The "factors" are the inverse of IL subsample factors. For
  149. example, if component 0 is not subsampled and 1 and 2 are subsampled by 2,
  150. then hori/vertFactor for comp 0 is 2, for comps 1..2 is 1, and max hori/vert
  151. factor is 2 (there are 4x as many comp 0 pixels as comps 1 or 2).
  152. So: loop over y, and over x within y, and decode one MCU (all components),
  153. advancing x by mcuWidth and y by mcuHeight.
  154. */
  155. mcuWidth = 8 * pData->maxHoriFactor;
  156. mcuHeight = 8 * pData->maxVertFactor;
  157. restartInterval = pData->restartInterval;
  158. /* Reset temp vars in comp data in private; "height" is size of one strip */
  159. for (comp = 0, pComp = pPriv->compData; comp < pData->nComps; comp++, pComp++) {
  160. pComp->height = nDstLines * pComp->vertFactor / pData->maxVertFactor;
  161. pComp->x = 0;
  162. pComp->y = 0;
  163. }
  164. /* Reset Huffman decoding: beginning of a strip/restart interval */
  165. if (doReset) {
  166. if ((error = _iljpgDehuffReset (pPriv)))
  167. return error;
  168. }
  169. /* Loop over y, and over x within y, and decode one MCU (all components),
  170. advancing x by mcuWidth and y by mcuHeight.
  171. */
  172. for (mcuMaxY = 0; mcuMaxY < nDstLines; mcuMaxY += mcuHeight) {
  173. for (mcuMaxX = 0; mcuMaxX < pData->width; mcuMaxX += mcuWidth) {
  174. /* Decode one MCU, all components, to (mcuX, mcuY). For each component
  175. there are horiFactor * vertFactor 8x8 blocks that go across then down.
  176. If a restart interval and mcu count >, do a reset/restart.
  177. */
  178. if (restartInterval && (pPriv->mcuRestartCount >= restartInterval)) {
  179. if ((error = _iljpgDehuffReset (pPriv)))
  180. return error;
  181. pPriv->mcuRestartCount = 0;
  182. }
  183. for (comp = 0, pComp = pPriv->compData; comp < pData->nComps; comp++, pComp++) {
  184. nBytesPerRow = nDstBytesPerRow[comp];
  185. pPixels = pDstPixels[comp];
  186. for (v = 0, bY = pComp->y; v < pComp->vertFactor; v++, bY += 8) {
  187. for (h = 0, bX = pComp->x; h < pComp->horiFactor; h++, bX += 8) {
  188. if ((error = _iljpgDehuffExecute (pPriv, stream, comp, outHuff,
  189. &blockType)))
  190. return error;
  191. /* Add previous DC to this one, save away for next */
  192. dc = outHuff[0] + pComp->lastDC;
  193. pComp->lastDC = dc;
  194. /* If an 8x8 block fits in output buffer, decode the DCT
  195. (based on return from Huffman decode) directly into
  196. the output buffer; otherwise decode into "outDCT" and
  197. copy top-left part of it into buffer below.
  198. */
  199. pDstLine = pPixels + (bY * nBytesPerRow) + bX;
  200. nLines = pComp->height - bY;
  201. nBytesInit = pComp->width - bX;
  202. if ((nLines >= 8) && (nBytesInit >= 8)) {
  203. switch (blockType) {
  204. case HUFF_DC_ONLY:
  205. dc = (int)(dc * *pComp->pRevScale + 128.0);
  206. if (dc < 0) dc = 0; else if (dc > 255) dc = 255;
  207. nLines = 7;
  208. do {
  209. pDstLine[0] = dc;
  210. pDstLine[1] = dc;
  211. pDstLine[2] = dc;
  212. pDstLine[3] = dc;
  213. pDstLine[4] = dc;
  214. pDstLine[5] = dc;
  215. pDstLine[6] = dc;
  216. pDstLine[7] = dc;
  217. pDstLine += nBytesPerRow;
  218. } while (--nLines >= 0);
  219. break;
  220. case HUFF_FOURX4:
  221. outHuff[0] = dc;
  222. _iljpgDeDCT4x4 (outHuff, nBytesPerRow, pDstLine,
  223. pComp->pRevScale);
  224. break;
  225. case HUFF_FULL:
  226. outHuff[0] = dc;
  227. _iljpgDeDCTFull (outHuff, nBytesPerRow, pDstLine,
  228. pComp->pRevScale);
  229. break;
  230. }
  231. } /* END whole 8x8 block */
  232. else { /* no space for 8x8; clip */
  233. outHuff[0] = dc;
  234. switch (blockType) {
  235. case HUFF_DC_ONLY:
  236. _iljpgDeDCTDCOnly (outHuff, 8, outDCT, pComp->pRevScale);
  237. break;
  238. case HUFF_FOURX4:
  239. _iljpgDeDCT4x4 (outHuff, 8, outDCT, pComp->pRevScale);
  240. break;
  241. case HUFF_FULL:
  242. _iljpgDeDCTFull (outHuff, 8, outDCT, pComp->pRevScale);
  243. break;
  244. }
  245. /* Clip and output 8x8 block to position (bX, bY) */
  246. { int nBytesM1;
  247. iljpgPtr pSrc, pSrcLine, pDst;
  248. if (nBytesInit > 8)
  249. nBytesInit = 8;
  250. if (nLines > 8)
  251. nLines = 8;
  252. if ((nLines > 0) && (nBytesInit > 0)) {
  253. nLines--; /* make # lines/bytes - 1 */
  254. nBytesInit--;
  255. pSrcLine = outDCT;
  256. do {
  257. nBytesM1 = nBytesInit;
  258. pSrc = pSrcLine;
  259. pSrcLine += 8;
  260. pDst = pDstLine;
  261. pDstLine += nBytesPerRow;
  262. do {
  263. *pDst++ = *pSrc++;
  264. } while (--nBytesM1 >= 0);
  265. } while (--nLines >= 0);
  266. }
  267. }
  268. } /* END clip */
  269. } /* END hori, one 8x8 block */
  270. } /* END vert */
  271. pComp->x += pComp->mcuXInc; /* move component one MCU to right */
  272. } /* END one component */
  273. pPriv->mcuRestartCount++; /* inc count of mcus since restart */
  274. } /* END one hori MCU */
  275. /* Move each component one MCU down, reset to left edge */
  276. for (comp = 0, pComp = pPriv->compData; comp < pData->nComps; comp++, pComp++) {
  277. pComp->y += pComp->mcuYInc;
  278. pComp->x = 0;
  279. }
  280. } /* END one vert MCU */
  281. return 0;
  282. }