PageRenderTime 108ms CodeModel.GetById 19ms app.highlight 80ms RepoModel.GetById 1ms app.codeStats 0ms

/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
  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
  89void MNG_DECL mng_init_source (j_decompress_ptr cinfo)
  90#else
  91void 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
 102boolean MNG_DECL mng_fill_input_buffer (j_decompress_ptr cinfo)
 103#else
 104boolean 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
 115void MNG_DECL mng_skip_input_data (j_decompress_ptr cinfo, long num_bytes)
 116#else
 117void 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
 148void MNG_DECL mng_skip_input_data2 (j_decompress_ptr cinfo, long num_bytes)
 149#else
 150void 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
 181void MNG_DECL mng_term_source (j_decompress_ptr cinfo)
 182#else
 183void 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
 194void MNG_DECL mng_error_exit (j_common_ptr cinfo)
 195#else
 196void 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
 213void MNG_DECL mng_output_message (j_common_ptr cinfo)
 214#else
 215void 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
 232mng_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
 318mng_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
 397mng_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
 454mng_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
 707mng_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
 751mng_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
 808mng_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
1044mng_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