/src/FreeImage/Source/LibMNG/libmng_jpeg.c

https://bitbucket.org/cabalistic/ogredeps/ · C · 1088 lines · 747 code · 168 blank · 173 comment · 147 complexity · 1a0ea204931b2b2fc197d206599a75bf MD5 · raw file

  1. /* ************************************************************************** */
  2. /* * For conditions of distribution and use, * */
  3. /* * see copyright notice in libmng.h * */
  4. /* ************************************************************************** */
  5. /* * * */
  6. /* * project : libmng * */
  7. /* * file : libmng_jpeg.c copyright (c) 2000-2004 G.Juyn * */
  8. /* * version : 1.0.9 * */
  9. /* * * */
  10. /* * purpose : JPEG library interface (implementation) * */
  11. /* * * */
  12. /* * author : G.Juyn * */
  13. /* * * */
  14. /* * comment : implementation of the JPEG library interface * */
  15. /* * * */
  16. /* * changes : 0.5.1 - 05/08/2000 - G.Juyn * */
  17. /* * - changed strict-ANSI stuff * */
  18. /* * * */
  19. /* * 0.5.2 - 05/22/2000 - G.Juyn * */
  20. /* * - implemented all the JNG routines * */
  21. /* * * */
  22. /* * 0.5.3 - 06/17/2000 - G.Juyn * */
  23. /* * - added tracing of JPEG calls * */
  24. /* * 0.5.3 - 06/24/2000 - G.Juyn * */
  25. /* * - fixed inclusion of IJG read/write code * */
  26. /* * 0.5.3 - 06/29/2000 - G.Juyn * */
  27. /* * - fixed some 64-bit warnings * */
  28. /* * * */
  29. /* * 0.9.2 - 08/05/2000 - G.Juyn * */
  30. /* * - changed file-prefixes * */
  31. /* * * */
  32. /* * 0.9.3 - 10/16/2000 - G.Juyn * */
  33. /* * - added support for JDAA * */
  34. /* * * */
  35. /* * 1.0.1 - 04/19/2001 - G.Juyn * */
  36. /* * - added export of JPEG functions for DLL * */
  37. /* * 1.0.1 - 04/22/2001 - G.Juyn * */
  38. /* * - fixed memory-leaks (Thanks Gregg!) * */
  39. /* * * */
  40. /* * 1.0.4 - 06/22/2002 - G.Juyn * */
  41. /* * - B526138 - returned IJGSRC6B calling convention to * */
  42. /* * default for MSVC * */
  43. /* * * */
  44. /* * 1.0.5 - 24/02/2003 - G.Juyn * */
  45. /* * - B683152 - libjpeg suspension not always honored correctly* */
  46. /* * * */
  47. /* * 1.0.6 - 03/04/2003 - G.Juyn * */
  48. /* * - fixed some compiler-warnings * */
  49. /* * * */
  50. /* * 1.0.8 - 08/01/2004 - G.Juyn * */
  51. /* * - added support for 3+byte pixelsize for JPEG's * */
  52. /* * * */
  53. /* * 1.0.9 - 12/20/2004 - G.Juyn * */
  54. /* * - cleaned up macro-invocations (thanks to D. Airlie) * */
  55. /* * * */
  56. /* ************************************************************************** */
  57. #include "libmng.h"
  58. #include "libmng_data.h"
  59. #include "libmng_error.h"
  60. #include "libmng_trace.h"
  61. #ifdef __BORLANDC__
  62. #pragma hdrstop
  63. #endif
  64. #include "libmng_memory.h"
  65. #include "libmng_pixels.h"
  66. #include "libmng_jpeg.h"
  67. #if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
  68. #pragma option -A /* force ANSI-C */
  69. #endif
  70. /* ************************************************************************** */
  71. #if defined(MNG_INCLUDE_JNG) && defined(MNG_INCLUDE_DISPLAY_PROCS)
  72. /* ************************************************************************** */
  73. /* * * */
  74. /* * Local IJG callback routines (source-manager, error-manager and such) * */
  75. /* * * */
  76. /* ************************************************************************** */
  77. #ifdef MNG_INCLUDE_IJG6B
  78. /* ************************************************************************** */
  79. #ifdef MNG_INCLUDE_JNG_READ
  80. #ifdef MNG_DEFINE_JPEG_STDCALL
  81. void MNG_DECL mng_init_source (j_decompress_ptr cinfo)
  82. #else
  83. void mng_init_source (j_decompress_ptr cinfo)
  84. #endif
  85. {
  86. return; /* nothing needed */
  87. }
  88. #endif /* MNG_INCLUDE_JNG_READ */
  89. /* ************************************************************************** */
  90. #ifdef MNG_INCLUDE_JNG_READ
  91. #ifdef MNG_DEFINE_JPEG_STDCALL
  92. boolean MNG_DECL mng_fill_input_buffer (j_decompress_ptr cinfo)
  93. #else
  94. boolean mng_fill_input_buffer (j_decompress_ptr cinfo)
  95. #endif
  96. {
  97. return FALSE; /* force IJG routine to return to caller */
  98. }
  99. #endif /* MNG_INCLUDE_JNG_READ */
  100. /* ************************************************************************** */
  101. #ifdef MNG_INCLUDE_JNG_READ
  102. #ifdef MNG_DEFINE_JPEG_STDCALL
  103. void MNG_DECL mng_skip_input_data (j_decompress_ptr cinfo, long num_bytes)
  104. #else
  105. void mng_skip_input_data (j_decompress_ptr cinfo, long num_bytes)
  106. #endif
  107. {
  108. if (num_bytes > 0) /* ignore fony calls */
  109. { /* address my generic structure */
  110. mng_datap pData = (mng_datap)cinfo->client_data;
  111. /* address source manager */
  112. mngjpeg_sourcep pSrc = pData->pJPEGdinfo->src;
  113. /* problem scenario ? */
  114. if (pSrc->bytes_in_buffer < (size_t)num_bytes)
  115. { /* tell the boss we need to skip some data! */
  116. pData->iJPEGtoskip = (mng_uint32)((size_t)num_bytes - pSrc->bytes_in_buffer);
  117. pSrc->bytes_in_buffer = 0; /* let the JPEG lib suspend */
  118. pSrc->next_input_byte = MNG_NULL;
  119. }
  120. else
  121. { /* simply advance in the buffer */
  122. pSrc->bytes_in_buffer -= num_bytes;
  123. pSrc->next_input_byte += num_bytes;
  124. }
  125. }
  126. return;
  127. }
  128. #endif /* MNG_INCLUDE_JNG_READ */
  129. /* ************************************************************************** */
  130. #ifdef MNG_INCLUDE_JNG_READ
  131. #ifdef MNG_DEFINE_JPEG_STDCALL
  132. void MNG_DECL mng_skip_input_data2 (j_decompress_ptr cinfo, long num_bytes)
  133. #else
  134. void mng_skip_input_data2 (j_decompress_ptr cinfo, long num_bytes)
  135. #endif
  136. {
  137. if (num_bytes > 0) /* ignore fony calls */
  138. { /* address my generic structure */
  139. mng_datap pData = (mng_datap)cinfo->client_data;
  140. /* address source manager */
  141. mngjpeg_sourcep pSrc = pData->pJPEGdinfo2->src;
  142. /* problem scenario ? */
  143. if (pSrc->bytes_in_buffer < (size_t)num_bytes)
  144. { /* tell the boss we need to skip some data! */
  145. pData->iJPEGtoskip2 = (mng_uint32)((size_t)num_bytes - pSrc->bytes_in_buffer);
  146. pSrc->bytes_in_buffer = 0; /* let the JPEG lib suspend */
  147. pSrc->next_input_byte = MNG_NULL;
  148. }
  149. else
  150. { /* simply advance in the buffer */
  151. pSrc->bytes_in_buffer -= num_bytes;
  152. pSrc->next_input_byte += num_bytes;
  153. }
  154. }
  155. return;
  156. }
  157. #endif /* MNG_INCLUDE_JNG_READ */
  158. /* ************************************************************************** */
  159. #ifdef MNG_INCLUDE_JNG_READ
  160. #ifdef MNG_DEFINE_JPEG_STDCALL
  161. void MNG_DECL mng_term_source (j_decompress_ptr cinfo)
  162. #else
  163. void mng_term_source (j_decompress_ptr cinfo)
  164. #endif
  165. {
  166. return; /* nothing needed */
  167. }
  168. #endif /* MNG_INCLUDE_JNG_READ */
  169. /* ************************************************************************** */
  170. #ifdef MNG_USE_SETJMP
  171. #ifdef MNG_DEFINE_JPEG_STDCALL
  172. void MNG_DECL mng_error_exit (j_common_ptr cinfo)
  173. #else
  174. void mng_error_exit (j_common_ptr cinfo)
  175. #endif
  176. { /* address my generic structure */
  177. mng_datap pData = (mng_datap)cinfo->client_data;
  178. #ifdef MNG_ERROR_TELLTALE /* fill the message text ??? */
  179. (*cinfo->err->output_message) (cinfo);
  180. #endif
  181. /* return to the point of no return... */
  182. longjmp (pData->sErrorbuf, cinfo->err->msg_code);
  183. }
  184. #endif /* MNG_USE_SETJMP */
  185. /* ************************************************************************** */
  186. #ifdef MNG_USE_SETJMP
  187. #ifdef MNG_DEFINE_JPEG_STDCALL
  188. void MNG_DECL mng_output_message (j_common_ptr cinfo)
  189. #else
  190. void mng_output_message (j_common_ptr cinfo)
  191. #endif
  192. {
  193. return; /* just do nothing ! */
  194. }
  195. #endif /* MNG_USE_SETJMP */
  196. /* ************************************************************************** */
  197. #endif /* MNG_INCLUDE_IJG6B */
  198. /* ************************************************************************** */
  199. /* * * */
  200. /* * Global JPEG routines * */
  201. /* * * */
  202. /* ************************************************************************** */
  203. mng_retcode mngjpeg_initialize (mng_datap pData)
  204. {
  205. #ifdef MNG_SUPPORT_TRACE
  206. MNG_TRACE (pData, MNG_FN_JPEG_INITIALIZE, MNG_LC_START);
  207. #endif
  208. /* allocate space for JPEG structures if necessary */
  209. #ifdef MNG_INCLUDE_JNG_READ
  210. if (pData->pJPEGderr == MNG_NULL)
  211. MNG_ALLOC (pData, pData->pJPEGderr, sizeof (mngjpeg_error ));
  212. if (pData->pJPEGdsrc == MNG_NULL)
  213. MNG_ALLOC (pData, pData->pJPEGdsrc, sizeof (mngjpeg_source));
  214. if (pData->pJPEGdinfo == MNG_NULL)
  215. MNG_ALLOC (pData, pData->pJPEGdinfo, sizeof (mngjpeg_decomp));
  216. /* enable reverse addressing */
  217. pData->pJPEGdinfo->client_data = pData;
  218. if (pData->pJPEGderr2 == MNG_NULL)
  219. MNG_ALLOC (pData, pData->pJPEGderr2, sizeof (mngjpeg_error ));
  220. if (pData->pJPEGdsrc2 == MNG_NULL)
  221. MNG_ALLOC (pData, pData->pJPEGdsrc2, sizeof (mngjpeg_source));
  222. if (pData->pJPEGdinfo2 == MNG_NULL)
  223. MNG_ALLOC (pData, pData->pJPEGdinfo2, sizeof (mngjpeg_decomp));
  224. /* enable reverse addressing */
  225. pData->pJPEGdinfo2->client_data = pData;
  226. #endif
  227. #ifdef MNG_INCLUDE_JNG_WRITE
  228. if (pData->pJPEGcerr == MNG_NULL)
  229. MNG_ALLOC (pData, pData->pJPEGcerr, sizeof (mngjpeg_error ));
  230. if (pData->pJPEGcinfo == MNG_NULL)
  231. MNG_ALLOC (pData, pData->pJPEGcinfo, sizeof (mngjpeg_comp ));
  232. /* enable reverse addressing */
  233. pData->pJPEGcinfo->client_data = pData;
  234. #endif
  235. if (pData->pJPEGbuf == MNG_NULL) /* initialize temporary buffers */
  236. {
  237. pData->iJPEGbufmax = MNG_JPEG_MAXBUF;
  238. MNG_ALLOC (pData, pData->pJPEGbuf, pData->iJPEGbufmax);
  239. }
  240. if (pData->pJPEGbuf2 == MNG_NULL)
  241. {
  242. pData->iJPEGbufmax2 = MNG_JPEG_MAXBUF;
  243. MNG_ALLOC (pData, pData->pJPEGbuf2, pData->iJPEGbufmax2);
  244. }
  245. pData->pJPEGcurrent = pData->pJPEGbuf;
  246. pData->iJPEGbufremain = 0;
  247. pData->pJPEGrow = MNG_NULL;
  248. pData->iJPEGrowlen = 0;
  249. pData->iJPEGtoskip = 0;
  250. pData->pJPEGcurrent2 = pData->pJPEGbuf2;
  251. pData->iJPEGbufremain2 = 0;
  252. pData->pJPEGrow2 = MNG_NULL;
  253. pData->iJPEGrowlen2 = 0;
  254. pData->iJPEGtoskip2 = 0;
  255. /* not doing anything yet ! */
  256. pData->bJPEGcompress = MNG_FALSE;
  257. pData->bJPEGdecompress = MNG_FALSE;
  258. pData->bJPEGhasheader = MNG_FALSE;
  259. pData->bJPEGdecostarted = MNG_FALSE;
  260. pData->bJPEGscanstarted = MNG_FALSE;
  261. pData->bJPEGscanending = MNG_FALSE;
  262. pData->bJPEGdecompress2 = MNG_FALSE;
  263. pData->bJPEGhasheader2 = MNG_FALSE;
  264. pData->bJPEGdecostarted2 = MNG_FALSE;
  265. pData->bJPEGscanstarted2 = MNG_FALSE;
  266. pData->iJPEGrow = 0; /* zero input/output lines */
  267. pData->iJPEGalpharow = 0;
  268. pData->iJPEGrgbrow = 0;
  269. pData->iJPEGdisprow = 0;
  270. #ifdef MNG_SUPPORT_TRACE
  271. MNG_TRACE (pData, MNG_FN_JPEG_INITIALIZE, MNG_LC_END);
  272. #endif
  273. return MNG_NOERROR;
  274. }
  275. /* ************************************************************************** */
  276. mng_retcode mngjpeg_cleanup (mng_datap pData)
  277. {
  278. #if defined(MNG_INCLUDE_IJG6B) && defined(MNG_USE_SETJMP)
  279. mng_retcode iRetcode;
  280. #endif
  281. #ifdef MNG_SUPPORT_TRACE
  282. MNG_TRACE (pData, MNG_FN_JPEG_CLEANUP, MNG_LC_START);
  283. #endif
  284. #ifdef MNG_INCLUDE_IJG6B
  285. #ifdef MNG_USE_SETJMP
  286. iRetcode = setjmp (pData->sErrorbuf);/* setup local JPEG error-recovery */
  287. if (iRetcode != 0) /* got here from longjmp ? */
  288. MNG_ERRORJ (pData, iRetcode); /* then IJG-lib issued an error */
  289. #endif
  290. #ifdef MNG_INCLUDE_JNG_READ /* still decompressing something ? */
  291. if (pData->bJPEGdecompress)
  292. jpeg_destroy_decompress (pData->pJPEGdinfo);
  293. if (pData->bJPEGdecompress2)
  294. jpeg_destroy_decompress (pData->pJPEGdinfo2);
  295. #endif
  296. #ifdef MNG_INCLUDE_JNG_WRITE
  297. if (pData->bJPEGcompress) /* still compressing something ? */
  298. jpeg_destroy_compress (pData->pJPEGcinfo);
  299. #endif
  300. #endif /* MNG_INCLUDE_IJG6B */
  301. /* cleanup temporary buffers */
  302. MNG_FREE (pData, pData->pJPEGbuf2, pData->iJPEGbufmax2);
  303. MNG_FREE (pData, pData->pJPEGbuf, pData->iJPEGbufmax);
  304. /* cleanup space for JPEG structures */
  305. #ifdef MNG_INCLUDE_JNG_WRITE
  306. MNG_FREE (pData, pData->pJPEGcinfo, sizeof (mngjpeg_comp ));
  307. MNG_FREE (pData, pData->pJPEGcerr, sizeof (mngjpeg_error ));
  308. #endif
  309. #ifdef MNG_INCLUDE_JNG_READ
  310. MNG_FREE (pData, pData->pJPEGdinfo, sizeof (mngjpeg_decomp));
  311. MNG_FREE (pData, pData->pJPEGdsrc, sizeof (mngjpeg_source));
  312. MNG_FREE (pData, pData->pJPEGderr, sizeof (mngjpeg_error ));
  313. MNG_FREE (pData, pData->pJPEGdinfo2, sizeof (mngjpeg_decomp));
  314. MNG_FREE (pData, pData->pJPEGdsrc2, sizeof (mngjpeg_source));
  315. MNG_FREE (pData, pData->pJPEGderr2, sizeof (mngjpeg_error ));
  316. #endif
  317. MNG_FREE (pData, pData->pJPEGrow2, pData->iJPEGrowlen2);
  318. MNG_FREE (pData, pData->pJPEGrow, pData->iJPEGrowlen);
  319. /* whatever we were doing ... */
  320. /* we don't anymore ... */
  321. pData->bJPEGcompress = MNG_FALSE;
  322. pData->bJPEGdecompress = MNG_FALSE;
  323. pData->bJPEGhasheader = MNG_FALSE;
  324. pData->bJPEGdecostarted = MNG_FALSE;
  325. pData->bJPEGscanstarted = MNG_FALSE;
  326. pData->bJPEGscanending = MNG_FALSE;
  327. pData->bJPEGdecompress2 = MNG_FALSE;
  328. pData->bJPEGhasheader2 = MNG_FALSE;
  329. pData->bJPEGdecostarted2 = MNG_FALSE;
  330. pData->bJPEGscanstarted2 = MNG_FALSE;
  331. #ifdef MNG_SUPPORT_TRACE
  332. MNG_TRACE (pData, MNG_FN_JPEG_CLEANUP, MNG_LC_END);
  333. #endif
  334. return MNG_NOERROR;
  335. }
  336. /* ************************************************************************** */
  337. /* * * */
  338. /* * JPEG decompression routines (JDAT) * */
  339. /* * * */
  340. /* ************************************************************************** */
  341. #ifdef MNG_INCLUDE_JNG_READ
  342. mng_retcode mngjpeg_decompressinit (mng_datap pData)
  343. {
  344. #if defined(MNG_INCLUDE_IJG6B) && defined(MNG_USE_SETJMP)
  345. mng_retcode iRetcode;
  346. #endif
  347. #ifdef MNG_SUPPORT_TRACE
  348. MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSINIT, MNG_LC_START);
  349. #endif
  350. #ifdef MNG_INCLUDE_IJG6B
  351. /* allocate and initialize a JPEG decompression object */
  352. pData->pJPEGdinfo->err = jpeg_std_error (pData->pJPEGderr);
  353. #ifdef MNG_USE_SETJMP /* setup local JPEG error-routines */
  354. pData->pJPEGderr->error_exit = mng_error_exit;
  355. pData->pJPEGderr->output_message = mng_output_message;
  356. iRetcode = setjmp (pData->sErrorbuf);/* setup local JPEG error-recovery */
  357. if (iRetcode != 0) /* got here from longjmp ? */
  358. MNG_ERRORJ (pData, iRetcode); /* then IJG-lib issued an error */
  359. #endif /* MNG_USE_SETJMP */
  360. /* allocate and initialize a JPEG decompression object (continued) */
  361. #ifdef MNG_SUPPORT_TRACE
  362. MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSINIT, MNG_LC_JPEG_CREATE_DECOMPRESS)
  363. #endif
  364. jpeg_create_decompress (pData->pJPEGdinfo);
  365. pData->bJPEGdecompress = MNG_TRUE; /* indicate it's initialized */
  366. /* specify the source of the compressed data (eg, a file) */
  367. /* no, not a file; we have buffered input */
  368. pData->pJPEGdinfo->src = pData->pJPEGdsrc;
  369. /* use the default handler */
  370. pData->pJPEGdinfo->src->resync_to_restart = jpeg_resync_to_restart;
  371. /* setup local source routine & parms */
  372. pData->pJPEGdinfo->src->init_source = mng_init_source;
  373. pData->pJPEGdinfo->src->fill_input_buffer = mng_fill_input_buffer;
  374. pData->pJPEGdinfo->src->skip_input_data = mng_skip_input_data;
  375. pData->pJPEGdinfo->src->term_source = mng_term_source;
  376. pData->pJPEGdinfo->src->next_input_byte = pData->pJPEGcurrent;
  377. pData->pJPEGdinfo->src->bytes_in_buffer = pData->iJPEGbufremain;
  378. #endif /* MNG_INCLUDE_IJG6B */
  379. #ifdef MNG_SUPPORT_TRACE
  380. MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSINIT, MNG_LC_END);
  381. #endif
  382. return MNG_NOERROR;
  383. }
  384. #endif /* MNG_INCLUDE_JNG_READ */
  385. /* ************************************************************************** */
  386. #ifdef MNG_INCLUDE_JNG_READ
  387. mng_retcode mngjpeg_decompressdata (mng_datap pData,
  388. mng_uint32 iRawsize,
  389. mng_uint8p pRawdata)
  390. {
  391. mng_retcode iRetcode;
  392. mng_uint32 iRemain;
  393. mng_uint8p pWork;
  394. #ifdef MNG_SUPPORT_TRACE
  395. MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSDATA, MNG_LC_START);
  396. #endif
  397. #if defined (MNG_INCLUDE_IJG6B) && defined(MNG_USE_SETJMP)
  398. iRetcode = setjmp (pData->sErrorbuf);/* initialize local JPEG error-recovery */
  399. if (iRetcode != 0) /* got here from longjmp ? */
  400. MNG_ERRORJ (pData, iRetcode); /* then IJG-lib issued an error */
  401. #endif
  402. pWork = pRawdata;
  403. iRemain = iRawsize;
  404. if (pData->iJPEGtoskip) /* JPEG-lib told us to skip some more data ? */
  405. {
  406. if (iRemain > pData->iJPEGtoskip) /* enough data in this buffer ? */
  407. {
  408. iRemain -= pData->iJPEGtoskip; /* skip enough to access the next byte */
  409. pWork += pData->iJPEGtoskip;
  410. pData->iJPEGtoskip = 0; /* no more to skip then */
  411. }
  412. else
  413. {
  414. pData->iJPEGtoskip -= iRemain; /* skip all data in the buffer */
  415. iRemain = 0; /* and indicate this accordingly */
  416. }
  417. /* the skip set current-pointer to NULL ! */
  418. pData->pJPEGcurrent = pData->pJPEGbuf;
  419. }
  420. while (iRemain) /* repeat until no more input-bytes */
  421. { /* need to shift anything ? */
  422. if ((pData->pJPEGcurrent > pData->pJPEGbuf) &&
  423. (pData->pJPEGcurrent - pData->pJPEGbuf + pData->iJPEGbufremain + iRemain > pData->iJPEGbufmax))
  424. {
  425. if (pData->iJPEGbufremain > 0) /* then do so */
  426. MNG_COPY (pData->pJPEGbuf, pData->pJPEGcurrent, pData->iJPEGbufremain);
  427. pData->pJPEGcurrent = pData->pJPEGbuf;
  428. }
  429. /* does the remaining input fit into the buffer ? */
  430. if (pData->iJPEGbufremain + iRemain <= pData->iJPEGbufmax)
  431. { /* move the lot */
  432. MNG_COPY ((pData->pJPEGcurrent + pData->iJPEGbufremain), pWork, iRemain);
  433. pData->iJPEGbufremain += iRemain;/* adjust remaining_bytes counter */
  434. iRemain = 0; /* and indicate there's no input left */
  435. }
  436. else
  437. { /* calculate what does fit */
  438. mng_uint32 iFits = pData->iJPEGbufmax - pData->iJPEGbufremain;
  439. if (iFits <= 0) /* no space is just bugger 'm all */
  440. MNG_ERROR (pData, MNG_JPEGBUFTOOSMALL);
  441. /* move that */
  442. MNG_COPY ((pData->pJPEGcurrent + pData->iJPEGbufremain), pWork, iFits);
  443. pData->iJPEGbufremain += iFits; /* adjust remain_bytes counter */
  444. iRemain -= iFits; /* and the input-parms */
  445. pWork += iFits;
  446. }
  447. #ifdef MNG_INCLUDE_IJG6B
  448. pData->pJPEGdinfo->src->next_input_byte = pData->pJPEGcurrent;
  449. pData->pJPEGdinfo->src->bytes_in_buffer = pData->iJPEGbufremain;
  450. if (!pData->bJPEGhasheader) /* haven't got the header yet ? */
  451. {
  452. /* call jpeg_read_header() to obtain image info */
  453. #ifdef MNG_SUPPORT_TRACE
  454. MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSDATA, MNG_LC_JPEG_READ_HEADER)
  455. #endif
  456. if (jpeg_read_header (pData->pJPEGdinfo, TRUE) != JPEG_SUSPENDED)
  457. { /* indicate the header's oke */
  458. pData->bJPEGhasheader = MNG_TRUE;
  459. /* let's do some sanity checks ! */
  460. if ((pData->pJPEGdinfo->image_width != pData->iDatawidth ) ||
  461. (pData->pJPEGdinfo->image_height != pData->iDataheight) )
  462. MNG_ERROR (pData, MNG_JPEGPARMSERR);
  463. if ( ((pData->iJHDRcolortype == MNG_COLORTYPE_JPEGGRAY ) ||
  464. (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGGRAYA) ) &&
  465. (pData->pJPEGdinfo->jpeg_color_space != JCS_GRAYSCALE ) )
  466. MNG_ERROR (pData, MNG_JPEGPARMSERR);
  467. if ( ((pData->iJHDRcolortype == MNG_COLORTYPE_JPEGCOLOR ) ||
  468. (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGCOLORA) ) &&
  469. (pData->pJPEGdinfo->jpeg_color_space != JCS_YCbCr ) )
  470. MNG_ERROR (pData, MNG_JPEGPARMSERR);
  471. /* indicate whether or not it's progressive */
  472. pData->bJPEGprogressive = (mng_bool)jpeg_has_multiple_scans (pData->pJPEGdinfo);
  473. /* progressive+alpha can't display "on-the-fly"!! */
  474. if ((pData->bJPEGprogressive) &&
  475. ((pData->iJHDRcolortype == MNG_COLORTYPE_JPEGGRAYA ) ||
  476. (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGCOLORA) ))
  477. pData->fDisplayrow = MNG_NULL;
  478. /* allocate a row of JPEG-samples */
  479. if (pData->pJPEGdinfo->jpeg_color_space == JCS_YCbCr)
  480. pData->iJPEGrowlen = pData->pJPEGdinfo->image_width * RGB_PIXELSIZE;
  481. else
  482. pData->iJPEGrowlen = pData->pJPEGdinfo->image_width;
  483. MNG_ALLOC (pData, pData->pJPEGrow, pData->iJPEGrowlen);
  484. pData->iJPEGrgbrow = 0; /* quite empty up to now */
  485. }
  486. pData->pJPEGcurrent = (mng_uint8p)pData->pJPEGdinfo->src->next_input_byte;
  487. pData->iJPEGbufremain = (mng_uint32)pData->pJPEGdinfo->src->bytes_in_buffer;
  488. }
  489. /* decompress not started ? */
  490. if ((pData->bJPEGhasheader) && (!pData->bJPEGdecostarted))
  491. {
  492. /* set parameters for decompression */
  493. if (pData->bJPEGprogressive) /* progressive display ? */
  494. pData->pJPEGdinfo->buffered_image = TRUE;
  495. /* jpeg_start_decompress(...); */
  496. #ifdef MNG_SUPPORT_TRACE
  497. MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSDATA, MNG_LC_JPEG_START_DECOMPRESS)
  498. #endif
  499. if (jpeg_start_decompress (pData->pJPEGdinfo) == TRUE)
  500. /* indicate it started */
  501. pData->bJPEGdecostarted = MNG_TRUE;
  502. pData->pJPEGcurrent = (mng_uint8p)pData->pJPEGdinfo->src->next_input_byte;
  503. pData->iJPEGbufremain = (mng_uint32)pData->pJPEGdinfo->src->bytes_in_buffer;
  504. }
  505. /* process some scanlines ? */
  506. if ((pData->bJPEGhasheader) && (pData->bJPEGdecostarted) &&
  507. ((!jpeg_input_complete (pData->pJPEGdinfo)) ||
  508. (pData->pJPEGdinfo->output_scanline < pData->pJPEGdinfo->output_height) ||
  509. ((pData->bJPEGprogressive) && (pData->bJPEGscanending))))
  510. {
  511. mng_int32 iLines = 0;
  512. /* for (each output pass) */
  513. do
  514. { /* address the row output buffer */
  515. JSAMPROW pRow = (JSAMPROW)pData->pJPEGrow;
  516. /* init new pass ? */
  517. if ((pData->bJPEGprogressive) && (!pData->bJPEGscanstarted))
  518. {
  519. pData->bJPEGscanstarted = MNG_TRUE;
  520. /* adjust output decompression parameters if required */
  521. /* nop */
  522. /* start a new output pass */
  523. #ifdef MNG_SUPPORT_TRACE
  524. MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSDATA, MNG_LC_JPEG_START_OUTPUT)
  525. #endif
  526. jpeg_start_output (pData->pJPEGdinfo, pData->pJPEGdinfo->input_scan_number);
  527. pData->iJPEGrow = 0; /* start at row 0 in the image again */
  528. }
  529. /* while (scan lines remain to be read) */
  530. if ((!pData->bJPEGprogressive) || (!pData->bJPEGscanending))
  531. {
  532. do
  533. {
  534. /* jpeg_read_scanlines(...); */
  535. #ifdef MNG_SUPPORT_TRACE
  536. MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSDATA, MNG_LC_JPEG_READ_SCANLINES)
  537. #endif
  538. iLines = jpeg_read_scanlines (pData->pJPEGdinfo, (JSAMPARRAY)&pRow, 1);
  539. pData->pJPEGcurrent = (mng_uint8p)pData->pJPEGdinfo->src->next_input_byte;
  540. pData->iJPEGbufremain = (mng_uint32)pData->pJPEGdinfo->src->bytes_in_buffer;
  541. if (iLines > 0) /* got something ? */
  542. {
  543. if (pData->fStorerow2) /* store in object ? */
  544. {
  545. iRetcode = ((mng_storerow)pData->fStorerow2) (pData);
  546. if (iRetcode) /* on error bail out */
  547. return iRetcode;
  548. }
  549. }
  550. }
  551. while ((pData->pJPEGdinfo->output_scanline < pData->pJPEGdinfo->output_height) &&
  552. (iLines > 0)); /* until end-of-image or not enough input-data */
  553. }
  554. /* terminate output pass */
  555. if ((pData->bJPEGprogressive) &&
  556. (pData->pJPEGdinfo->output_scanline >= pData->pJPEGdinfo->output_height))
  557. {
  558. #ifdef MNG_SUPPORT_TRACE
  559. MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSDATA, MNG_LC_JPEG_FINISH_OUTPUT)
  560. #endif
  561. if (jpeg_finish_output (pData->pJPEGdinfo) != JPEG_SUSPENDED)
  562. { /* this scan has ended */
  563. pData->bJPEGscanstarted = MNG_FALSE;
  564. pData->bJPEGscanending = MNG_FALSE;
  565. }
  566. else
  567. {
  568. pData->bJPEGscanending = MNG_TRUE;
  569. }
  570. }
  571. }
  572. while ((!jpeg_input_complete (pData->pJPEGdinfo)) &&
  573. (iLines > 0) && (!pData->bJPEGscanending));
  574. }
  575. /* end of image ? */
  576. if ((pData->bJPEGhasheader) && (pData->bJPEGdecostarted) &&
  577. (!pData->bJPEGscanending) && (jpeg_input_complete (pData->pJPEGdinfo)) &&
  578. (pData->pJPEGdinfo->input_scan_number == pData->pJPEGdinfo->output_scan_number))
  579. {
  580. /* jpeg_finish_decompress(...); */
  581. #ifdef MNG_SUPPORT_TRACE
  582. MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSDATA, MNG_LC_JPEG_FINISH_DECOMPRESS)
  583. #endif
  584. if (jpeg_finish_decompress (pData->pJPEGdinfo) == TRUE)
  585. { /* indicate it's done */
  586. pData->bJPEGhasheader = MNG_FALSE;
  587. pData->bJPEGdecostarted = MNG_FALSE;
  588. pData->pJPEGcurrent = (mng_uint8p)pData->pJPEGdinfo->src->next_input_byte;
  589. pData->iJPEGbufremain = (mng_uint32)pData->pJPEGdinfo->src->bytes_in_buffer;
  590. /* remaining fluff is an error ! */
  591. if ((pData->iJPEGbufremain > 0) || (iRemain > 0))
  592. MNG_ERROR (pData, MNG_TOOMUCHJDAT);
  593. }
  594. }
  595. #endif /* MNG_INCLUDE_IJG6B */
  596. }
  597. #ifdef MNG_SUPPORT_TRACE
  598. MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSDATA, MNG_LC_END);
  599. #endif
  600. return MNG_NOERROR;
  601. }
  602. #endif /* MNG_INCLUDE_JNG_READ */
  603. /* ************************************************************************** */
  604. #ifdef MNG_INCLUDE_JNG_READ
  605. mng_retcode mngjpeg_decompressfree (mng_datap pData)
  606. {
  607. #if defined(MNG_INCLUDE_IJG6B) && defined(MNG_USE_SETJMP)
  608. mng_retcode iRetcode;
  609. #endif
  610. #ifdef MNG_SUPPORT_TRACE
  611. MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSFREE, MNG_LC_START);
  612. #endif
  613. #ifdef MNG_INCLUDE_IJG6B
  614. #ifdef MNG_USE_SETJMP
  615. iRetcode = setjmp (pData->sErrorbuf);/* setup local JPEG error-recovery */
  616. if (iRetcode != 0) /* got here from longjmp ? */
  617. MNG_ERRORJ (pData, iRetcode); /* then IJG-lib issued an error */
  618. #endif
  619. /* free the row of JPEG-samples*/
  620. MNG_FREE (pData, pData->pJPEGrow, pData->iJPEGrowlen);
  621. /* release the JPEG decompression object */
  622. #ifdef MNG_SUPPORT_TRACE
  623. MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSFREE, MNG_LC_JPEG_DESTROY_DECOMPRESS)
  624. #endif
  625. jpeg_destroy_decompress (pData->pJPEGdinfo);
  626. pData->bJPEGdecompress = MNG_FALSE; /* indicate it's done */
  627. #endif /* MNG_INCLUDE_IJG6B */
  628. #ifdef MNG_SUPPORT_TRACE
  629. MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSFREE, MNG_LC_END);
  630. #endif
  631. return MNG_NOERROR;
  632. }
  633. #endif /* MNG_INCLUDE_JNG_READ */
  634. /* ************************************************************************** */
  635. /* * * */
  636. /* * JPEG decompression routines (JDAA) * */
  637. /* * * */
  638. /* ************************************************************************** */
  639. #ifdef MNG_INCLUDE_JNG_READ
  640. mng_retcode mngjpeg_decompressinit2 (mng_datap pData)
  641. {
  642. #if defined(MNG_INCLUDE_IJG6B) && defined(MNG_USE_SETJMP)
  643. mng_retcode iRetcode;
  644. #endif
  645. #ifdef MNG_SUPPORT_TRACE
  646. MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSINIT, MNG_LC_START);
  647. #endif
  648. #ifdef MNG_INCLUDE_IJG6B
  649. /* allocate and initialize a JPEG decompression object */
  650. pData->pJPEGdinfo2->err = jpeg_std_error (pData->pJPEGderr2);
  651. #ifdef MNG_USE_SETJMP /* setup local JPEG error-routines */
  652. pData->pJPEGderr2->error_exit = mng_error_exit;
  653. pData->pJPEGderr2->output_message = mng_output_message;
  654. iRetcode = setjmp (pData->sErrorbuf);/* setup local JPEG error-recovery */
  655. if (iRetcode != 0) /* got here from longjmp ? */
  656. MNG_ERRORJ (pData, iRetcode); /* then IJG-lib issued an error */
  657. #endif /* MNG_USE_SETJMP */
  658. /* allocate and initialize a JPEG decompression object (continued) */
  659. #ifdef MNG_SUPPORT_TRACE
  660. MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSINIT, MNG_LC_JPEG_CREATE_DECOMPRESS)
  661. #endif
  662. jpeg_create_decompress (pData->pJPEGdinfo2);
  663. pData->bJPEGdecompress2 = MNG_TRUE; /* indicate it's initialized */
  664. /* specify the source of the compressed data (eg, a file) */
  665. /* no, not a file; we have buffered input */
  666. pData->pJPEGdinfo2->src = pData->pJPEGdsrc2;
  667. /* use the default handler */
  668. pData->pJPEGdinfo2->src->resync_to_restart = jpeg_resync_to_restart;
  669. /* setup local source routine & parms */
  670. pData->pJPEGdinfo2->src->init_source = mng_init_source;
  671. pData->pJPEGdinfo2->src->fill_input_buffer = mng_fill_input_buffer;
  672. pData->pJPEGdinfo2->src->skip_input_data = mng_skip_input_data2;
  673. pData->pJPEGdinfo2->src->term_source = mng_term_source;
  674. pData->pJPEGdinfo2->src->next_input_byte = pData->pJPEGcurrent2;
  675. pData->pJPEGdinfo2->src->bytes_in_buffer = pData->iJPEGbufremain2;
  676. #endif /* MNG_INCLUDE_IJG6B */
  677. #ifdef MNG_SUPPORT_TRACE
  678. MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSINIT, MNG_LC_END);
  679. #endif
  680. return MNG_NOERROR;
  681. }
  682. #endif /* MNG_INCLUDE_JNG_READ */
  683. /* ************************************************************************** */
  684. #ifdef MNG_INCLUDE_JNG_READ
  685. mng_retcode mngjpeg_decompressdata2 (mng_datap pData,
  686. mng_uint32 iRawsize,
  687. mng_uint8p pRawdata)
  688. {
  689. mng_retcode iRetcode;
  690. mng_uint32 iRemain;
  691. mng_uint8p pWork;
  692. #ifdef MNG_SUPPORT_TRACE
  693. MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSDATA, MNG_LC_START);
  694. #endif
  695. #if defined (MNG_INCLUDE_IJG6B) && defined(MNG_USE_SETJMP)
  696. iRetcode = setjmp (pData->sErrorbuf);/* initialize local JPEG error-recovery */
  697. if (iRetcode != 0) /* got here from longjmp ? */
  698. MNG_ERRORJ (pData, iRetcode); /* then IJG-lib issued an error */
  699. #endif
  700. pWork = pRawdata;
  701. iRemain = iRawsize;
  702. if (pData->iJPEGtoskip2) /* JPEG-lib told us to skip some more data ? */
  703. {
  704. if (iRemain > pData->iJPEGtoskip2) /* enough data in this buffer ? */
  705. {
  706. iRemain -= pData->iJPEGtoskip2; /* skip enough to access the next byte */
  707. pWork += pData->iJPEGtoskip2;
  708. pData->iJPEGtoskip2 = 0; /* no more to skip then */
  709. }
  710. else
  711. {
  712. pData->iJPEGtoskip2 -= iRemain; /* skip all data in the buffer */
  713. iRemain = 0; /* and indicate this accordingly */
  714. }
  715. /* the skip set current-pointer to NULL ! */
  716. pData->pJPEGcurrent2 = pData->pJPEGbuf2;
  717. }
  718. while (iRemain) /* repeat until no more input-bytes */
  719. { /* need to shift anything ? */
  720. if ((pData->pJPEGcurrent2 > pData->pJPEGbuf2) &&
  721. (pData->pJPEGcurrent2 - pData->pJPEGbuf2 + pData->iJPEGbufremain2 + iRemain > pData->iJPEGbufmax2))
  722. {
  723. if (pData->iJPEGbufremain2 > 0) /* then do so */
  724. MNG_COPY (pData->pJPEGbuf2, pData->pJPEGcurrent2, pData->iJPEGbufremain2);
  725. pData->pJPEGcurrent2 = pData->pJPEGbuf2;
  726. }
  727. /* does the remaining input fit into the buffer ? */
  728. if (pData->iJPEGbufremain2 + iRemain <= pData->iJPEGbufmax2)
  729. { /* move the lot */
  730. MNG_COPY ((pData->pJPEGcurrent2 + pData->iJPEGbufremain2), pWork, iRemain);
  731. /* adjust remaining_bytes counter */
  732. pData->iJPEGbufremain2 += iRemain;
  733. iRemain = 0; /* and indicate there's no input left */
  734. }
  735. else
  736. { /* calculate what does fit */
  737. mng_uint32 iFits = pData->iJPEGbufmax2 - pData->iJPEGbufremain2;
  738. if (iFits <= 0) /* no space is just bugger 'm all */
  739. MNG_ERROR (pData, MNG_JPEGBUFTOOSMALL);
  740. /* move that */
  741. MNG_COPY ((pData->pJPEGcurrent2 + pData->iJPEGbufremain2), pWork, iFits);
  742. pData->iJPEGbufremain2 += iFits; /* adjust remain_bytes counter */
  743. iRemain -= iFits; /* and the input-parms */
  744. pWork += iFits;
  745. }
  746. #ifdef MNG_INCLUDE_IJG6B
  747. pData->pJPEGdinfo2->src->next_input_byte = pData->pJPEGcurrent2;
  748. pData->pJPEGdinfo2->src->bytes_in_buffer = pData->iJPEGbufremain2;
  749. if (!pData->bJPEGhasheader2) /* haven't got the header yet ? */
  750. {
  751. /* call jpeg_read_header() to obtain image info */
  752. #ifdef MNG_SUPPORT_TRACE
  753. MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSDATA, MNG_LC_JPEG_READ_HEADER)
  754. #endif
  755. if (jpeg_read_header (pData->pJPEGdinfo2, TRUE) != JPEG_SUSPENDED)
  756. { /* indicate the header's oke */
  757. pData->bJPEGhasheader2 = MNG_TRUE;
  758. /* let's do some sanity checks ! */
  759. if ((pData->pJPEGdinfo2->image_width != pData->iDatawidth ) ||
  760. (pData->pJPEGdinfo2->image_height != pData->iDataheight) )
  761. MNG_ERROR (pData, MNG_JPEGPARMSERR);
  762. if (pData->pJPEGdinfo2->jpeg_color_space != JCS_GRAYSCALE)
  763. MNG_ERROR (pData, MNG_JPEGPARMSERR);
  764. /* indicate whether or not it's progressive */
  765. pData->bJPEGprogressive2 = (mng_bool)jpeg_has_multiple_scans (pData->pJPEGdinfo2);
  766. if (pData->bJPEGprogressive2) /* progressive alphachannel not allowed !!! */
  767. MNG_ERROR (pData, MNG_JPEGPARMSERR);
  768. /* allocate a row of JPEG-samples */
  769. if (pData->pJPEGdinfo2->jpeg_color_space == JCS_YCbCr)
  770. pData->iJPEGrowlen2 = pData->pJPEGdinfo2->image_width * RGB_PIXELSIZE;
  771. else
  772. pData->iJPEGrowlen2 = pData->pJPEGdinfo2->image_width;
  773. MNG_ALLOC (pData, pData->pJPEGrow2, pData->iJPEGrowlen2);
  774. pData->iJPEGalpharow = 0; /* quite empty up to now */
  775. }
  776. pData->pJPEGcurrent2 = (mng_uint8p)pData->pJPEGdinfo2->src->next_input_byte;
  777. pData->iJPEGbufremain2 = (mng_uint32)pData->pJPEGdinfo2->src->bytes_in_buffer;
  778. }
  779. /* decompress not started ? */
  780. if ((pData->bJPEGhasheader2) && (!pData->bJPEGdecostarted2))
  781. {
  782. /* set parameters for decompression */
  783. if (pData->bJPEGprogressive2) /* progressive display ? */
  784. pData->pJPEGdinfo2->buffered_image = TRUE;
  785. /* jpeg_start_decompress(...); */
  786. #ifdef MNG_SUPPORT_TRACE
  787. MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSDATA, MNG_LC_JPEG_START_DECOMPRESS)
  788. #endif
  789. if (jpeg_start_decompress (pData->pJPEGdinfo2) == TRUE)
  790. /* indicate it started */
  791. pData->bJPEGdecostarted2 = MNG_TRUE;
  792. pData->pJPEGcurrent2 = (mng_uint8p)pData->pJPEGdinfo2->src->next_input_byte;
  793. pData->iJPEGbufremain2 = (mng_uint32)pData->pJPEGdinfo2->src->bytes_in_buffer;
  794. }
  795. /* process some scanlines ? */
  796. if ((pData->bJPEGhasheader2) && (pData->bJPEGdecostarted2) &&
  797. ((!jpeg_input_complete (pData->pJPEGdinfo2)) ||
  798. (pData->pJPEGdinfo2->output_scanline < pData->pJPEGdinfo2->output_height)))
  799. {
  800. mng_int32 iLines;
  801. /* for (each output pass) */
  802. do
  803. { /* address the row output buffer */
  804. JSAMPROW pRow = (JSAMPROW)pData->pJPEGrow2;
  805. /* init new pass ? */
  806. if ((pData->bJPEGprogressive2) &&
  807. ((!pData->bJPEGscanstarted2) ||
  808. (pData->pJPEGdinfo2->output_scanline >= pData->pJPEGdinfo2->output_height)))
  809. {
  810. pData->bJPEGscanstarted2 = MNG_TRUE;
  811. /* adjust output decompression parameters if required */
  812. /* nop */
  813. /* start a new output pass */
  814. #ifdef MNG_SUPPORT_TRACE
  815. MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSDATA, MNG_LC_JPEG_START_OUTPUT)
  816. #endif
  817. jpeg_start_output (pData->pJPEGdinfo2, pData->pJPEGdinfo2->input_scan_number);
  818. pData->iJPEGrow = 0; /* start at row 0 in the image again */
  819. }
  820. /* while (scan lines remain to be read) */
  821. do
  822. {
  823. /* jpeg_read_scanlines(...); */
  824. #ifdef MNG_SUPPORT_TRACE
  825. MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSDATA, MNG_LC_JPEG_READ_SCANLINES)
  826. #endif
  827. iLines = jpeg_read_scanlines (pData->pJPEGdinfo2, (JSAMPARRAY)&pRow, 1);
  828. pData->pJPEGcurrent2 = (mng_uint8p)pData->pJPEGdinfo2->src->next_input_byte;
  829. pData->iJPEGbufremain2 = (mng_uint32)pData->pJPEGdinfo2->src->bytes_in_buffer;
  830. if (iLines > 0) /* got something ? */
  831. {
  832. if (pData->fStorerow3) /* store in object ? */
  833. {
  834. iRetcode = ((mng_storerow)pData->fStorerow3) (pData);
  835. if (iRetcode) /* on error bail out */
  836. return iRetcode;
  837. }
  838. }
  839. }
  840. while ((pData->pJPEGdinfo2->output_scanline < pData->pJPEGdinfo2->output_height) &&
  841. (iLines > 0)); /* until end-of-image or not enough input-data */
  842. /* terminate output pass */
  843. if ((pData->bJPEGprogressive2) &&
  844. (pData->pJPEGdinfo2->output_scanline >= pData->pJPEGdinfo2->output_height))
  845. {
  846. #ifdef MNG_SUPPORT_TRACE
  847. MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSDATA, MNG_LC_JPEG_FINISH_OUTPUT)
  848. #endif
  849. if (jpeg_finish_output (pData->pJPEGdinfo2) == JPEG_SUSPENDED)
  850. jpeg_finish_output (pData->pJPEGdinfo2);
  851. /* this scan has ended */
  852. pData->bJPEGscanstarted2 = MNG_FALSE;
  853. }
  854. }
  855. while ((!jpeg_input_complete (pData->pJPEGdinfo2)) && (iLines > 0));
  856. }
  857. /* end of image ? */
  858. if ((pData->bJPEGhasheader2) && (pData->bJPEGdecostarted2) &&
  859. (jpeg_input_complete (pData->pJPEGdinfo2)) &&
  860. (pData->pJPEGdinfo2->input_scan_number == pData->pJPEGdinfo2->output_scan_number))
  861. {
  862. /* jpeg_finish_decompress(...); */
  863. #ifdef MNG_SUPPORT_TRACE
  864. MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSDATA, MNG_LC_JPEG_FINISH_DECOMPRESS)
  865. #endif
  866. if (jpeg_finish_decompress (pData->pJPEGdinfo2) == TRUE)
  867. { /* indicate it's done */
  868. pData->bJPEGhasheader2 = MNG_FALSE;
  869. pData->bJPEGdecostarted2 = MNG_FALSE;
  870. pData->pJPEGcurrent2 = (mng_uint8p)pData->pJPEGdinfo2->src->next_input_byte;
  871. pData->iJPEGbufremain2 = (mng_uint32)pData->pJPEGdinfo2->src->bytes_in_buffer;
  872. /* remaining fluff is an error ! */
  873. if ((pData->iJPEGbufremain2 > 0) || (iRemain > 0))
  874. MNG_ERROR (pData, MNG_TOOMUCHJDAT);
  875. }
  876. }
  877. #endif /* MNG_INCLUDE_IJG6B */
  878. }
  879. #ifdef MNG_SUPPORT_TRACE
  880. MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSDATA, MNG_LC_END);
  881. #endif
  882. return MNG_NOERROR;
  883. }
  884. #endif /* MNG_INCLUDE_JNG_READ */
  885. /* ************************************************************************** */
  886. #ifdef MNG_INCLUDE_JNG_READ
  887. mng_retcode mngjpeg_decompressfree2 (mng_datap pData)
  888. {
  889. #if defined(MNG_INCLUDE_IJG6B) && defined(MNG_USE_SETJMP)
  890. mng_retcode iRetcode;
  891. #endif
  892. #ifdef MNG_SUPPORT_TRACE
  893. MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSFREE, MNG_LC_START);
  894. #endif
  895. #ifdef MNG_INCLUDE_IJG6B
  896. #ifdef MNG_USE_SETJMP
  897. iRetcode = setjmp (pData->sErrorbuf);/* setup local JPEG error-recovery */
  898. if (iRetcode != 0) /* got here from longjmp ? */
  899. MNG_ERRORJ (pData, iRetcode); /* then IJG-lib issued an error */
  900. #endif
  901. /* free the row of JPEG-samples*/
  902. MNG_FREE (pData, pData->pJPEGrow2, pData->iJPEGrowlen2);
  903. /* release the JPEG decompression object */
  904. #ifdef MNG_SUPPORT_TRACE
  905. MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSFREE, MNG_LC_JPEG_DESTROY_DECOMPRESS)
  906. #endif
  907. jpeg_destroy_decompress (pData->pJPEGdinfo2);
  908. pData->bJPEGdecompress2 = MNG_FALSE; /* indicate it's done */
  909. #endif /* MNG_INCLUDE_IJG6B */
  910. #ifdef MNG_SUPPORT_TRACE
  911. MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSFREE, MNG_LC_END);
  912. #endif
  913. return MNG_NOERROR;
  914. }
  915. #endif /* MNG_INCLUDE_JNG_READ */
  916. /* ************************************************************************** */
  917. #endif /* MNG_INCLUDE_JNG && MNG_INCLUDE_DISPLAY_PROCS */
  918. /* ************************************************************************** */
  919. /* * end of file * */
  920. /* ************************************************************************** */