src/3rdparty/libmng/libmng_jpeg.c
changeset 0 1918ee327afb
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     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
       
    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
       
   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
       
   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
       
   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
       
   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
       
   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
       
   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 
       
   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 
       
   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
       
   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
       
   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
       
   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
       
   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
       
   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
       
  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