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