~ubuntu-branches/ubuntu/oneiric/libmng/oneiric

1 by Luis Arocha
New Maintainer (closes: #127702).
1
/* ************************************************************************** */
2
/* *             For conditions of distribution and use,                    * */
3
/* *                see copyright notice in libmng.h                        * */
4
/* ************************************************************************** */
5
/* *                                                                        * */
6
/* * project   : libmng                                                     * */
7
/* * file      : libmng_display.c          copyright (c) 2000 G.Juyn        * */
8
/* * version   : 1.0.2                                                      * */
9
/* *                                                                        * */
10
/* * purpose   : Display management (implementation)                        * */
11
/* *                                                                        * */
12
/* * author    : G.Juyn                                                     * */
13
/* * web       : http://www.3-t.com                                         * */
14
/* * email     : mailto:info@3-t.com                                        * */
15
/* *                                                                        * */
16
/* * comment   : implementation of the display management routines          * */
17
/* *                                                                        * */
18
/* * changes   : 0.5.1 - 05/08/2000 - G.Juyn                                * */
19
/* *             - changed strict-ANSI stuff                                * */
20
/* *             0.5.1 - 05/11/2000 - G.Juyn                                * */
21
/* *             - added callback error-reporting support                   * */
22
/* *             - fixed frame_delay misalignment                           * */
23
/* *             0.5.1 - 05/12/2000 - G.Juyn                                * */
24
/* *             - added sanity check for frozen status                     * */
25
/* *             - changed trace to macro for callback error-reporting      * */
26
/* *             0.5.1 - 05/13/2000 - G.Juyn                                * */
27
/* *             - changed display_mend to reset state to initial or SAVE   * */
28
/* *             - added eMNGma hack (will be removed in 1.0.0 !!!)         * */
29
/* *             - added TERM animation object pointer (easier reference)   * */
30
/* *             - added process_save & process_seek routines               * */
31
/* *             0.5.1 - 05/14/2000 - G.Juyn                                * */
32
/* *             - added save_state and restore_state for SAVE/SEEK/TERM    * */
33
/* *               processing                                               * */
34
/* *                                                                        * */
35
/* *             0.5.2 - 05/20/2000 - G.Juyn                                * */
36
/* *             - added JNG support (JHDR/JDAT)                            * */
37
/* *             0.5.2 - 05/23/2000 - G.Juyn                                * */
38
/* *             - fixed problem with DEFI clipping                         * */
39
/* *             0.5.2 - 05/30/2000 - G.Juyn                                * */
40
/* *             - added delta-image support (DHDR,PROM,IPNG,IJNG)          * */
41
/* *             0.5.2 - 05/31/2000 - G.Juyn                                * */
42
/* *             - fixed pointer confusion (contributed by Tim Rowley)      * */
43
/* *             0.5.2 - 06/03/2000 - G.Juyn                                * */
44
/* *             - fixed makeup for Linux gcc compile                       * */
45
/* *             0.5.2 - 06/05/2000 - G.Juyn                                * */
46
/* *             - added support for RGB8_A8 canvasstyle                    * */
47
/* *             0.5.2 - 06/09/2000 - G.Juyn                                * */
48
/* *             - fixed timer-handling to run with Mozilla (Tim Rowley)    * */
49
/* *             0.5.2 - 06/10/2000 - G.Juyn                                * */
50
/* *             - fixed some compilation-warnings (contrib Jason Morris)   * */
51
/* *                                                                        * */
52
/* *             0.5.3 - 06/12/2000 - G.Juyn                                * */
53
/* *             - fixed display of stored JNG images                       * */
54
/* *             0.5.3 - 06/13/2000 - G.Juyn                                * */
55
/* *             - fixed problem with BASI-IEND as object 0                 * */
56
/* *             0.5.3 - 06/16/2000 - G.Juyn                                * */
57
/* *             - changed progressive-display processing                   * */
58
/* *             0.5.3 - 06/17/2000 - G.Juyn                                * */
59
/* *             - changed delta-image processing                           * */
60
/* *             0.5.3 - 06/20/2000 - G.Juyn                                * */
61
/* *             - fixed some minor stuff                                   * */
62
/* *             0.5.3 - 06/21/2000 - G.Juyn                                * */
63
/* *             - added speed-modifier to timing routine                   * */
64
/* *             0.5.3 - 06/22/2000 - G.Juyn                                * */
65
/* *             - added support for PPLT chunk processing                  * */
66
/* *             0.5.3 - 06/29/2000 - G.Juyn                                * */
67
/* *             - swapped refresh parameters                               * */
68
/* *                                                                        * */
69
/* *             0.9.0 - 06/30/2000 - G.Juyn                                * */
70
/* *             - changed refresh parameters to 'x,y,width,height'         * */
71
/* *                                                                        * */
72
/* *             0.9.1 - 07/07/2000 - G.Juyn                                * */
73
/* *             - implemented support for freeze/reset/resume & go_xxxx    * */
74
/* *             0.9.1 - 07/08/2000 - G.Juyn                                * */
75
/* *             - added support for improved timing                        * */
76
/* *             0.9.1 - 07/14/2000 - G.Juyn                                * */
77
/* *             - changed EOF processing behavior                          * */
78
/* *             - fixed TERM delay processing                              * */
79
/* *             0.9.1 - 07/15/2000 - G.Juyn                                * */
80
/* *             - fixed freeze & reset processing                          * */
81
/* *             0.9.1 - 07/16/2000 - G.Juyn                                * */
82
/* *             - fixed storage of images during mng_read()                * */
83
/* *             - fixed support for mng_display() after mng_read()         * */
84
/* *             0.9.1 - 07/24/2000 - G.Juyn                                * */
85
/* *             - fixed reading of still-images                            * */
86
/* *                                                                        * */
87
/* *             0.9.2 - 08/05/2000 - G.Juyn                                * */
88
/* *             - changed file-prefixes                                    * */
89
/* *                                                                        * */
90
/* *             0.9.3 - 08/07/2000 - G.Juyn                                * */
91
/* *             - B111300 - fixup for improved portability                 * */
92
/* *             0.9.3 - 08/21/2000 - G.Juyn                                * */
93
/* *             - fixed TERM processing delay of 0 msecs                   * */
94
/* *             0.9.3 - 08/26/2000 - G.Juyn                                * */
95
/* *             - added MAGN chunk                                         * */
96
/* *             0.9.3 - 09/10/2000 - G.Juyn                                * */
97
/* *             - fixed problem with no refresh after TERM                 * */
98
/* *             - fixed DEFI behavior                                      * */
99
/* *             0.9.3 - 09/16/2000 - G.Juyn                                * */
100
/* *             - fixed timing & refresh behavior for single PNG/JNG       * */
101
/* *             0.9.3 - 09/19/2000 - G.Juyn                                * */
102
/* *             - refixed timing & refresh behavior for single PNG/JNG     * */
103
/* *             0.9.3 - 10/02/2000 - G.Juyn                                * */
104
/* *             - fixed timing again (this is getting boring...)           * */
105
/* *             - refixed problem with no refresh after TERM               * */
106
/* *             0.9.3 - 10/16/2000 - G.Juyn                                * */
107
/* *             - added JDAA chunk                                         * */
108
/* *             0.9.3 - 10/17/2000 - G.Juyn                                * */
109
/* *             - fixed support for bKGD                                   * */
110
/* *             0.9.3 - 10/18/2000 - G.Juyn                                * */
111
/* *             - fixed delta-processing behavior                          * */
112
/* *             0.9.3 - 10/19/2000 - G.Juyn                                * */
113
/* *             - added storage for pixel-/alpha-sampledepth for delta's   * */
114
/* *             0.9.3 - 10/27/2000 - G.Juyn                                * */
115
/* *             - fixed seperate read() & display() processing             * */
116
/* *                                                                        * */
117
/* *             0.9.4 - 10/31/2000 - G.Juyn                                * */
118
/* *             - fixed possible loop in display_resume() (Thanks Vova!)   * */
119
/* *             0.9.4 - 11/20/2000 - G.Juyn                                * */
120
/* *             - fixed unwanted repetition in mng_readdisplay()           * */
121
/* *             0.9.4 - 11/24/2000 - G.Juyn                                * */
122
/* *             - moved restore of object 0 to libmng_display              * */
123
/* *             - added restore of object 0 to TERM processing !!!         * */
124
/* *             - fixed TERM delay processing                              * */
125
/* *             - fixed TERM end processing (count = 0)                    * */
126
/* *             0.9.4 - 12/16/2000 - G.Juyn                                * */
127
/* *             - fixed mixup of data- & function-pointers (thanks Dimitri)* */
128
/* *             0.9.4 -  1/18/2001 - G.Juyn                                * */
129
/* *             - removed test filter-methods 1 & 65                       * */
130
/* *             - set default level-set for filtertype=64 to all zeroes    * */
131
/* *                                                                        * */
132
/* *             0.9.5 -  1/20/2001 - G.Juyn                                * */
133
/* *             - fixed compiler-warnings Mozilla (thanks Tim)             * */
134
/* *             0.9.5 -  1/23/2001 - G.Juyn                                * */
135
/* *             - fixed timing-problem with switching framing_modes        * */
136
/* *                                                                        * */
137
/* *             1.0.1 - 02/08/2001 - G.Juyn                                * */
138
/* *             - added MEND processing callback                           * */
139
/* *             1.0.1 - 02/13/2001 - G.Juyn                                * */
140
/* *             - fixed first FRAM_MODE=4 timing problem                   * */
141
/* *             1.0.1 - 04/21/2001 - G.Juyn                                * */
142
/* *             - fixed memory-leak for JNGs with alpha (Thanks Gregg!)    * */
143
/* *             - added BGRA8 canvas with premultiplied alpha              * */
144
/* *                                                                        * */
145
/* *             1.0.2 - 06/25/2001 - G.Juyn                                * */
146
/* *             - fixed memory-leak with delta-images (Thanks Michael!)    * */
147
/* *                                                                        * */
148
/* ************************************************************************** */
149
150
#include "libmng.h"
151
#include "libmng_data.h"
152
#include "libmng_error.h"
153
#include "libmng_trace.h"
154
#ifdef __BORLANDC__
155
#pragma hdrstop
156
#endif
157
#include "libmng_objects.h"
158
#include "libmng_object_prc.h"
159
#include "libmng_memory.h"
160
#include "libmng_zlib.h"
161
#include "libmng_jpeg.h"
162
#include "libmng_cms.h"
163
#include "libmng_pixels.h"
164
#include "libmng_display.h"
165
166
#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
167
#pragma option -A                      /* force ANSI-C */
168
#endif
169
170
/* ************************************************************************** */
171
172
#ifdef MNG_INCLUDE_DISPLAY_PROCS
173
174
/* ************************************************************************** */
175
176
mng_retcode set_delay (mng_datap  pData,
177
                       mng_uint32 iInterval)
178
{
179
  if (!iInterval)                      /* at least 1 msec please! */
180
    iInterval = 1;
181
182
  if (!pData->fSettimer ((mng_handle)pData, iInterval))
183
    MNG_ERROR (pData, MNG_APPTIMERERROR)
184
185
  pData->bTimerset = MNG_TRUE;         /* and indicate so */
186
187
  return MNG_NOERROR;
188
}
189
190
/* ************************************************************************** */
191
/* *                                                                        * */
192
/* * Progressive display refresh - does the call to the refresh callback    * */
193
/* * and sets the timer to allow the app to perform the actual refresh to   * */
194
/* * the screen (eg. process its main message-loop)                         * */
195
/* *                                                                        * */
196
/* ************************************************************************** */
197
198
mng_retcode display_progressive_refresh (mng_datap  pData,
199
                                         mng_uint32 iInterval)
200
{
201
  if (!pData->bSearching)              /* we mustn't be searching !!! */
202
  {
203
    if ((pData->bRunning) &&           /* let the app refresh first ? */
204
        (pData->iUpdatetop < pData->iUpdatebottom) && (pData->iUpdateleft < pData->iUpdateright))
205
    {
206
      if (!pData->fRefresh (((mng_handle)pData),
207
                            pData->iUpdateleft, pData->iUpdatetop,
208
                            pData->iUpdateright  - pData->iUpdateleft,
209
                            pData->iUpdatebottom - pData->iUpdatetop))
210
        MNG_ERROR (pData, MNG_APPMISCERROR)
211
212
      pData->iUpdateleft   = 0;        /* reset update-region */
213
      pData->iUpdateright  = 0;
214
      pData->iUpdatetop    = 0;
215
      pData->iUpdatebottom = 0;        /* reset refreshneeded indicator */
216
      pData->bNeedrefresh  = MNG_FALSE;
217
                                       /* interval requested ? */
218
      if ((!pData->bFreezing) && (iInterval))
219
      {                                /* setup the timer */
220
        mng_retcode iRetcode = set_delay (pData, iInterval);
221
222
        if (iRetcode)                  /* on error bail out */
223
          return iRetcode;
224
      }
225
    }
226
  }
227
228
  return MNG_NOERROR;
229
}
230
231
/* ************************************************************************** */
232
/* *                                                                        * */
233
/* * Generic display routines                                               * */
234
/* *                                                                        * */
235
/* ************************************************************************** */
236
237
mng_retcode interframe_delay (mng_datap pData)
238
{
239
  mng_uint32  iWaitfor = 0;
240
  mng_uint32  iInterval;
241
  mng_uint32  iRuninterval;
242
  mng_retcode iRetcode;
243
244
#ifdef MNG_SUPPORT_TRACE
245
  MNG_TRACE (pData, MNG_FN_INTERFRAME_DELAY, MNG_LC_START)
246
#endif
247
248
  if (!pData->bSearching)              /* we mustn't be searching !!! */
249
  {                                    
250
    if (pData->iFramedelay > 0)        /* real delay ? */
251
    {
252
      if ((pData->bRunning) &&         /* let the app refresh first ? */
253
          (pData->iUpdatetop < pData->iUpdatebottom) && (pData->iUpdateleft < pData->iUpdateright))
254
        if (!pData->fRefresh (((mng_handle)pData),
255
                              pData->iUpdateleft,  pData->iUpdatetop,
256
                              pData->iUpdateright - pData->iUpdateleft,
257
                              pData->iUpdatebottom - pData->iUpdatetop))
258
          MNG_ERROR (pData, MNG_APPMISCERROR)
259
260
      pData->iUpdateleft   = 0;        /* reset update-region */
261
      pData->iUpdateright  = 0;
262
      pData->iUpdatetop    = 0;
263
      pData->iUpdatebottom = 0;        /* reset refreshneeded indicator */
264
      pData->bNeedrefresh  = MNG_FALSE;
265
                                       /* get current tickcount */
266
      pData->iRuntime = pData->fGettickcount ((mng_handle)pData);
267
                                       /* calculate interval since last sync-point */
268
      if (pData->iRuntime < pData->iSynctime)
269
        iRuninterval    = pData->iRuntime + ~pData->iSynctime + 1;
270
      else
271
        iRuninterval    = pData->iRuntime - pData->iSynctime;
272
                                       /* calculate actual run-time */
273
      if (pData->iRuntime < pData->iStarttime)
274
        pData->iRuntime = pData->iRuntime + ~pData->iStarttime + 1;
275
      else
276
        pData->iRuntime = pData->iRuntime - pData->iStarttime;
277
278
      if (pData->iTicks)               /* what are we aiming for */
279
      {
280
        switch (pData->iSpeed)         /* honor speed modifier */
281
        {
282
          case mng_st_fast :
283
            {
284
              iWaitfor = (mng_uint32)(( 500 * pData->iFramedelay) / pData->iTicks);
285
              break;
286
            }
287
          case mng_st_slow :
288
            {
289
              iWaitfor = (mng_uint32)((3000 * pData->iFramedelay) / pData->iTicks);
290
              break;
291
            }
292
          case mng_st_slowest :
293
            {
294
              iWaitfor = (mng_uint32)((8000 * pData->iFramedelay) / pData->iTicks);
295
              break;
296
            }
297
          default :
298
            {
299
              iWaitfor = (mng_uint32)((1000 * pData->iFramedelay) / pData->iTicks);
300
            }
301
        }
302
      }
303
      else
304
      {
305
        if (pData->eImagetype == mng_it_mng)
306
          iWaitfor = 1000;
307
        else
308
          iWaitfor = 1;
309
      }
310
311
      if (iWaitfor > iRuninterval)     /* delay necessary ? */
312
        iInterval = iWaitfor - iRuninterval;
313
      else
314
        iInterval = 1;                 /* force app to process messageloop */
315
316
      if (pData->bRunning)             /* set the timer ? */
317
      {
318
        iRetcode = set_delay (pData, iInterval);
319
320
        if (iRetcode)                  /* on error bail out */
321
          return iRetcode;
322
      }
323
    }
324
325
    if (pData->bRunning)               /* increase frametime in advance */
326
      pData->iFrametime = pData->iFrametime + iWaitfor;
327
                                       /* setup for next delay */
328
    pData->iFramedelay = pData->iNextdelay;
329
  }
330
331
#ifdef MNG_SUPPORT_TRACE
332
  MNG_TRACE (pData, MNG_FN_INTERFRAME_DELAY, MNG_LC_END)
333
#endif
334
335
  return MNG_NOERROR;
336
}
337
338
/* ************************************************************************** */
339
340
void set_display_routine (mng_datap pData)
341
{                                        /* actively running ? */
342
  if ((pData->bRunning) && (!pData->bFreezing))
343
  {
344
    switch (pData->iCanvasstyle)         /* determine display routine */
345
    {
346
      case MNG_CANVAS_RGB8    : { pData->fDisplayrow = (mng_fptr)display_rgb8;     break; }
347
      case MNG_CANVAS_RGBA8   : { pData->fDisplayrow = (mng_fptr)display_rgba8;    break; }
348
      case MNG_CANVAS_ARGB8   : { pData->fDisplayrow = (mng_fptr)display_argb8;    break; }
349
      case MNG_CANVAS_RGB8_A8 : { pData->fDisplayrow = (mng_fptr)display_rgb8_a8;  break; }
350
      case MNG_CANVAS_BGR8    : { pData->fDisplayrow = (mng_fptr)display_bgr8;     break; }
351
      case MNG_CANVAS_BGRA8   : { pData->fDisplayrow = (mng_fptr)display_bgra8;    break; }
352
      case MNG_CANVAS_BGRA8PM : { pData->fDisplayrow = (mng_fptr)display_bgra8_pm; break; }
353
      case MNG_CANVAS_ABGR8   : { pData->fDisplayrow = (mng_fptr)display_abgr8;    break; }
354
/*      case MNG_CANVAS_RGB16   : { pData->fDisplayrow = (mng_fptr)display_rgb16;    break; } */
355
/*      case MNG_CANVAS_RGBA16  : { pData->fDisplayrow = (mng_fptr)display_rgba16;   break; } */
356
/*      case MNG_CANVAS_ARGB16  : { pData->fDisplayrow = (mng_fptr)display_argb16;   break; } */
357
/*      case MNG_CANVAS_BGR16   : { pData->fDisplayrow = (mng_fptr)display_bgr16;    break; } */
358
/*      case MNG_CANVAS_BGRA16  : { pData->fDisplayrow = (mng_fptr)display_bgra16;   break; } */
359
/*      case MNG_CANVAS_ABGR16  : { pData->fDisplayrow = (mng_fptr)display_abgr16;   break; } */
360
/*      case MNG_CANVAS_INDEX8  : { pData->fDisplayrow = (mng_fptr)display_index8;   break; } */
361
/*      case MNG_CANVAS_INDEXA8 : { pData->fDisplayrow = (mng_fptr)display_indexa8;  break; } */
362
/*      case MNG_CANVAS_AINDEX8 : { pData->fDisplayrow = (mng_fptr)display_aindex8;  break; } */
363
/*      case MNG_CANVAS_GRAY8   : { pData->fDisplayrow = (mng_fptr)display_gray8;    break; } */
364
/*      case MNG_CANVAS_GRAY16  : { pData->fDisplayrow = (mng_fptr)display_gray16;   break; } */
365
/*      case MNG_CANVAS_GRAYA8  : { pData->fDisplayrow = (mng_fptr)display_graya8;   break; } */
366
/*      case MNG_CANVAS_GRAYA16 : { pData->fDisplayrow = (mng_fptr)display_graya16;  break; } */
367
/*      case MNG_CANVAS_AGRAY8  : { pData->fDisplayrow = (mng_fptr)display_agray8;   break; } */
368
/*      case MNG_CANVAS_AGRAY16 : { pData->fDisplayrow = (mng_fptr)display_agray16;  break; } */
369
/*      case MNG_CANVAS_DX15    : { pData->fDisplayrow = (mng_fptr)display_dx15;     break; } */
370
/*      case MNG_CANVAS_DX16    : { pData->fDisplayrow = (mng_fptr)display_dx16;     break; } */
371
    }
372
  }
373
374
  return;
375
}
376
377
/* ************************************************************************** */
378
379
mng_retcode load_bkgdlayer (mng_datap pData)
380
{
381
#ifdef MNG_SUPPORT_TRACE
382
  MNG_TRACE (pData, MNG_FN_LOAD_BKGDLAYER, MNG_LC_START)
383
#endif
384
                                       /* actively running ? */
385
  if ((pData->bRunning) && (!pData->bFreezing))
386
  {
387
    mng_int32   iY;
388
    mng_retcode iRetcode;              /* save values */
389
    mng_int32   iDestl      = pData->iDestl;
390
    mng_int32   iDestr      = pData->iDestr;
391
    mng_int32   iDestt      = pData->iDestt;
392
    mng_int32   iDestb      = pData->iDestb;
393
    mng_int32   iSourcel    = pData->iSourcel;
394
    mng_int32   iSourcer    = pData->iSourcer;
395
    mng_int32   iSourcet    = pData->iSourcet;
396
    mng_int32   iSourceb    = pData->iSourceb;
397
    mng_int8    iPass       = pData->iPass;
398
    mng_int32   iRow        = pData->iRow;
399
    mng_int32   iRowinc     = pData->iRowinc;
400
    mng_int32   iCol        = pData->iCol;
401
    mng_int32   iColinc     = pData->iColinc;
402
    mng_int32   iRowsamples = pData->iRowsamples;
403
    mng_int32   iRowsize    = pData->iRowsize;
404
    mng_bool    bIsRGBA16   = pData->bIsRGBA16;
405
    mng_bool    bIsOpaque   = pData->bIsOpaque;
406
    mng_fptr    fCorrectrow = pData->fCorrectrow;
407
408
    pData->iDestl   = 0;               /* determine clipping region */
409
    pData->iDestt   = 0;
410
    pData->iDestr   = pData->iWidth;
411
    pData->iDestb   = pData->iHeight;
412
413
    if (pData->bFrameclipping)         /* frame clipping specified ? */
414
    {
415
      pData->iDestl = MAX_COORD (pData->iDestl,  pData->iFrameclipl);
416
      pData->iDestt = MAX_COORD (pData->iDestt,  pData->iFrameclipt);
417
      pData->iDestr = MIN_COORD (pData->iDestr,  pData->iFrameclipr);
418
      pData->iDestb = MIN_COORD (pData->iDestb,  pData->iFrameclipb);
419
    }
420
                                       /* anything to clear ? */
421
    if ((pData->iDestr >= pData->iDestl) && (pData->iDestb >= pData->iDestt))
422
    {
423
      pData->iPass       = -1;         /* these are the object's dimensions now */
424
      pData->iRow        = 0;
425
      pData->iRowinc     = 1;
426
      pData->iCol        = 0;
427
      pData->iColinc     = 1;
428
      pData->iRowsamples = pData->iWidth;
429
      pData->iRowsize    = pData->iRowsamples << 2;
430
      pData->bIsRGBA16   = MNG_FALSE;    /* let's keep it simple ! */
431
      pData->bIsOpaque   = MNG_TRUE;
432
433
      pData->iSourcel    = 0;          /* source relative to destination */
434
      pData->iSourcer    = pData->iDestr - pData->iDestl;
435
      pData->iSourcet    = 0;
436
      pData->iSourceb    = pData->iDestb - pData->iDestt;
437
438
      set_display_routine (pData);     /* determine display routine */
439
                                       /* default restore using preset BG color */
440
      pData->fRestbkgdrow = (mng_fptr)restore_bkgd_bgcolor;
441
442
      if (((pData->eImagetype == mng_it_png) || (pData->eImagetype == mng_it_jng)) &&
443
          (pData->bUseBKGD))
444
      {                                /* prefer bKGD in PNG/JNG */
445
        mng_imagep pImage = (mng_imagep)pData->pCurrentobj;
446
447
        if (!pImage)
448
          pImage = (mng_imagep)pData->pObjzero;
449
450
        if (pImage->pImgbuf->bHasBKGD)
451
          pData->fRestbkgdrow = (mng_fptr)restore_bkgd_bkgd;
452
      }
453
454
      if (pData->fGetbkgdline)         /* background-canvas-access callback set ? */
455
      {
456
        switch (pData->iBkgdstyle)
457
        {
458
          case MNG_CANVAS_RGB8    : { pData->fRestbkgdrow = (mng_fptr)restore_bkgd_rgb8;    break; }
459
          case MNG_CANVAS_BGR8    : { pData->fRestbkgdrow = (mng_fptr)restore_bkgd_bgr8;    break; }
460
  /*        case MNG_CANVAS_RGB16   : { pData->fRestbkgdrow = (mng_fptr)restore_bkgd_rgb16;   break; } */
461
  /*        case MNG_CANVAS_BGR16   : { pData->fRestbkgdrow = (mng_fptr)restore_bkgd_bgr16;   break; } */
462
  /*        case MNG_CANVAS_INDEX8  : { pData->fRestbkgdrow = (mng_fptr)restore_bkgd_index8;  break; } */
463
  /*        case MNG_CANVAS_GRAY8   : { pData->fRestbkgdrow = (mng_fptr)restore_bkgd_gray8;   break; } */
464
  /*        case MNG_CANVAS_GRAY16  : { pData->fRestbkgdrow = (mng_fptr)restore_bkgd_gray16;  break; } */
465
  /*        case MNG_CANVAS_DX15    : { pData->fRestbkgdrow = (mng_fptr)restore_bkgd_dx15;    break; } */
466
  /*        case MNG_CANVAS_DX16    : { pData->fRestbkgdrow = (mng_fptr)restore_bkgd_dx16;    break; } */
467
        }
468
      }
469
470
      if (pData->bHasBACK)
471
      {                                /* background image ? */
472
        if ((pData->iBACKmandatory & 0x02) && (pData->iBACKimageid))
473
          pData->fRestbkgdrow = (mng_fptr)restore_bkgd_backimage;
474
        else                           /* background color ? */
475
        if (pData->iBACKmandatory & 0x01)
476
          pData->fRestbkgdrow = (mng_fptr)restore_bkgd_backcolor;
477
478
      }
479
480
      pData->fCorrectrow = MNG_NULL;   /* default no color-correction */
481
482
483
      /* TODO: determine color correction; this is tricky;
484
         the BACK color is treated differently as the image;
485
         it probably requires a rewrite of the logic here... */
486
487
488
                                       /* get a temporary row-buffer */
489
      MNG_ALLOC (pData, pData->pRGBArow, pData->iRowsize)
490
491
      iY       = pData->iDestt;        /* this is where we start */
492
      iRetcode = MNG_NOERROR;          /* so far, so good */
493
494
      while ((!iRetcode) && (iY < pData->iDestb))
495
      {                                /* restore a background row */
496
        iRetcode = ((mng_restbkgdrow)pData->fRestbkgdrow) (pData);
497
                                       /* color correction ? */
498
        if ((!iRetcode) && (pData->fCorrectrow))
499
          iRetcode = ((mng_correctrow)pData->fCorrectrow) (pData);
500
501
        if (!iRetcode)                 /* so... display it */
502
          iRetcode = ((mng_displayrow)pData->fDisplayrow) (pData);
503
504
        if (!iRetcode)
505
          iRetcode = next_row (pData); /* adjust variables for next row */
506
507
        iY++;                          /* and next line */
508
      }
509
                                       /* drop the temporary row-buffer */
510
      MNG_FREE (pData, pData->pRGBArow, pData->iRowsize)
511
512
      if (iRetcode)                    /* on error bail out */
513
        return iRetcode;
514
515
    }
516
517
    pData->iDestl      = iDestl;       /* restore values */
518
    pData->iDestr      = iDestr;
519
    pData->iDestt      = iDestt;
520
    pData->iDestb      = iDestb;
521
    pData->iSourcel    = iSourcel;
522
    pData->iSourcer    = iSourcer;
523
    pData->iSourcet    = iSourcet;
524
    pData->iSourceb    = iSourceb;
525
    pData->iPass       = iPass;
526
    pData->iRow        = iRow;
527
    pData->iRowinc     = iRowinc;
528
    pData->iCol        = iCol;
529
    pData->iColinc     = iColinc;
530
    pData->iRowsamples = iRowsamples;
531
    pData->iRowsize    = iRowsize;
532
    pData->bIsRGBA16   = bIsRGBA16;
533
    pData->bIsOpaque   = bIsOpaque;
534
    pData->fCorrectrow = fCorrectrow;
535
  }
536
537
#ifdef MNG_SUPPORT_TRACE
538
  MNG_TRACE (pData, MNG_FN_LOAD_BKGDLAYER, MNG_LC_END)
539
#endif
540
541
  return MNG_NOERROR;
542
}
543
544
/* ************************************************************************** */
545
546
mng_retcode clear_canvas (mng_datap pData)
547
{
548
  mng_int32   iY;
549
  mng_retcode iRetcode;
550
551
#ifdef MNG_SUPPORT_TRACE
552
  MNG_TRACE (pData, MNG_FN_CLEAR_CANVAS, MNG_LC_START)
553
#endif
554
555
  pData->iDestl      = 0;              /* clipping region is full canvas! */
556
  pData->iDestt      = 0;
557
  pData->iDestr      = pData->iWidth;
558
  pData->iDestb      = pData->iHeight;
559
560
  pData->iSourcel    = 0;              /* source is same as destination */
561
  pData->iSourcer    = pData->iWidth;
562
  pData->iSourcet    = 0;
563
  pData->iSourceb    = pData->iHeight;
564
565
  pData->iPass       = -1;             /* these are the object's dimensions now */
566
  pData->iRow        = 0;
567
  pData->iRowinc     = 1;
568
  pData->iCol        = 0;
569
  pData->iColinc     = 1;
570
  pData->iRowsamples = pData->iWidth;
571
  pData->iRowsize    = pData->iRowsamples << 2;
572
  pData->bIsRGBA16   = MNG_FALSE;      /* let's keep it simple ! */
573
  pData->bIsOpaque   = MNG_TRUE;
574
575
  set_display_routine (pData);         /* determine display routine */
576
                                       /* get a temporary row-buffer */
577
                                       /* it's transparent black by default!! */
578
  MNG_ALLOC (pData, pData->pRGBArow, pData->iRowsize)
579
580
  iY       = pData->iDestt;            /* this is where we start */
581
  iRetcode = MNG_NOERROR;              /* so far, so good */
582
583
  while ((!iRetcode) && (iY < pData->iDestb))
584
  {                                    /* clear a row then */
585
    iRetcode = ((mng_displayrow)pData->fDisplayrow) (pData);
586
587
    if (!iRetcode)
588
      iRetcode = next_row (pData);     /* adjust variables for next row */
589
590
    iY++;                              /* and next line */
591
  }
592
                                       /* drop the temporary row-buffer */
593
  MNG_FREE (pData, pData->pRGBArow, pData->iRowsize)
594
595
  if (iRetcode)                        /* on error bail out */
596
    return iRetcode;
597
598
#ifdef MNG_SUPPORT_TRACE
599
  MNG_TRACE (pData, MNG_FN_CLEAR_CANVAS, MNG_LC_END)
600
#endif
601
602
  return MNG_NOERROR;
603
}
604
605
/* ************************************************************************** */
606
607
mng_retcode next_frame (mng_datap  pData,
608
                        mng_uint8  iFramemode,
609
                        mng_uint8  iChangedelay,
610
                        mng_uint32 iDelay,
611
                        mng_uint8  iChangetimeout,
612
                        mng_uint32 iTimeout,
613
                        mng_uint8  iChangeclipping,
614
                        mng_uint8  iCliptype,
615
                        mng_int32  iClipl,
616
                        mng_int32  iClipr,
617
                        mng_int32  iClipt,
618
                        mng_int32  iClipb)
619
{
620
  mng_retcode iRetcode = MNG_NOERROR;
621
622
#ifdef MNG_SUPPORT_TRACE
623
  MNG_TRACE (pData, MNG_FN_NEXT_FRAME, MNG_LC_START)
624
#endif
625
626
  if (!pData->iBreakpoint)             /* no previous break here ? */
627
  {
628
    mng_uint8 iOldmode = pData->iFramemode;
629
                                       /* interframe delay required ? */
630
    if ((iOldmode == 2) || (iOldmode == 4))
631
    {
632
/* changed here because FRAM 1/3 will delay themselves before each image */
633
      if ((pData->iFrameseq) && (iFramemode != 1) && (iFramemode != 3))
634
        iRetcode = interframe_delay (pData);
635
      else
636
        pData->iFramedelay = pData->iNextdelay;
637
    }
638
    else
639
    {                                  /* delay before inserting background layer? */
640
      if ((pData->bFramedone) && (iFramemode == 4))
641
        iRetcode = interframe_delay (pData);
642
    }
643
644
    if (iRetcode)                      /* on error bail out */
645
      return iRetcode;
646
                                       /* now we'll assume we're in the next frame! */
647
    if (iFramemode)                    /* save the new framing mode ? */
648
    {
649
      pData->iFRAMmode  = iFramemode;
650
      pData->iFramemode = iFramemode;
651
    }
652
    else                               /* reload default */
653
      pData->iFramemode = pData->iFRAMmode;
654
655
    if (iChangedelay)                  /* delay changed ? */
656
    {
657
      pData->iNextdelay = iDelay;      /* for *after* next subframe */
658
659
      if ((iOldmode == 2) || (iOldmode == 4))
660
/*        pData->iFramedelay = iDelay; */
661
        pData->iFramedelay = pData->iFRAMdelay;
662
663
      if (iChangedelay == 2)           /* also overall ? */
664
        pData->iFRAMdelay = iDelay;
665
    }
666
    else
667
    {                                  /* reload default */
668
      pData->iNextdelay = pData->iFRAMdelay;
669
670
/*      if ((iOldmode == 2) || (iOldmode == 4))
671
        pData->iFramedelay = pData->iNextdelay; */
672
    }
673
674
    if (iChangetimeout)                /* timeout changed ? */
675
    {                                  /* for next subframe */
676
      pData->iFrametimeout = iTimeout;
677
678
      if ((iChangetimeout == 2) ||     /* also overall ? */
679
          (iChangetimeout == 4) ||
680
          (iChangetimeout == 6) ||
681
          (iChangetimeout == 8))
682
        pData->iFRAMtimeout = iTimeout;
683
    }
684
    else                               /* reload default */
685
      pData->iFrametimeout = pData->iFRAMtimeout;
686
687
    if (iChangeclipping)               /* clipping changed ? */
688
    {
689
      pData->bFrameclipping = MNG_TRUE;
690
691
      if (!iCliptype)                  /* absolute ? */
692
      {
693
        pData->iFrameclipl = iClipl;
694
        pData->iFrameclipr = iClipr;
695
        pData->iFrameclipt = iClipt;
696
        pData->iFrameclipb = iClipb;
697
      }
698
      else                             /* relative */
699
      {
700
        pData->iFrameclipl = pData->iFrameclipl + iClipl;
701
        pData->iFrameclipr = pData->iFrameclipr + iClipr;
702
        pData->iFrameclipt = pData->iFrameclipt + iClipt;
703
        pData->iFrameclipb = pData->iFrameclipb + iClipb;
704
      }
705
706
      if (iChangeclipping == 2)        /* also overall ? */
707
      {
708
        pData->bFRAMclipping = MNG_TRUE;
709
710
        if (!iCliptype)                /* absolute ? */
711
        {
712
          pData->iFRAMclipl = iClipl;
713
          pData->iFRAMclipr = iClipr;
714
          pData->iFRAMclipt = iClipt;
715
          pData->iFRAMclipb = iClipb;
716
        }
717
        else                           /* relative */
718
        {
719
          pData->iFRAMclipl = pData->iFRAMclipl + iClipl;
720
          pData->iFRAMclipr = pData->iFRAMclipr + iClipr;
721
          pData->iFRAMclipt = pData->iFRAMclipt + iClipt;
722
          pData->iFRAMclipb = pData->iFRAMclipb + iClipb;
723
        }
724
      }
725
    }
726
    else
727
    {                                  /* reload defaults */
728
      pData->bFrameclipping = pData->bFRAMclipping;
729
      pData->iFrameclipl    = pData->iFRAMclipl;
730
      pData->iFrameclipr    = pData->iFRAMclipr;
731
      pData->iFrameclipt    = pData->iFRAMclipt;
732
      pData->iFrameclipb    = pData->iFRAMclipb;
733
    }
734
  }
735
736
  if (!pData->bTimerset)               /* timer still off ? */
737
  {
738
    if ((pData->iFramemode == 4) ||    /* insert background layer after a new frame */
739
        (!pData->iLayerseq))           /* and certainly before the very first layer */
740
      iRetcode = load_bkgdlayer (pData);
741
742
    if (iRetcode)                      /* on error bail out */
743
      return iRetcode;
744
745
    if ((pData->bDisplaying) && (pData->bRunning))
746
    {
747
      pData->iFrameseq++;              /* count the frame ! */
748
      pData->bFramedone = MNG_TRUE;    /* and indicate we've done one */
749
    }
750
  }
751
752
#ifdef MNG_SUPPORT_TRACE
753
  MNG_TRACE (pData, MNG_FN_NEXT_FRAME, MNG_LC_END)
754
#endif
755
756
  return MNG_NOERROR;
757
}
758
759
/* ************************************************************************** */
760
761
mng_retcode next_layer (mng_datap pData)
762
{
763
  mng_imagep  pImage;
764
  mng_retcode iRetcode = MNG_NOERROR;
765
766
#ifdef MNG_SUPPORT_TRACE
767
  MNG_TRACE (pData, MNG_FN_NEXT_LAYER, MNG_LC_START)
768
#endif
769
770
  if (!pData->iBreakpoint)             /* no previous break here ? */
771
  {                                    /* interframe delay required ? */
772
    if ((pData->eImagetype == mng_it_mng) && (pData->iLayerseq) &&
773
        ((pData->iFramemode == 1) || (pData->iFramemode == 3)))
774
      iRetcode = interframe_delay (pData);
775
    else
776
      pData->iFramedelay = pData->iNextdelay;
777
778
    if (iRetcode)                      /* on error bail out */
779
      return iRetcode;
780
  }
781
782
  if (!pData->bTimerset)               /* timer still off ? */
783
  {
784
    if (!pData->iLayerseq)             /* restore background for the very first layer ? */
785
    {                                  /* wait till IDAT/JDAT for PNGs & JNGs !!! */
786
      if ((pData->eImagetype == mng_it_png) || (pData->eImagetype == mng_it_jng))
787
        pData->bRestorebkgd = MNG_TRUE;
788
      else
789
      {                                /* for MNG we do it right away */
790
        iRetcode = load_bkgdlayer (pData);
791
792
        if (pData->bRunning)
793
          pData->iLayerseq++;          /* and it counts as a layer then ! */
794
      }
795
    }
796
    else
797
    if (pData->iFramemode == 3)        /* restore background for each layer ? */
798
      iRetcode = load_bkgdlayer (pData);
799
800
    if (iRetcode)                      /* on error bail out */
801
      return iRetcode;
802
803
    if (pData->bHasDHDR)               /* processing a delta-image ? */
804
      pImage = (mng_imagep)pData->pDeltaImage;
805
    else
806
      pImage = (mng_imagep)pData->pCurrentobj;
807
808
    if (!pImage)                       /* not an active object ? */
809
      pImage = (mng_imagep)pData->pObjzero;
810
                                       /* determine display rectangle */
811
    pData->iDestl   = MAX_COORD ((mng_int32)0,   pImage->iPosx);
812
    pData->iDestt   = MAX_COORD ((mng_int32)0,   pImage->iPosy);
813
                                       /* is it a valid buffer ? */
814
    if ((pImage->pImgbuf->iWidth) && (pImage->pImgbuf->iHeight))
815
    {
816
      pData->iDestr = MIN_COORD ((mng_int32)pData->iWidth,
817
                                 pImage->iPosx + (mng_int32)pImage->pImgbuf->iWidth );
818
      pData->iDestb = MIN_COORD ((mng_int32)pData->iHeight,
819
                                 pImage->iPosy + (mng_int32)pImage->pImgbuf->iHeight);
820
    }
821
    else                               /* it's a single image ! */
822
    {
823
      pData->iDestr = MIN_COORD ((mng_int32)pData->iWidth,
824
                                 (mng_int32)pData->iDatawidth );
825
      pData->iDestb = MIN_COORD ((mng_int32)pData->iHeight,
826
                                 (mng_int32)pData->iDataheight);
827
    }
828
829
    if (pData->bFrameclipping)         /* frame clipping specified ? */
830
    {
831
      pData->iDestl = MAX_COORD (pData->iDestl,  pData->iFrameclipl);
832
      pData->iDestt = MAX_COORD (pData->iDestt,  pData->iFrameclipt);
833
      pData->iDestr = MIN_COORD (pData->iDestr,  pData->iFrameclipr);
834
      pData->iDestb = MIN_COORD (pData->iDestb,  pData->iFrameclipb);
835
    }
836
837
    if (pImage->bClipped)              /* is the image clipped itself ? */
838
    {
839
      pData->iDestl = MAX_COORD (pData->iDestl,  pImage->iClipl);
840
      pData->iDestt = MAX_COORD (pData->iDestt,  pImage->iClipt);
841
      pData->iDestr = MIN_COORD (pData->iDestr,  pImage->iClipr);
842
      pData->iDestb = MIN_COORD (pData->iDestb,  pImage->iClipb);
843
    }
844
                                       /* determine source starting point */
845
    pData->iSourcel = MAX_COORD ((mng_int32)0,   pData->iDestl - pImage->iPosx);
846
    pData->iSourcet = MAX_COORD ((mng_int32)0,   pData->iDestt - pImage->iPosy);
847
848
    if ((pImage->pImgbuf->iWidth) && (pImage->pImgbuf->iHeight))
849
    {                                  /* and maximum size  */
850
      pData->iSourcer = MIN_COORD ((mng_int32)pImage->pImgbuf->iWidth,
851
                                   pData->iSourcel + pData->iDestr - pData->iDestl);
852
      pData->iSourceb = MIN_COORD ((mng_int32)pImage->pImgbuf->iHeight,
853
                                   pData->iSourcet + pData->iDestb - pData->iDestt);
854
    }
855
    else                               /* it's a single image ! */
856
    {
857
      pData->iSourcer = pData->iSourcel + pData->iDestr - pData->iDestl;
858
      pData->iSourceb = pData->iSourcet + pData->iDestb - pData->iDestt;
859
    }
860
861
    if (pData->bRunning)
862
      pData->iLayerseq++;              /* count the layer ! */
863
  }
864
865
#ifdef MNG_SUPPORT_TRACE
866
  MNG_TRACE (pData, MNG_FN_NEXT_LAYER, MNG_LC_END)
867
#endif
868
869
  return MNG_NOERROR;
870
}
871
872
/* ************************************************************************** */
873
874
mng_retcode display_image (mng_datap  pData,
875
                           mng_imagep pImage,
876
                           mng_bool   bLayeradvanced)
877
{
878
  mng_retcode iRetcode;
879
  
880
#ifdef MNG_SUPPORT_TRACE
881
  MNG_TRACE (pData, MNG_FN_DISPLAY_IMAGE, MNG_LC_START)
882
#endif
883
                                       /* actively running ? */
884
  if ((pData->bRunning) && (!pData->bFreezing))
885
  {
886
    if ( (!pData->iBreakpoint) &&      /* needs magnification ? */
887
         ( (pImage->iMAGN_MethodX) || (pImage->iMAGN_MethodY) ) )
888
    {
889
      iRetcode = magnify_imageobject (pData, pImage);
890
891
      if (iRetcode)                    /* on error bail out */
892
        return iRetcode;
893
    }
894
  }
895
896
  pData->pRetrieveobj = pImage;        /* so retrieve-row and color-correction can find it */
897
898
  if (!bLayeradvanced)                 /* need to advance the layer ? */
899
  {
900
    mng_imagep pSave    = pData->pCurrentobj;
901
    pData->pCurrentobj  = pImage;
902
    next_layer (pData);                /* advance to next layer */
903
    pData->pCurrentobj  = pSave;
904
  }
905
                                       /* need to restore the background ? */
906
  if ((!pData->bTimerset) && (pData->bRestorebkgd))
907
  {
908
    mng_imagep pSave    = pData->pCurrentobj;
909
    pData->pCurrentobj  = pImage;
910
    pData->bRestorebkgd = MNG_FALSE;
911
    iRetcode            = load_bkgdlayer (pData);
912
    pData->pCurrentobj  = pSave;
913
914
    if (iRetcode)                      /* on error bail out */
915
      return iRetcode;
916
917
    if (pData->bRunning)
918
      pData->iLayerseq++;              /* and it counts as a layer then ! */
919
  }
920
                                       /* actively running ? */
921
  if ((pData->bRunning) && (!pData->bFreezing))
922
  {
923
    if (!pData->bTimerset)             /* all systems still go ? */
924
    {
925
      pData->iBreakpoint = 0;          /* let's make absolutely sure... */
926
                                       /* anything to display ? */
927
      if ((pData->iDestr >= pData->iDestl) && (pData->iDestb >= pData->iDestt))
928
      {
929
        mng_int32 iY;
930
931
        set_display_routine (pData);   /* determine display routine */
932
                                       /* and image-buffer retrieval routine */
933
        switch (pImage->pImgbuf->iColortype)
934
        {
935
          case  0 : { if (pImage->pImgbuf->iBitdepth > 8)
936
                        pData->fRetrieverow = (mng_fptr)retrieve_g16;
937
                      else
938
                        pData->fRetrieverow = (mng_fptr)retrieve_g8;
939
940
                      pData->bIsOpaque      = (mng_bool)(!pImage->pImgbuf->bHasTRNS);
941
                      break;
942
                    }
943
944
          case  2 : { if (pImage->pImgbuf->iBitdepth > 8)
945
                        pData->fRetrieverow = (mng_fptr)retrieve_rgb16;
946
                      else
947
                        pData->fRetrieverow = (mng_fptr)retrieve_rgb8;
948
949
                      pData->bIsOpaque      = (mng_bool)(!pImage->pImgbuf->bHasTRNS);
950
                      break;
951
                    }
952
953
954
          case  3 : { pData->fRetrieverow   = (mng_fptr)retrieve_idx8;
955
                      pData->bIsOpaque      = (mng_bool)(!pImage->pImgbuf->bHasTRNS);
956
                      break;
957
                    }
958
959
960
          case  4 : { if (pImage->pImgbuf->iBitdepth > 8)
961
                        pData->fRetrieverow = (mng_fptr)retrieve_ga16;
962
                      else
963
                        pData->fRetrieverow = (mng_fptr)retrieve_ga8;
964
965
                      pData->bIsOpaque      = MNG_FALSE;
966
                      break;
967
                    }
968
969
970
          case  6 : { if (pImage->pImgbuf->iBitdepth > 8)
971
                        pData->fRetrieverow = (mng_fptr)retrieve_rgba16;
972
                      else
973
                        pData->fRetrieverow = (mng_fptr)retrieve_rgba8;
974
975
                      pData->bIsOpaque      = MNG_FALSE;
976
                      break;
977
                    }
978
979
          case  8 : { if (pImage->pImgbuf->iBitdepth > 8)
980
                        pData->fRetrieverow = (mng_fptr)retrieve_g16;
981
                      else
982
                        pData->fRetrieverow = (mng_fptr)retrieve_g8;
983
984
                      pData->bIsOpaque      = MNG_TRUE;
985
                      break;
986
                    }
987
988
          case 10 : { if (pImage->pImgbuf->iBitdepth > 8)
989
                        pData->fRetrieverow = (mng_fptr)retrieve_rgb16;
990
                      else
991
                        pData->fRetrieverow = (mng_fptr)retrieve_rgb8;
992
993
                      pData->bIsOpaque      = MNG_TRUE;
994
                      break;
995
                    }
996
997
998
          case 12 : { if (pImage->pImgbuf->iBitdepth > 8)
999
                        pData->fRetrieverow = (mng_fptr)retrieve_ga16;
1000
                      else
1001
                        pData->fRetrieverow = (mng_fptr)retrieve_ga8;
1002
1003
                      pData->bIsOpaque      = MNG_FALSE;
1004
                      break;
1005
                    }
1006
1007
1008
          case 14 : { if (pImage->pImgbuf->iBitdepth > 8)
1009
                        pData->fRetrieverow = (mng_fptr)retrieve_rgba16;
1010
                      else
1011
                        pData->fRetrieverow = (mng_fptr)retrieve_rgba8;
1012
1013
                      pData->bIsOpaque      = MNG_FALSE;
1014
                      break;
1015
                    }
1016
1017
        }
1018
1019
        pData->iPass       = -1;       /* these are the object's dimensions now */
1020
        pData->iRow        = pData->iSourcet;
1021
        pData->iRowinc     = 1;
1022
        pData->iCol        = 0;
1023
        pData->iColinc     = 1;
1024
        pData->iRowsamples = pImage->pImgbuf->iWidth;
1025
        pData->iRowsize    = pData->iRowsamples << 2;
1026
        pData->bIsRGBA16   = MNG_FALSE;
1027
                                       /* adjust for 16-bit object ? */
1028
        if (pImage->pImgbuf->iBitdepth > 8)
1029
        {
1030
          pData->bIsRGBA16 = MNG_TRUE;
1031
          pData->iRowsize  = pData->iRowsamples << 3;
1032
        }
1033
1034
        pData->fCorrectrow = MNG_NULL; /* default no color-correction */
1035
1036
#ifdef MNG_NO_CMS
1037
        iRetcode = MNG_NOERROR;
1038
#else
1039
#if defined(MNG_FULL_CMS)              /* determine color-management routine */
1040
        iRetcode = init_full_cms_object   (pData);
1041
#elif defined(MNG_GAMMA_ONLY)
1042
        iRetcode = init_gamma_only_object (pData);
1043
#elif defined(MNG_APP_CMS)
1044
        iRetcode = init_app_cms_object    (pData);
1045
#endif
1046
        if (iRetcode)                  /* on error bail out */
1047
          return iRetcode;
1048
#endif /* MNG_NO_CMS */
1049
                                       /* get a temporary row-buffer */
1050
        MNG_ALLOC (pData, pData->pRGBArow, pData->iRowsize)
1051
1052
        iY = pData->iSourcet;          /* this is where we start */
1053
1054
        while ((!iRetcode) && (iY < pData->iSourceb))
1055
        {                              /* get a row */
1056
          iRetcode = ((mng_retrieverow)pData->fRetrieverow) (pData);
1057
                                       /* color correction ? */
1058
          if ((!iRetcode) && (pData->fCorrectrow))
1059
            iRetcode = ((mng_correctrow)pData->fCorrectrow) (pData);
1060
1061
          if (!iRetcode)               /* so... display it */
1062
            iRetcode = ((mng_displayrow)pData->fDisplayrow) (pData);
1063
1064
          if (!iRetcode)               /* adjust variables for next row */
1065
            iRetcode = next_row (pData);
1066
1067
          iY++;                        /* and next line */
1068
        }
1069
                                       /* drop the temporary row-buffer */
1070
        MNG_FREE (pData, pData->pRGBArow, pData->iRowsize)
1071
1072
        if (iRetcode)                  /* on error bail out */
1073
          return iRetcode;
1074
1075
#if defined(MNG_INCLUDE_LCMS)          /* cleanup cms stuff */
1076
        iRetcode = mng_clear_cms (pData);
1077
1078
        if (iRetcode)                  /* on error bail out */
1079
          return iRetcode;
1080
#endif
1081
      }
1082
    }
1083
  }
1084
1085
#ifdef MNG_SUPPORT_TRACE
1086
  MNG_TRACE (pData, MNG_FN_DISPLAY_IMAGE, MNG_LC_END)
1087
#endif
1088
1089
  return MNG_NOERROR;                  /* whehehe, this is good ! */
1090
}
1091
1092
/* ************************************************************************** */
1093
1094
mng_retcode execute_delta_image (mng_datap  pData,
1095
                                 mng_imagep pTarget,
1096
                                 mng_imagep pDelta)
1097
{
1098
  mng_imagedatap pBuftarget = pTarget->pImgbuf;
1099
  mng_imagedatap pBufdelta  = pDelta->pImgbuf;
1100
  mng_uint32     iY;
1101
  mng_retcode    iRetcode;
1102
1103
#ifdef MNG_SUPPORT_TRACE
1104
  MNG_TRACE (pData, MNG_FN_EXECUTE_DELTA_IMAGE, MNG_LC_START)
1105
#endif
1106
                                       /* actively running ? */
1107
  if ((pData->bRunning) && (!pData->bFreezing))
1108
  {
1109
    if (pBufdelta->bHasPLTE)           /* palette in delta ? */
1110
    {
1111
      mng_uint32 iX;
1112
                                       /* new palette larger than old one ? */
1113
      if ((!pBuftarget->bHasPLTE) || (pBuftarget->iPLTEcount < pBufdelta->iPLTEcount))
1114
        pBuftarget->iPLTEcount = pBufdelta->iPLTEcount;
1115
                                       /* it's definitely got a PLTE now */
1116
      pBuftarget->bHasPLTE = MNG_TRUE;
1117
1118
      for (iX = 0; iX < pBufdelta->iPLTEcount; iX++)
1119
      {
1120
        pBuftarget->aPLTEentries[iX].iRed   = pBufdelta->aPLTEentries[iX].iRed;
1121
        pBuftarget->aPLTEentries[iX].iGreen = pBufdelta->aPLTEentries[iX].iGreen;
1122
        pBuftarget->aPLTEentries[iX].iBlue  = pBufdelta->aPLTEentries[iX].iBlue;
1123
      }
1124
    }
1125
1126
    if (pBufdelta->bHasTRNS)           /* cheap transparency in delta ? */
1127
    {
1128
      switch (pData->iColortype)       /* drop it into the target */
1129
      {
1130
        case 0: {                      /* gray */
1131
                  pBuftarget->iTRNSgray  = pBufdelta->iTRNSgray;
1132
                  pBuftarget->iTRNSred   = 0;
1133
                  pBuftarget->iTRNSgreen = 0;
1134
                  pBuftarget->iTRNSblue  = 0;
1135
                  pBuftarget->iTRNScount = 0;
1136
                  break;
1137
                }
1138
        case 2: {                      /* rgb */
1139
                  pBuftarget->iTRNSgray  = 0;
1140
                  pBuftarget->iTRNSred   = pBufdelta->iTRNSred;
1141
                  pBuftarget->iTRNSgreen = pBufdelta->iTRNSgreen;
1142
                  pBuftarget->iTRNSblue  = pBufdelta->iTRNSblue;
1143
                  pBuftarget->iTRNScount = 0;
1144
                  break;
1145
                }
1146
        case 3: {                      /* indexed */
1147
                  pBuftarget->iTRNSgray  = 0;
1148
                  pBuftarget->iTRNSred   = 0;
1149
                  pBuftarget->iTRNSgreen = 0;
1150
                  pBuftarget->iTRNSblue  = 0;
1151
                                       /* existing range smaller than new one ? */
1152
                  if ((!pBuftarget->bHasTRNS) || (pBuftarget->iTRNScount < pBufdelta->iTRNScount))
1153
                    pBuftarget->iTRNScount = pBufdelta->iTRNScount;
1154
1155
                  MNG_COPY (pBuftarget->aTRNSentries, pBufdelta->aTRNSentries, pBufdelta->iTRNScount)
1156
                  break;
1157
                }
1158
      }
1159
1160
      pBuftarget->bHasTRNS = MNG_TRUE; /* tell it it's got a tRNS now */
1161
    }
1162
1163
    if (pBufdelta->bHasBKGD)           /* bkgd in source ? */
1164
    {                                  /* drop it onto the target */
1165
      pBuftarget->bHasBKGD   = MNG_TRUE;
1166
      pBuftarget->iBKGDindex = pBufdelta->iBKGDindex;
1167
      pBuftarget->iBKGDgray  = pBufdelta->iBKGDgray;
1168
      pBuftarget->iBKGDred   = pBufdelta->iBKGDred;
1169
      pBuftarget->iBKGDgreen = pBufdelta->iBKGDgreen;
1170
      pBuftarget->iBKGDblue  = pBufdelta->iBKGDblue;
1171
    }
1172
1173
    if (pBufdelta->bHasGAMA)           /* gamma in source ? */
1174
    {
1175
      pBuftarget->bHasGAMA = MNG_TRUE; /* drop it onto the target */
1176
      pBuftarget->iGamma   = pBufdelta->iGamma;
1177
    }
1178
1179
    if (pBufdelta->bHasCHRM)           /* chroma in delta ? */
1180
    {                                  /* drop it onto the target */
1181
      pBuftarget->bHasCHRM       = MNG_TRUE;
1182
      pBuftarget->iWhitepointx   = pBufdelta->iWhitepointx;
1183
      pBuftarget->iWhitepointy   = pBufdelta->iWhitepointy;
1184
      pBuftarget->iPrimaryredx   = pBufdelta->iPrimaryredx;
1185
      pBuftarget->iPrimaryredy   = pBufdelta->iPrimaryredy;
1186
      pBuftarget->iPrimarygreenx = pBufdelta->iPrimarygreenx;
1187
      pBuftarget->iPrimarygreeny = pBufdelta->iPrimarygreeny;
1188
      pBuftarget->iPrimarybluex  = pBufdelta->iPrimarybluex;
1189
      pBuftarget->iPrimarybluey  = pBufdelta->iPrimarybluey;
1190
    }
1191
1192
    if (pBufdelta->bHasSRGB)           /* sRGB in delta ? */
1193
    {                                  /* drop it onto the target */
1194
      pBuftarget->bHasSRGB         = MNG_TRUE;
1195
      pBuftarget->iRenderingintent = pBufdelta->iRenderingintent;
1196
    }
1197
1198
    if (pBufdelta->bHasICCP)           /* ICC profile in delta ? */
1199
    {
1200
      pBuftarget->bHasICCP = MNG_TRUE; /* drop it onto the target */
1201
1202
      if (pBuftarget->pProfile)        /* profile existed ? */
1203
        MNG_FREEX (pData, pBuftarget->pProfile, pBuftarget->iProfilesize)
1204
                                       /* allocate a buffer & copy it */
1205
      MNG_ALLOC (pData, pBuftarget->pProfile, pBufdelta->iProfilesize)
1206
      MNG_COPY  (pBuftarget->pProfile, pBufdelta->pProfile, pBufdelta->iProfilesize)
1207
                                       /* store it's length as well */
1208
      pBuftarget->iProfilesize = pBufdelta->iProfilesize;
1209
    }
1210
                                       /* need to execute delta pixels ? */
1211
    if ((!pData->bDeltaimmediate) && (pData->iDeltatype != MNG_DELTATYPE_NOCHANGE))
1212
    {
1213
      pData->fScalerow = MNG_NULL;     /* not needed by default */
1214
1215
      switch (pBuftarget->iBitdepth)   /* determine scaling routine */
1216
      {
1217
1218
1219
      }
1220
1221
      pData->fDeltarow = MNG_NULL;     /* let's assume there's nothing to do */
1222
1223
      switch (pBuftarget->iColortype)  /* determine delta processing routine */
1224
      {
1225
        case  0 : ;
1226
        case  8 : {                     /* gray */
1227
                    if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE          ) ||
1228
                        (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD    ) ||
1229
                        (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)    )
1230
                    {
1231
                      if ((pBufdelta->iColortype == 0) || (pBufdelta->iColortype == 3) ||
1232
                          (pBufdelta->iColortype == 8))
1233
                      {
1234
                        switch (pBuftarget->iBitdepth)
1235
                        {
1236
                          case  1 : { pData->fDeltarow = (mng_fptr)delta_g1_g1;   break; }
1237
                          case  2 : { pData->fDeltarow = (mng_fptr)delta_g2_g2;   break; }
1238
                          case  4 : { pData->fDeltarow = (mng_fptr)delta_g4_g4;   break; }
1239
                          case  8 : { pData->fDeltarow = (mng_fptr)delta_g8_g8;   break; }
1240
                          case 16 : { pData->fDeltarow = (mng_fptr)delta_g16_g16; break; }
1241
                        }
1242
                      }
1243
                    }
1244
1245
                    break;
1246
                  }
1247
1248
        case  2 : ;
1249
        case 10 : {                     /* rgb */
1250
                    if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE          ) ||
1251
                        (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD    ) ||
1252
                        (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)    )
1253
                    {
1254
                      if ((pBufdelta->iColortype == 2) || (pBufdelta->iColortype == 10))
1255
                      {
1256
                        switch (pBuftarget->iBitdepth)
1257
                        {
1258
                          case  8 : { pData->fDeltarow = (mng_fptr)delta_rgb8_rgb8;   break; }
1259
                          case 16 : { pData->fDeltarow = (mng_fptr)delta_rgb16_rgb16; break; }
1260
                        }
1261
                      }
1262
                    }
1263
1264
                    break;
1265
                  }
1266
1267
        case  3 : {                     /* indexed; abuse gray routines */
1268
                    if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE          ) ||
1269
                        (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD    ) ||
1270
                        (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)    )
1271
                    {
1272
                      if ((pBufdelta->iColortype == 0) || (pBufdelta->iColortype == 3))
1273
                      {
1274
                        switch (pBuftarget->iBitdepth)
1275
                        {
1276
                          case  1 : { pData->fDeltarow = (mng_fptr)delta_g1_g1; break; }
1277
                          case  2 : { pData->fDeltarow = (mng_fptr)delta_g2_g2; break; }
1278
                          case  4 : { pData->fDeltarow = (mng_fptr)delta_g4_g4; break; }
1279
                          case  8 : { pData->fDeltarow = (mng_fptr)delta_g8_g8; break; }
1280
                        }
1281
                      }
1282
                    }
1283
1284
                    break;
1285
                  }
1286
1287
        case  4 : ;
1288
        case 12 : {                     /* gray + alpha */
1289
                    if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE          ) ||
1290
                        (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD    ) ||
1291
                        (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)    )
1292
                    {
1293
                      if ((pBufdelta->iColortype == 4) || (pBufdelta->iColortype == 12))
1294
                      {
1295
                        switch (pBuftarget->iBitdepth)
1296
                        {
1297
                          case  8 : { pData->fDeltarow = (mng_fptr)delta_ga8_ga8;   break; }
1298
                          case 16 : { pData->fDeltarow = (mng_fptr)delta_ga16_ga16; break; }
1299
                        }
1300
                      }
1301
                    }
1302
                    else
1303
                    if ((pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORADD    ) ||
1304
                        (pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORREPLACE)    )
1305
                    {
1306
                      if ((pBufdelta->iColortype == 0) || (pBufdelta->iColortype == 3) ||
1307
                          (pBufdelta->iColortype == 8))
1308
                      {
1309
                        switch (pBuftarget->iBitdepth)
1310
                        {
1311
                          case  8 : { pData->fDeltarow = (mng_fptr)delta_ga8_g8;   break; }
1312
                          case 16 : { pData->fDeltarow = (mng_fptr)delta_ga16_g16; break; }
1313
                        }
1314
                      }
1315
                    }
1316
                    else
1317
                    if ((pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAADD    ) ||
1318
                        (pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAREPLACE)    )
1319
                    {
1320
                      if ((pBufdelta->iColortype == 0) || (pBufdelta->iColortype == 3))
1321
                      {
1322
                        switch (pBuftarget->iBitdepth)
1323
                        {
1324
                          case  8 : { pData->fDeltarow = (mng_fptr)delta_ga8_a8;   break; }
1325
                          case 16 : { pData->fDeltarow = (mng_fptr)delta_ga16_a16; break; }
1326
                        }
1327
                      }
1328
                    }
1329
1330
                    break;
1331
                  }
1332
1333
        case  6 : ;
1334
        case 14 : {                     /* rgb + alpha */
1335
                    if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE          ) ||
1336
                        (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD    ) ||
1337
                        (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)    )
1338
                    {
1339
                      if ((pBufdelta->iColortype == 6) || (pBufdelta->iColortype == 14))
1340
                      {
1341
                        switch (pBuftarget->iBitdepth)
1342
                        {
1343
                          case  8 : { pData->fDeltarow = (mng_fptr)delta_rgba8_rgba8;   break; }
1344
                          case 16 : { pData->fDeltarow = (mng_fptr)delta_rgba16_rgba16; break; }
1345
                        }
1346
                      }
1347
                    }
1348
                    else
1349
                    if ((pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORADD    ) ||
1350
                        (pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORREPLACE)    )
1351
                    {
1352
                      if ((pBufdelta->iColortype == 2) || (pBufdelta->iColortype == 10))
1353
                      {
1354
                        switch (pBuftarget->iBitdepth)
1355
                        {
1356
                          case  8 : { pData->fDeltarow = (mng_fptr)delta_rgba8_rgb8;   break; }
1357
                          case 16 : { pData->fDeltarow = (mng_fptr)delta_rgba16_rgb16; break; }
1358
                        }
1359
                      }
1360
                    }
1361
                    else
1362
                    if ((pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAADD    ) ||
1363
                        (pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAREPLACE)    )
1364
                    {
1365
                      if ((pBufdelta->iColortype == 0) || (pBufdelta->iColortype == 3))
1366
                      {
1367
                        switch (pBuftarget->iBitdepth)
1368
                        {
1369
                          case  8 : { pData->fDeltarow = (mng_fptr)delta_rgba8_a8;   break; }
1370
                          case 16 : { pData->fDeltarow = (mng_fptr)delta_rgba16_a16; break; }
1371
                        }
1372
                      }
1373
                    }
1374
1375
                    break;
1376
                  }
1377
1378
      }
1379
1380
      if (pData->fDeltarow)            /* do we need to take action ? */
1381
      {
1382
        pData->iPass        = -1;      /* setup row dimensions and stuff */
1383
        pData->iRow         = pData->iDeltaBlocky;
1384
        pData->iRowinc      = 1;
1385
        pData->iCol         = pData->iDeltaBlockx;
1386
        pData->iColinc      = 1;
1387
        pData->iRowsamples  = pBufdelta->iWidth;
1388
        pData->iRowsize     = pBuftarget->iRowsize;
1389
                                       /* indicate where to retrieve & where to store */
1390
        pData->pRetrieveobj = (mng_objectp)pDelta;
1391
        pData->pStoreobj    = (mng_objectp)pTarget;
1392
1393
        if (pData->pRGBArow)           /* prevent duplicate allocation! */
1394
          MNG_FREE (pData, pData->pRGBArow, (pData->iDatawidth << 3))
1395
                                       /* get a temporary row-buffer */
1396
        MNG_ALLOC (pData, pData->pRGBArow, pBufdelta->iRowsize)
1397
1398
        iY       = 0;                  /* this is where we start */
1399
        iRetcode = MNG_NOERROR;        /* still oke for now */
1400
1401
        while ((!iRetcode) && (iY < pBufdelta->iHeight))
1402
        {                              /* get a row */
1403
          mng_uint8p pWork = pBufdelta->pImgdata + (iY * pBufdelta->iRowsize);
1404
1405
          MNG_COPY (pData->pRGBArow, pWork, pBufdelta->iRowsize);
1406
1407
          if (pData->fScalerow)        /* scale it (if necessary) */
1408
            iRetcode = ((mng_scalerow)pData->fScalerow) (pData);
1409
1410
          if (!iRetcode)               /* and... execute it */
1411
            iRetcode = ((mng_deltarow)pData->fDeltarow) (pData);
1412
1413
          if (!iRetcode)               /* adjust variables for next row */
1414
            iRetcode = next_row (pData);
1415
1416
          iY++;                        /* and next line */
1417
        }
1418
                                       /* drop the temporary row-buffer */
1419
        MNG_FREE (pData, pData->pRGBArow, pBufdelta->iRowsize)
1420
1421
        if (iRetcode)                  /* on error bail out */
1422
          return iRetcode;
1423
1424
      }
1425
      else
1426
        MNG_ERROR (pData, MNG_INVALIDDELTA)
1427
1428
    }
1429
  }
1430
1431
#ifdef MNG_SUPPORT_TRACE
1432
  MNG_TRACE (pData, MNG_FN_EXECUTE_DELTA_IMAGE, MNG_LC_END)
1433
#endif
1434
1435
  return MNG_NOERROR;
1436
}
1437
1438
/* ************************************************************************** */
1439
1440
mng_retcode save_state (mng_datap pData)
1441
{
1442
  mng_savedatap pSave;
1443
  mng_imagep    pImage;
1444
1445
#ifdef MNG_SUPPORT_TRACE
1446
  MNG_TRACE (pData, MNG_FN_SAVE_STATE, MNG_LC_START)
1447
#endif
1448
1449
  if (pData->pSavedata)                /* sanity check */
1450
    MNG_ERROR (pData, MNG_INTERNALERROR)
1451
                                       /* get a buffer for saving */
1452
  MNG_ALLOC (pData, pData->pSavedata, sizeof (mng_savedata))
1453
1454
  pSave = pData->pSavedata;            /* address it more directly */
1455
                                       /* and copy global data from the main struct */
1456
#if defined(MNG_SUPPORT_READ) || defined(MNG_SUPPORT_WRITE)
1457
  pSave->bHasglobalPLTE       = pData->bHasglobalPLTE;
1458
  pSave->bHasglobalTRNS       = pData->bHasglobalTRNS;
1459
  pSave->bHasglobalGAMA       = pData->bHasglobalGAMA;
1460
  pSave->bHasglobalCHRM       = pData->bHasglobalCHRM;
1461
  pSave->bHasglobalSRGB       = pData->bHasglobalSRGB;
1462
  pSave->bHasglobalICCP       = pData->bHasglobalICCP;
1463
  pSave->bHasglobalBKGD       = pData->bHasglobalBKGD;
1464
#endif /* MNG_SUPPORT_READ || MNG_SUPPORT_WRITE */
1465
1466
  pSave->iBACKred             = pData->iBACKred;
1467
  pSave->iBACKgreen           = pData->iBACKgreen;
1468
  pSave->iBACKblue            = pData->iBACKblue;
1469
  pSave->iBACKmandatory       = pData->iBACKmandatory;
1470
  pSave->iBACKimageid         = pData->iBACKimageid;
1471
  pSave->iBACKtile            = pData->iBACKtile;
1472
1473
  pSave->iFRAMmode            = pData->iFRAMmode;
1474
  pSave->iFRAMdelay           = pData->iFRAMdelay;
1475
  pSave->iFRAMtimeout         = pData->iFRAMtimeout;
1476
  pSave->bFRAMclipping        = pData->bFRAMclipping;
1477
  pSave->iFRAMclipl           = pData->iFRAMclipl;
1478
  pSave->iFRAMclipr           = pData->iFRAMclipr;
1479
  pSave->iFRAMclipt           = pData->iFRAMclipt;
1480
  pSave->iFRAMclipb           = pData->iFRAMclipb;
1481
1482
  pSave->iGlobalPLTEcount     = pData->iGlobalPLTEcount;
1483
1484
  MNG_COPY (pSave->aGlobalPLTEentries, pData->aGlobalPLTEentries, sizeof (mng_rgbpaltab))
1485
1486
  pSave->iGlobalTRNSrawlen    = pData->iGlobalTRNSrawlen;
1487
  MNG_COPY (pSave->aGlobalTRNSrawdata, pData->aGlobalTRNSrawdata, 256)
1488
1489
  pSave->iGlobalGamma         = pData->iGlobalGamma;
1490
1491
  pSave->iGlobalWhitepointx   = pData->iGlobalWhitepointx;
1492
  pSave->iGlobalWhitepointy   = pData->iGlobalWhitepointy;
1493
  pSave->iGlobalPrimaryredx   = pData->iGlobalPrimaryredx;
1494
  pSave->iGlobalPrimaryredy   = pData->iGlobalPrimaryredy;
1495
  pSave->iGlobalPrimarygreenx = pData->iGlobalPrimarygreenx;
1496
  pSave->iGlobalPrimarygreeny = pData->iGlobalPrimarygreeny;
1497
  pSave->iGlobalPrimarybluex  = pData->iGlobalPrimarybluex;
1498
  pSave->iGlobalPrimarybluey  = pData->iGlobalPrimarybluey;
1499
1500
  pSave->iGlobalRendintent    = pData->iGlobalRendintent;
1501
1502
  pSave->iGlobalProfilesize   = pData->iGlobalProfilesize;
1503
1504
  if (pSave->iGlobalProfilesize)       /* has a profile ? */
1505
  {                                    /* then copy that ! */
1506
    MNG_ALLOC (pData, pSave->pGlobalProfile, pSave->iGlobalProfilesize)
1507
    MNG_COPY (pSave->pGlobalProfile, pData->pGlobalProfile, pSave->iGlobalProfilesize)
1508
  }
1509
1510
  pSave->iGlobalBKGDred       = pData->iGlobalBKGDred;
1511
  pSave->iGlobalBKGDgreen     = pData->iGlobalBKGDgreen;
1512
  pSave->iGlobalBKGDblue      = pData->iGlobalBKGDblue;
1513
1514
                                       /* freeze current image objects */
1515
  pImage = (mng_imagep)pData->pFirstimgobj;
1516
1517
  while (pImage)
1518
  {                                    /* freeze the object AND it's buffer */
1519
    pImage->bFrozen          = MNG_TRUE;
1520
    pImage->pImgbuf->bFrozen = MNG_TRUE;
1521
                                       /* neeeext */
1522
    pImage = (mng_imagep)pImage->sHeader.pNext;
1523
  }
1524
1525
#ifdef MNG_SUPPORT_TRACE
1526
  MNG_TRACE (pData, MNG_FN_SAVE_STATE, MNG_LC_END)
1527
#endif
1528
1529
  return MNG_NOERROR;
1530
}
1531
1532
/* ************************************************************************** */
1533
1534
mng_retcode mng_reset_objzero (mng_datap pData)
1535
{
1536
  mng_imagep  pImage   = (mng_imagep)pData->pObjzero;
1537
  mng_retcode iRetcode = reset_object_details (pData, pImage, 0, 0, 0,
1538
                                               0, 0, 0, 0, MNG_TRUE);
1539
1540
  if (iRetcode)                        /* on error bail out */
1541
    return iRetcode;
1542
1543
  pImage->bVisible             = MNG_TRUE;
1544
  pImage->bViewable            = MNG_TRUE;
1545
  pImage->iPosx                = 0;
1546
  pImage->iPosy                = 0;
1547
  pImage->bClipped             = MNG_FALSE;
1548
  pImage->iClipl               = 0;
1549
  pImage->iClipr               = 0;
1550
  pImage->iClipt               = 0;
1551
  pImage->iClipb               = 0;
1552
  pImage->iMAGN_MethodX        = 0;
1553
  pImage->iMAGN_MethodY        = 0;
1554
  pImage->iMAGN_MX             = 0;
1555
  pImage->iMAGN_MY             = 0;
1556
  pImage->iMAGN_ML             = 0;
1557
  pImage->iMAGN_MR             = 0;
1558
  pImage->iMAGN_MT             = 0;
1559
  pImage->iMAGN_MB             = 0;
1560
1561
  return MNG_NOERROR;
1562
}
1563
1564
/* ************************************************************************** */
1565
1566
mng_retcode restore_state (mng_datap pData)
1567
{
1568
  mng_savedatap pSave;
1569
  mng_imagep    pImage;
1570
  mng_retcode   iRetcode;
1571
1572
#ifdef MNG_SUPPORT_TRACE
1573
  MNG_TRACE (pData, MNG_FN_RESTORE_STATE, MNG_LC_START)
1574
#endif
1575
                                       /* restore object 0 status !!! */
1576
  iRetcode = mng_reset_objzero (pData);
1577
1578
  if (iRetcode)                        /* on error bail out */
1579
    return iRetcode;
1580
                                       /* fresh cycle; fake no frames done yet */
1581
  pData->bFramedone             = MNG_FALSE;
1582
1583
  if (pData->pSavedata)                /* do we have a saved state ? */
1584
  {
1585
    pSave = pData->pSavedata;          /* address it more directly */
1586
                                       /* and copy it back to the main struct */
1587
#if defined(MNG_SUPPORT_READ) || defined(MNG_SUPPORT_WRITE)
1588
    pData->bHasglobalPLTE       = pSave->bHasglobalPLTE;
1589
    pData->bHasglobalTRNS       = pSave->bHasglobalTRNS;
1590
    pData->bHasglobalGAMA       = pSave->bHasglobalGAMA;
1591
    pData->bHasglobalCHRM       = pSave->bHasglobalCHRM;
1592
    pData->bHasglobalSRGB       = pSave->bHasglobalSRGB;
1593
    pData->bHasglobalICCP       = pSave->bHasglobalICCP;
1594
    pData->bHasglobalBKGD       = pSave->bHasglobalBKGD;
1595
#endif /* MNG_SUPPORT_READ || MNG_SUPPORT_WRITE */
1596
1597
    pData->iBACKred             = pSave->iBACKred;
1598
    pData->iBACKgreen           = pSave->iBACKgreen;
1599
    pData->iBACKblue            = pSave->iBACKblue;
1600
    pData->iBACKmandatory       = pSave->iBACKmandatory;
1601
    pData->iBACKimageid         = pSave->iBACKimageid;
1602
    pData->iBACKtile            = pSave->iBACKtile;
1603
1604
    pData->iFRAMmode            = pSave->iFRAMmode;
1605
    pData->iFRAMdelay           = pSave->iFRAMdelay;
1606
    pData->iFRAMtimeout         = pSave->iFRAMtimeout;
1607
    pData->bFRAMclipping        = pSave->bFRAMclipping;
1608
    pData->iFRAMclipl           = pSave->iFRAMclipl;
1609
    pData->iFRAMclipr           = pSave->iFRAMclipr;
1610
    pData->iFRAMclipt           = pSave->iFRAMclipt;
1611
    pData->iFRAMclipb           = pSave->iFRAMclipb;
1612
                                       /* also the next subframe parms */
1613
    pData->iFramemode           = pSave->iFRAMmode;
1614
    pData->iFramedelay          = pSave->iFRAMdelay;
1615
    pData->iFrametimeout        = pSave->iFRAMtimeout;
1616
    pData->bFrameclipping       = pSave->bFRAMclipping;
1617
    pData->iFrameclipl          = pSave->iFRAMclipl;
1618
    pData->iFrameclipr          = pSave->iFRAMclipr;
1619
    pData->iFrameclipt          = pSave->iFRAMclipt;
1620
    pData->iFrameclipb          = pSave->iFRAMclipb;
1621
1622
    pData->iNextdelay           = pSave->iFRAMdelay;
1623
1624
    pData->iGlobalPLTEcount     = pSave->iGlobalPLTEcount;
1625
    MNG_COPY (pData->aGlobalPLTEentries, pSave->aGlobalPLTEentries, sizeof (mng_rgbpaltab))
1626
1627
    pData->iGlobalTRNSrawlen    = pSave->iGlobalTRNSrawlen;
1628
    MNG_COPY (pData->aGlobalTRNSrawdata, pSave->aGlobalTRNSrawdata, 256)
1629
1630
    pData->iGlobalGamma         = pSave->iGlobalGamma;
1631
1632
    pData->iGlobalWhitepointx   = pSave->iGlobalWhitepointx;
1633
    pData->iGlobalWhitepointy   = pSave->iGlobalWhitepointy;
1634
    pData->iGlobalPrimaryredx   = pSave->iGlobalPrimaryredx;
1635
    pData->iGlobalPrimaryredy   = pSave->iGlobalPrimaryredy;
1636
    pData->iGlobalPrimarygreenx = pSave->iGlobalPrimarygreenx;
1637
    pData->iGlobalPrimarygreeny = pSave->iGlobalPrimarygreeny;
1638
    pData->iGlobalPrimarybluex  = pSave->iGlobalPrimarybluex;
1639
    pData->iGlobalPrimarybluey  = pSave->iGlobalPrimarybluey;
1640
1641
    pData->iGlobalRendintent    = pSave->iGlobalRendintent;
1642
1643
    pData->iGlobalProfilesize   = pSave->iGlobalProfilesize;
1644
1645
    if (pData->iGlobalProfilesize)     /* has a profile ? */
1646
    {                                  /* then copy that ! */
1647
      MNG_ALLOC (pData, pData->pGlobalProfile, pData->iGlobalProfilesize)
1648
      MNG_COPY (pData->pGlobalProfile, pSave->pGlobalProfile, pData->iGlobalProfilesize)
1649
    }
1650
1651
    pData->iGlobalBKGDred       = pSave->iGlobalBKGDred;
1652
    pData->iGlobalBKGDgreen     = pSave->iGlobalBKGDgreen;
1653
    pData->iGlobalBKGDblue      = pSave->iGlobalBKGDblue;
1654
  }
1655
  else                                 /* no saved-data; so reset the lot */
1656
  {
1657
#if defined(MNG_SUPPORT_READ) || defined(MNG_SUPPORT_WRITE)
1658
    pData->bHasglobalPLTE       = MNG_FALSE;
1659
    pData->bHasglobalTRNS       = MNG_FALSE;
1660
    pData->bHasglobalGAMA       = MNG_FALSE;
1661
    pData->bHasglobalCHRM       = MNG_FALSE;
1662
    pData->bHasglobalSRGB       = MNG_FALSE;
1663
    pData->bHasglobalICCP       = MNG_FALSE;
1664
    pData->bHasglobalBKGD       = MNG_FALSE;
1665
#endif /* MNG_SUPPORT_READ || MNG_SUPPORT_WRITE */
1666
1667
    if (!pData->bEMNGMAhack)             /* TODO: remove line in 1.0.0 !!! */
1668
    {                                    /* TODO: remove line in 1.0.0 !!! */
1669
    pData->iBACKred             = 0;
1670
    pData->iBACKgreen           = 0;
1671
    pData->iBACKblue            = 0;
1672
    pData->iBACKmandatory       = 0;
1673
    pData->iBACKimageid         = 0;
1674
    pData->iBACKtile            = 0;
1675
    }                                    /* TODO: remove line in 1.0.0 !!! */
1676
1677
    pData->iFRAMmode            = 1;
1678
    pData->iFRAMdelay           = 1;
1679
    pData->iFRAMtimeout         = 0x7fffffffl;
1680
    pData->bFRAMclipping        = MNG_FALSE;
1681
    pData->iFRAMclipl           = 0;
1682
    pData->iFRAMclipr           = 0;
1683
    pData->iFRAMclipt           = 0;
1684
    pData->iFRAMclipb           = 0;
1685
                                         /* also the next subframe parms */
1686
    pData->iFramemode           = 1;
1687
    pData->iFramedelay          = 1;
1688
    pData->iFrametimeout        = 0x7fffffffl;
1689
    pData->bFrameclipping       = MNG_FALSE;
1690
    pData->iFrameclipl          = 0;
1691
    pData->iFrameclipr          = 0;
1692
    pData->iFrameclipt          = 0;
1693
    pData->iFrameclipb          = 0;
1694
1695
    pData->iNextdelay           = 1;
1696
1697
    pData->iGlobalPLTEcount     = 0;
1698
1699
    pData->iGlobalTRNSrawlen    = 0;
1700
1701
    pData->iGlobalGamma         = 0;
1702
1703
    pData->iGlobalWhitepointx   = 0;
1704
    pData->iGlobalWhitepointy   = 0;
1705
    pData->iGlobalPrimaryredx   = 0;
1706
    pData->iGlobalPrimaryredy   = 0;
1707
    pData->iGlobalPrimarygreenx = 0;
1708
    pData->iGlobalPrimarygreeny = 0;
1709
    pData->iGlobalPrimarybluex  = 0;
1710
    pData->iGlobalPrimarybluey  = 0;
1711
1712
    pData->iGlobalRendintent    = 0;
1713
1714
    if (pData->iGlobalProfilesize)       /* free a previous profile ? */
1715
      MNG_FREE (pData, pData->pGlobalProfile, pData->iGlobalProfilesize)
1716
1717
    pData->iGlobalProfilesize   = 0;
1718
1719
    pData->iGlobalBKGDred       = 0;
1720
    pData->iGlobalBKGDgreen     = 0;
1721
    pData->iGlobalBKGDblue      = 0;
1722
  }
1723
1724
  if (!pData->bEMNGMAhack)             /* TODO: remove line in 1.0.0 !!! */
1725
  {                                    /* TODO: remove line in 1.0.0 !!! */
1726
                                       /* drop un-frozen image objects */
1727
  pImage = (mng_imagep)pData->pFirstimgobj;
1728
1729
  while (pImage)
1730
  {                                    /* is it un-frozen ? */
1731
    if (!pImage->bFrozen)
1732
    {
1733
      mng_imagep  pPrev = (mng_imagep)pImage->sHeader.pPrev;
1734
      mng_imagep  pNext = (mng_imagep)pImage->sHeader.pNext;
1735
1736
      if (pPrev)                       /* unlink it */
1737
        pPrev->sHeader.pNext = pNext;
1738
      else
1739
        pData->pFirstimgobj  = pNext;
1740
1741
      if (pNext)
1742
        pNext->sHeader.pPrev = pPrev;
1743
      else
1744
        pData->pLastimgobj   = pPrev;
1745
1746
      if (pImage->pImgbuf->bFrozen)    /* buffer frozen ? */
1747
      {
1748
        if (pImage->pImgbuf->iRefcount <= 2)
1749
          MNG_ERROR (pData, MNG_INTERNALERROR)
1750
                                       /* decrease ref counter */
1751
        pImage->pImgbuf->iRefcount--;
1752
                                       /* just cleanup the object then */
1753
        MNG_FREEX (pData, pImage, sizeof (mng_image))
1754
      }
1755
      else
1756
      {                                /* free the image buffer */
1757
        iRetcode = free_imagedataobject (pData, pImage->pImgbuf);
1758
                                       /* and cleanup the object */
1759
        MNG_FREEX (pData, pImage, sizeof (mng_image))
1760
1761
        if (iRetcode)                  /* on error bail out */
1762
          return iRetcode;
1763
      }
1764
1765
      pImage = pNext;                  /* this is the next */
1766
    }
1767
    else                               /* neeeext */
1768
      pImage = (mng_imagep)pImage->sHeader.pNext;
1769
1770
  }
1771
  }                                    /* TODO: remove line in 1.0.0 !!! */
1772
1773
#ifdef MNG_SUPPORT_TRACE
1774
  MNG_TRACE (pData, MNG_FN_RESTORE_STATE, MNG_LC_END)
1775
#endif
1776
1777
  return MNG_NOERROR;
1778
}
1779
1780
/* ************************************************************************** */
1781
/* *                                                                        * */
1782
/* * General display processing routine                                     * */
1783
/* *                                                                        * */
1784
/* ************************************************************************** */
1785
1786
mng_retcode process_display (mng_datap pData)
1787
{
1788
  mng_retcode iRetcode = MNG_NOERROR;
1789
1790
#ifdef MNG_SUPPORT_TRACE
1791
  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY, MNG_LC_START)
1792
#endif
1793
1794
  if (!pData->iBreakpoint)             /* not broken previously ? */
1795
  {
1796
    if ((pData->iRequestframe) || (pData->iRequestlayer) || (pData->iRequesttime))
1797
    {
1798
      pData->bSearching = MNG_TRUE;    /* indicate we're searching */
1799
1800
      iRetcode = clear_canvas (pData); /* make the canvas virgin black ?!? */
1801
1802
      if (iRetcode)                    /* on error bail out */
1803
        return iRetcode;
1804
                                       /* let's start from the top, shall we */
1805
      pData->pCurraniobj = pData->pFirstaniobj;
1806
    }
1807
  }
1808
1809
  do                                   /* process the objects */
1810
  {
1811
    if (pData->bSearching)             /* are we looking sor something ? */
1812
    {
1813
      if ((pData->iRequestframe) &&
1814
          (pData->iRequestframe < ((mng_object_headerp)pData->pCurraniobj)->iFramenr))
1815
      {
1816
        pData->iRequestframe = 0;      /* found the frame ! */
1817
        pData->bSearching    = MNG_FALSE;
1818
      }
1819
      else
1820
      if ((pData->iRequestlayer) &&
1821
          (pData->iRequestlayer < ((mng_object_headerp)pData->pCurraniobj)->iLayernr))
1822
      {
1823
        pData->iRequestlayer = 0;      /* found the layer ! */
1824
        pData->bSearching    = MNG_FALSE;
1825
      }
1826
      else
1827
      if ((pData->iRequesttime) &&
1828
          (pData->iRequesttime < ((mng_object_headerp)pData->pCurraniobj)->iPlaytime))
1829
      {
1830
        pData->iRequesttime  = 0;      /* found the playtime ! */
1831
        pData->bSearching    = MNG_FALSE;
1832
      }
1833
    }
1834
                                       /* do we need to finish something first ? */
1835
    if ((pData->iBreakpoint) && (pData->iBreakpoint < 99))
1836
    {
1837
      switch (pData->iBreakpoint)      /* return to broken display routine */
1838
      {
1839
        case 1  : { iRetcode = process_display_fram2 (pData); break; }
1840
        case 3  : ;                    /* same as 4 !!! */
1841
        case 4  : { iRetcode = process_display_show  (pData); break; }
1842
        case 5  : { iRetcode = process_display_clon2 (pData); break; }
1843
        case 9  : { iRetcode = process_display_magn2 (pData); break; }
1844
        default : MNG_ERROR (pData, MNG_INTERNALERROR)
1845
      }
1846
    }
1847
    else
1848
    {
1849
      if (pData->pCurraniobj)
1850
        iRetcode = ((mng_object_headerp)pData->pCurraniobj)->fProcess (pData, pData->pCurraniobj);
1851
    }
1852
1853
    if (!pData->bTimerset)             /* reset breakpoint flag ? */
1854
      pData->iBreakpoint = 0;
1855
                                       /* can we advance to next object ? */
1856
    if ((!iRetcode) && (pData->pCurraniobj) &&
1857
        (!pData->bTimerset) && (!pData->bSectionwait))
1858
    {
1859
      pData->pCurraniobj = ((mng_object_headerp)pData->pCurraniobj)->pNext;
1860
                                       /* MEND processing to be done ? */
1861
      if ((pData->eImagetype == mng_it_mng) && (!pData->pCurraniobj))
1862
        iRetcode = process_display_mend (pData);
1863
1864
      if (!pData->pCurraniobj)         /* refresh after last image ? */
1865
        pData->bNeedrefresh = MNG_TRUE;
1866
    }
1867
  }                                    /* until error or a break or no more objects */
1868
  while ((!iRetcode) && (pData->pCurraniobj) &&
1869
         (!pData->bTimerset) && (!pData->bSectionwait) && (!pData->bFreezing));
1870
1871
  if (iRetcode)                        /* on error bail out */
1872
    return iRetcode;
1873
                                       /* refresh needed ? */
1874
  if ((!pData->bTimerset) && (pData->bNeedrefresh))
1875
  {
1876
    iRetcode = display_progressive_refresh (pData, 1);
1877
1878
    if (iRetcode)                      /* on error bail out */
1879
      return iRetcode;
1880
  }
1881
                                       /* timer break ? */
1882
  if ((pData->bTimerset) && (!pData->iBreakpoint))
1883
    pData->iBreakpoint = 99;
1884
  else
1885
  if (!pData->bTimerset)
1886
    pData->iBreakpoint = 0;            /* reset if no timer break */
1887
1888
  if ((!pData->bTimerset) && (!pData->pCurraniobj))
1889
    pData->bRunning = MNG_FALSE;       /* all done now ! */
1890
1891
#ifdef MNG_SUPPORT_TRACE
1892
  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY, MNG_LC_END)
1893
#endif
1894
1895
  return MNG_NOERROR;
1896
}
1897
1898
/* ************************************************************************** */
1899
/* *                                                                        * */
1900
/* * Chunk display processing routines                                      * */
1901
/* *                                                                        * */
1902
/* ************************************************************************** */
1903
1904
mng_retcode process_display_ihdr (mng_datap pData)
1905
{                                      /* address the current "object" if any */
1906
  mng_imagep pImage = (mng_imagep)pData->pCurrentobj;
1907
1908
#ifdef MNG_SUPPORT_TRACE
1909
  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_IHDR, MNG_LC_START)
1910
#endif
1911
1912
  if (!pData->bHasDHDR)
1913
  {
1914
    pData->fInitrowproc = MNG_NULL;    /* do nothing by default */
1915
    pData->fDisplayrow  = MNG_NULL;
1916
    pData->fCorrectrow  = MNG_NULL;
1917
    pData->fStorerow    = MNG_NULL;
1918
    pData->fProcessrow  = MNG_NULL;
1919
    pData->fDifferrow   = MNG_NULL;
1920
    pData->pStoreobj    = MNG_NULL;
1921
  }
1922
1923
  if (!pData->iBreakpoint)             /* not previously broken ? */
1924
  {
1925
    mng_retcode iRetcode = MNG_NOERROR;
1926
1927
    if (pData->bHasDHDR)               /* is a delta-image ? */
1928
    {
1929
      if (pData->iDeltatype == MNG_DELTATYPE_REPLACE)
1930
        iRetcode = reset_object_details (pData, (mng_imagep)pData->pDeltaImage,
1931
                                         pData->iDatawidth, pData->iDataheight,
1932
                                         pData->iBitdepth, pData->iColortype,
1933
                                         pData->iCompression, pData->iFilter,
1934
                                         pData->iInterlace, MNG_TRUE);
1935
      else
1936
      if ((pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD    ) ||
1937
          (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)    )
1938
      {
1939
        ((mng_imagep)pData->pDeltaImage)->pImgbuf->iPixelsampledepth = pData->iBitdepth;
1940
        ((mng_imagep)pData->pDeltaImage)->pImgbuf->iAlphasampledepth = pData->iBitdepth;
1941
      }
1942
      else
1943
      if ((pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAADD    ) ||
1944
          (pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAREPLACE)    )
1945
        ((mng_imagep)pData->pDeltaImage)->pImgbuf->iAlphasampledepth = pData->iBitdepth;
1946
      else
1947
      if ((pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORADD    ) ||
1948
          (pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORREPLACE)    )
1949
        ((mng_imagep)pData->pDeltaImage)->pImgbuf->iPixelsampledepth = pData->iBitdepth;
1950
        
1951
                                       /* process immediatly if bitdepth & colortype are equal */
1952
      pData->bDeltaimmediate =
1953
        (mng_bool)((pData->iBitdepth  == ((mng_imagep)pData->pDeltaImage)->pImgbuf->iBitdepth ) &&
1954
                   (pData->iColortype == ((mng_imagep)pData->pDeltaImage)->pImgbuf->iColortype)    );
1955
    }
1956
    else
1957
    {
1958
      if (pImage)                      /* update object buffer ? */
1959
        iRetcode = reset_object_details (pData, pImage,
1960
                                         pData->iDatawidth, pData->iDataheight,
1961
                                         pData->iBitdepth, pData->iColortype,
1962
                                         pData->iCompression, pData->iFilter,
1963
                                         pData->iInterlace, MNG_TRUE);
1964
      else
1965
        iRetcode = reset_object_details (pData, (mng_imagep)pData->pObjzero,
1966
                                         pData->iDatawidth, pData->iDataheight,
1967
                                         pData->iBitdepth, pData->iColortype,
1968
                                         pData->iCompression, pData->iFilter,
1969
                                         pData->iInterlace, MNG_TRUE);
1970
    }
1971
1972
    if (iRetcode)                      /* on error bail out */
1973
      return iRetcode;
1974
  }
1975
1976
  if (!pData->bHasDHDR)
1977
  {
1978
    if (pImage)                        /* real object ? */
1979
      pData->pStoreobj = pImage;       /* tell the row routines */
1980
    else                               /* otherwise use object 0 */
1981
      pData->pStoreobj = pData->pObjzero;
1982
                                       /* display "on-the-fly" ? */
1983
    if ( (((mng_imagep)pData->pStoreobj)->iMAGN_MethodX == 0) &&
1984
         (((mng_imagep)pData->pStoreobj)->iMAGN_MethodY == 0) &&
1985
         ( (pData->eImagetype == mng_it_png         ) ||
1986
           (((mng_imagep)pData->pStoreobj)->bVisible)    )       )
1987
    {
1988
      next_layer (pData);              /* that's a new layer then ! */
1989
1990
      if (pData->bTimerset)            /* timer break ? */
1991
        pData->iBreakpoint = 2;
1992
      else
1993
      {
1994
        pData->iBreakpoint = 0;
1995
                                       /* anything to display ? */
1996
        if ((pData->iDestr > pData->iDestl) && (pData->iDestb > pData->iDestt))
1997
          set_display_routine (pData); /* then determine display routine */
1998
      }
1999
    }
2000
  }
2001
2002
  if (!pData->bTimerset)               /* no timer break ? */
2003
  {
2004
    switch (pData->iColortype)         /* determine row initialization routine */
2005
    {
2006
      case 0 : {                       /* gray */
2007
                 switch (pData->iBitdepth)
2008
                 {
2009
                   case  1 : {
2010
                               if (!pData->iInterlace)
2011
                                 pData->fInitrowproc = (mng_fptr)init_g1_ni;
2012
                               else
2013
                                 pData->fInitrowproc = (mng_fptr)init_g1_i;
2014
2015
                               break;
2016
                             }
2017
                   case  2 : {
2018
                               if (!pData->iInterlace)
2019
                                 pData->fInitrowproc = (mng_fptr)init_g2_ni;
2020
                               else
2021
                                 pData->fInitrowproc = (mng_fptr)init_g2_i;
2022
2023
                               break;
2024
                             }
2025
                   case  4 : {
2026
                               if (!pData->iInterlace)
2027
                                 pData->fInitrowproc = (mng_fptr)init_g4_ni;
2028
                               else
2029
                                 pData->fInitrowproc = (mng_fptr)init_g4_i;
2030
2031
                               break;
2032
                             }
2033
                   case  8 : {
2034
                               if (!pData->iInterlace)
2035
                                 pData->fInitrowproc = (mng_fptr)init_g8_ni;
2036
                               else
2037
                                 pData->fInitrowproc = (mng_fptr)init_g8_i;
2038
2039
                               break;
2040
                             }
2041
                   case 16 : {
2042
                               if (!pData->iInterlace)
2043
                                 pData->fInitrowproc = (mng_fptr)init_g16_ni;
2044
                               else
2045
                                 pData->fInitrowproc = (mng_fptr)init_g16_i;
2046
2047
                               break;
2048
                             }
2049
                 }
2050
2051
                 break;
2052
               }
2053
      case 2 : {                       /* rgb */
2054
                 switch (pData->iBitdepth)
2055
                 {
2056
                   case  8 : {
2057
                               if (!pData->iInterlace)
2058
                                 pData->fInitrowproc = (mng_fptr)init_rgb8_ni;
2059
                               else
2060
                                 pData->fInitrowproc = (mng_fptr)init_rgb8_i;
2061
2062
                               break;
2063
                             }
2064
                   case 16 : {
2065
                               if (!pData->iInterlace)
2066
                                 pData->fInitrowproc = (mng_fptr)init_rgb16_ni;
2067
                               else
2068
                                 pData->fInitrowproc = (mng_fptr)init_rgb16_i;
2069
2070
                               break;
2071
                             }
2072
                 }
2073
2074
                 break;
2075
               }
2076
      case 3 : {                       /* indexed */
2077
                 switch (pData->iBitdepth)
2078
                 {
2079
                   case  1 : {
2080
                               if (!pData->iInterlace)
2081
                                 pData->fInitrowproc = (mng_fptr)init_idx1_ni;
2082
                               else
2083
                                 pData->fInitrowproc = (mng_fptr)init_idx1_i;
2084
2085
                               break;
2086
                             }
2087
                   case  2 : {
2088
                               if (!pData->iInterlace)
2089
                                 pData->fInitrowproc = (mng_fptr)init_idx2_ni;
2090
                               else
2091
                                 pData->fInitrowproc = (mng_fptr)init_idx2_i;
2092
2093
                               break;
2094
                             }
2095
                   case  4 : {
2096
                               if (!pData->iInterlace)
2097
                                 pData->fInitrowproc = (mng_fptr)init_idx4_ni;
2098
                               else
2099
                                 pData->fInitrowproc = (mng_fptr)init_idx4_i;
2100
2101
                               break;
2102
                             }
2103
                   case  8 : {
2104
                               if (!pData->iInterlace)
2105
                                 pData->fInitrowproc = (mng_fptr)init_idx8_ni;
2106
                               else
2107
                                 pData->fInitrowproc = (mng_fptr)init_idx8_i;
2108
2109
                               break;
2110
                             }
2111
                 }
2112
2113
                 break;
2114
               }
2115
      case 4 : {                       /* gray+alpha */
2116
                 switch (pData->iBitdepth)
2117
                 {
2118
                   case  8 : {
2119
                               if (!pData->iInterlace)
2120
                                 pData->fInitrowproc = (mng_fptr)init_ga8_ni;
2121
                               else
2122
                                 pData->fInitrowproc = (mng_fptr)init_ga8_i;
2123
2124
                               break;
2125
                             }
2126
                   case 16 : {
2127
                               if (!pData->iInterlace)
2128
                                 pData->fInitrowproc = (mng_fptr)init_ga16_ni;
2129
                               else
2130
                                 pData->fInitrowproc = (mng_fptr)init_ga16_i;
2131
2132
                               break;
2133
                             }
2134
                 }
2135
2136
                 break;
2137
               }
2138
      case 6 : {                       /* rgb+alpha */
2139
                 switch (pData->iBitdepth)
2140
                 {
2141
                   case  8 : {
2142
                               if (!pData->iInterlace)
2143
                                 pData->fInitrowproc = (mng_fptr)init_rgba8_ni;
2144
                               else
2145
                                 pData->fInitrowproc = (mng_fptr)init_rgba8_i;
2146
2147
                               break;
2148
                             }
2149
                   case 16 : {
2150
                               if (!pData->iInterlace)
2151
                                 pData->fInitrowproc = (mng_fptr)init_rgba16_ni;
2152
                               else
2153
                                 pData->fInitrowproc = (mng_fptr)init_rgba16_i;
2154
2155
                               break;
2156
                             }
2157
                 }
2158
2159
                 break;
2160
               }
2161
    }
2162
2163
    pData->iFilterofs = 0;             /* determine filter characteristics */
2164
    pData->iLevel0    = 0;             /* default levels */
2165
    pData->iLevel1    = 0;    
2166
    pData->iLevel2    = 0;
2167
    pData->iLevel3    = 0;
2168
                                       /* leveling & differing ? */
2169
/*    if (pData->iFilter & 0x40)
2170
    {
2171
      switch (pData->iColortype)
2172
      {
2173
        case 0 : {
2174
                   if (pData->iBitdepth <= 8)
2175
                     pData->iFilterofs = 1;
2176
                   else
2177
                     pData->iFilterofs = 2;
2178
2179
                   break;
2180
                 }
2181
        case 2 : {
2182
                   if (pData->iBitdepth <= 8)
2183
                     pData->iFilterofs = 3;
2184
                   else
2185
                     pData->iFilterofs = 6;
2186
2187
                   break;
2188
                 }
2189
        case 3 : {
2190
                   pData->iFilterofs = 1;
2191
                   break;
2192
                 }
2193
        case 4 : {
2194
                   if (pData->iBitdepth <= 8)
2195
                     pData->iFilterofs = 2;
2196
                   else
2197
                     pData->iFilterofs = 4;
2198
2199
                   break;
2200
                 }
2201
        case 6 : {
2202
                   if (pData->iBitdepth <= 8)
2203
                     pData->iPixelofs  = 5;
2204
                   else
2205
                     pData->iFilterofs = 8;
2206
2207
                   break;
2208
                 }
2209
      }
2210
    } */
2211
                                       /* no adaptive filtering ? */
2212
/*    if (pData->iFilter & 0x01)
2213
      pData->iPixelofs = pData->iFilterofs;
2214
    else */
2215
      pData->iPixelofs = pData->iFilterofs + 1;
2216
2217
  }
2218
2219
#ifdef MNG_SUPPORT_TRACE
2220
  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_IHDR, MNG_LC_END)
2221
#endif
2222
2223
  return MNG_NOERROR;
2224
}
2225
2226
/* ************************************************************************** */
2227
2228
mng_retcode process_display_idat (mng_datap  pData,
2229
                                  mng_uint32 iRawlen,
2230
                                  mng_uint8p pRawdata)
2231
{
2232
  mng_retcode iRetcode = MNG_NOERROR;
2233
2234
#ifdef MNG_SUPPORT_TRACE
2235
  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_IDAT, MNG_LC_START)
2236
#endif
2237
2238
  if (pData->bRestorebkgd)             /* need to restore the background ? */
2239
  {
2240
    pData->bRestorebkgd = MNG_FALSE;
2241
    iRetcode            = load_bkgdlayer (pData);
2242
2243
    if (iRetcode)                      /* on error bail out */
2244
      return iRetcode;
2245
2246
    if ((pData->bDisplaying) && (pData->bRunning))
2247
      pData->iLayerseq++;              /* and it counts as a layer then ! */
2248
  }
2249
2250
  if (pData->fInitrowproc)             /* need to initialize row processing? */
2251
  {
2252
    iRetcode = ((mng_initrowproc)pData->fInitrowproc) (pData);
2253
    pData->fInitrowproc = MNG_NULL;    /* only call this once !!! */
2254
  }
2255
2256
  if ((!iRetcode) && (!pData->bInflating))
2257
                                       /* initialize inflate */
2258
    iRetcode = mngzlib_inflateinit (pData);
2259
2260
  if (!iRetcode)                       /* all ok? then inflate, my man */
2261
    iRetcode = mngzlib_inflaterows (pData, iRawlen, pRawdata);
2262
2263
  if (iRetcode)                        /* on error bail out */
2264
    return iRetcode;
2265
    
2266
#ifdef MNG_SUPPORT_TRACE
2267
  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_IDAT, MNG_LC_END)
2268
#endif
2269
2270
  return MNG_NOERROR;
2271
}
2272
2273
/* ************************************************************************** */
2274
2275
mng_retcode process_display_iend (mng_datap pData)
2276
{
2277
  mng_retcode iRetcode, iRetcode2;
2278
  mng_bool bDodisplay = MNG_FALSE;
2279
  mng_bool bMagnify   = MNG_FALSE;
2280
  mng_bool bCleanup   = (mng_bool)(pData->iBreakpoint != 0);
2281
2282
#ifdef MNG_SUPPORT_TRACE
2283
  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_IEND, MNG_LC_START)
2284
#endif
2285
2286
#ifdef MNG_INCLUDE_JNG                 /* progressive+alpha JNG can be displayed now */
2287
  if ( (pData->bHasJHDR                                         ) &&
2288
       ( (pData->bJPEGprogressive) || (pData->bJPEGprogressive2)) &&
2289
       ( (pData->eImagetype == mng_it_jng         ) ||
2290
         (((mng_imagep)pData->pStoreobj)->bVisible)             ) &&
2291
       ( (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGGRAYA ) ||
2292
         (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGCOLORA)    )    )
2293
    bDodisplay = MNG_TRUE;
2294
#endif
2295
2296
  if ( (pData->pStoreobj) &&           /* on-the-fly magnification ? */
2297
       ( (((mng_imagep)pData->pStoreobj)->iMAGN_MethodX) ||
2298
         (((mng_imagep)pData->pStoreobj)->iMAGN_MethodY)    ) )
2299
    bMagnify = MNG_TRUE;
2300
2301
  if ((pData->bHasBASI) ||             /* was it a BASI stream */
2302
      (bDodisplay)      ||             /* or should we display the JNG */
2303
      (bMagnify)        ||             /* or should we magnify it */
2304
                                       /* or did we get broken here last time ? */
2305
      ((pData->iBreakpoint) && (pData->iBreakpoint != 8)))
2306
  {
2307
    mng_imagep pImage = (mng_imagep)pData->pCurrentobj;
2308
2309
    if (!pImage)                       /* or was it object 0 ? */
2310
      pImage = (mng_imagep)pData->pObjzero;
2311
                                       /* display it now then ? */
2312
    if ((pImage->bVisible) && (pImage->bViewable))
2313
    {                                  /* ok, so do it */
2314
      iRetcode = display_image (pData, pImage, bDodisplay);
2315
2316
      if (iRetcode)                    /* on error bail out */
2317
        return iRetcode;
2318
2319
      if (pData->bTimerset)            /* timer break ? */
2320
        pData->iBreakpoint = 6;
2321
    }
2322
  }
2323
  else
2324
  if ((pData->bHasDHDR) ||             /* was it a DHDR stream */
2325
      (pData->iBreakpoint == 8))       /* or did we get broken here last time ? */
2326
  {
2327
    mng_imagep pImage = (mng_imagep)pData->pDeltaImage;
2328
2329
    if (!pData->iBreakpoint)
2330
    {                                  /* perform the delta operations needed */
2331
      iRetcode = execute_delta_image (pData, pImage, (mng_imagep)pData->pObjzero);
2332
2333
      if (iRetcode)                    /* on error bail out */
2334
        return iRetcode;
2335
    }
2336
                                       /* display it now then ? */
2337
    if ((pImage->bVisible) && (pImage->bViewable))
2338
    {                                  /* ok, so do it */
2339
      iRetcode = display_image (pData, pImage, MNG_FALSE);
2340
2341
      if (iRetcode)                    /* on error bail out */
2342
        return iRetcode;
2343
2344
      if (pData->bTimerset)            /* timer break ? */
2345
        pData->iBreakpoint = 8;
2346
    }
2347
  }
2348
2349
  if (!pData->bTimerset)               /* can we continue ? */
2350
  {
2351
    pData->iBreakpoint = 0;            /* clear this flag now ! */
2352
                                       /* cleanup object 0 */
2353
    reset_object_details (pData, (mng_imagep)pData->pObjzero,
2354
                          0, 0, 0, 0, 0, 0, 0, MNG_TRUE);
2355
2356
    if (pData->bInflating)             /* if we've been inflating */
2357
    {                                  /* cleanup row-processing, */
2358
      iRetcode  = cleanup_rowproc (pData);
2359
                                       /* also cleanup inflate! */
2360
      iRetcode2 = mngzlib_inflatefree (pData);
2361
2362
      if (iRetcode)                    /* on error bail out */
2363
        return iRetcode;
2364
      if (iRetcode2)
2365
        return iRetcode2;
2366
    }
2367
2368
#ifdef MNG_INCLUDE_JNG
2369
    if (pData->bJPEGdecompress)        /* if we've been decompressing JDAT */
2370
    {                                  /* cleanup row-processing, */
2371
      iRetcode  = cleanup_rowproc (pData);
2372
                                       /* also cleanup decompress! */
2373
      iRetcode2 = mngjpeg_decompressfree (pData);
2374
2375
      if (iRetcode)                    /* on error bail out */
2376
        return iRetcode;
2377
      if (iRetcode2)
2378
        return iRetcode2;
2379
    }
2380
2381
    if (pData->bJPEGdecompress2)       /* if we've been decompressing JDAA */
2382
    {                                  /* cleanup row-processing, */
2383
      iRetcode  = cleanup_rowproc (pData);
2384
                                       /* also cleanup decompress! */
2385
      iRetcode2 = mngjpeg_decompressfree2 (pData);
2386
2387
      if (iRetcode)                    /* on error bail out */
2388
        return iRetcode;
2389
      if (iRetcode2)
2390
        return iRetcode2;
2391
    }
2392
#endif
2393
2394
    if (bCleanup)                      /* if we got broken last time we need to cleanup */
2395
    {
2396
      pData->bHasIHDR = MNG_FALSE;     /* IEND signals the end for most ... */
2397
      pData->bHasBASI = MNG_FALSE;
2398
      pData->bHasDHDR = MNG_FALSE;
2399
#ifdef MNG_INCLUDE_JNG
2400
      pData->bHasJHDR = MNG_FALSE;
2401
      pData->bHasJSEP = MNG_FALSE;
2402
      pData->bHasJDAA = MNG_FALSE;
2403
      pData->bHasJDAT = MNG_FALSE;
2404
#endif
2405
      pData->bHasPLTE = MNG_FALSE;
2406
      pData->bHasTRNS = MNG_FALSE;
2407
      pData->bHasGAMA = MNG_FALSE;
2408
      pData->bHasCHRM = MNG_FALSE;
2409
      pData->bHasSRGB = MNG_FALSE;
2410
      pData->bHasICCP = MNG_FALSE;
2411
      pData->bHasBKGD = MNG_FALSE;
2412
      pData->bHasIDAT = MNG_FALSE;
2413
    }
2414
                                       /* if the image was displayed on the fly, */
2415
                                       /* we'll have to make the app refresh */
2416
    if ((pData->eImagetype != mng_it_mng) && (pData->fDisplayrow))
2417
      pData->bNeedrefresh = MNG_TRUE;
2418
     
2419
  }
2420
2421
#ifdef MNG_SUPPORT_TRACE
2422
  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_IEND, MNG_LC_END)
2423
#endif
2424
2425
  return MNG_NOERROR;
2426
}
2427
2428
/* ************************************************************************** */
2429
2430
mng_retcode process_display_mend (mng_datap pData)
2431
{
2432
#ifdef MNG_SUPPORT_TRACE
2433
  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_MEND, MNG_LC_START)
2434
#endif
2435
                                       /* TERM processed ? */
2436
  if ((pData->bDisplaying) && (pData->bRunning) &&
2437
      (pData->bHasTERM) && (pData->pTermaniobj))
2438
  {
2439
    mng_retcode   iRetcode;
2440
    mng_ani_termp pTERM;
2441
                                       /* get the right animation object ! */
2442
    pTERM = (mng_ani_termp)pData->pTermaniobj;
2443
2444
    pData->iIterations++;              /* increase iteration count */
2445
2446
    switch (pTERM->iTermaction)        /* determine what to do! */
2447
    {
2448
      case 0 : {                       /* show last frame indefinitly */
2449
                 break;                /* piece of cake, that is... */
2450
               }
2451
2452
      case 1 : {                       /* cease displaying anything */
2453
                 pData->bFrameclipping = MNG_FALSE;
2454
                 load_bkgdlayer (pData);
2455
                 break;
2456
               }
2457
2458
      case 2 : {                       /* show first image after TERM */
2459
2460
                 /* TODO: something */
2461
2462
                 break;
2463
               }
2464
2465
      case 3 : {                       /* repeat */
2466
                 if ((pTERM->iItermax) && (pTERM->iItermax < 0x7FFFFFFF))
2467
                   pTERM->iItermax--;
2468
2469
                 if (pTERM->iItermax)  /* go back to TERM ? */
2470
                 {                     /* restore to initial or SAVE state */
2471
                   iRetcode = restore_state (pData);
2472
2473
                   if (iRetcode)       /* on error bail out */
2474
                     return iRetcode;
2475
                                       /* notify the app ? */
2476
                   if (pData->fProcessmend)
2477
                   {
2478
                     mng_bool bOke = pData->fProcessmend ((mng_handle)pData,
2479
                                                          pData->iIterations,
2480
                                                          pTERM->iItermax);
2481
                     if (!bOke)        /* stop here and now ? */ 
2482
                       break;
2483
                   }
2484
                                       /* restart from TERM chunk */
2485
                   pData->pCurraniobj = pTERM;
2486
2487
                   if (pTERM->iDelay)  /* set the delay (?) */
2488
                   {
2489
                     mng_uint32 iWaitfor = 1000;
2490
                                       /* what are we aiming for */
2491
                     if (pData->iTicks)
2492
                     {                 /* honor speed modifier */
2493
                       switch (pData->iSpeed)
2494
                       {
2495
                         case mng_st_fast :
2496
                           {
2497
                             iWaitfor = (mng_uint32)(( 500 * pTERM->iDelay) / pData->iTicks);
2498
                             break;
2499
                           }
2500
                         case mng_st_slow :
2501
                           {
2502
                             iWaitfor = (mng_uint32)((3000 * pTERM->iDelay) / pData->iTicks);
2503
                             break;
2504
                           }
2505
                         case mng_st_slowest :
2506
                           {
2507
                             iWaitfor = (mng_uint32)((8000 * pTERM->iDelay) / pData->iTicks);
2508
                             break;
2509
                           }
2510
                         default :
2511
                           {
2512
                             iWaitfor = (mng_uint32)((1000 * pTERM->iDelay) / pData->iTicks);
2513
                           }
2514
                       }
2515
                     }
2516
2517
                     iRetcode = display_progressive_refresh (pData, iWaitfor);
2518
2519
                     if (iRetcode)     /* on error bail out */
2520
                       return iRetcode;
2521
                   }
2522
                 }
2523
                 else
2524
                 {
2525
                   switch (pTERM->iIteraction)
2526
                   {
2527
                     case 0 : {        /* show last frame indefinitly */
2528
                                break; /* piece of cake, that is... */
2529
                              }
2530
2531
                     case 1 : {        /* cease displaying anything */
2532
                                pData->bFrameclipping = MNG_FALSE;
2533
                                load_bkgdlayer (pData);
2534
                                break;
2535
                              }
2536
2537
                     case 2 : {        /* show first image after TERM */
2538
2539
                                /* TODO: something */
2540
2541
                                break;
2542
                              }
2543
2544
                   }
2545
                 }
2546
2547
                 break;
2548
               }
2549
2550
    }
2551
  }
2552
2553
  if (!pData->pCurraniobj)             /* always let the app refresh at the end ! */
2554
    pData->bNeedrefresh = MNG_TRUE;
2555
2556
#ifdef MNG_SUPPORT_TRACE
2557
  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_MEND, MNG_LC_END)
2558
#endif
2559
2560
  return MNG_NOERROR;
2561
}
2562
2563
/* ************************************************************************** */
2564
2565
mng_retcode process_display_defi (mng_datap pData)
2566
{
2567
  mng_imagep pImage;
2568
2569
#ifdef MNG_SUPPORT_TRACE
2570
  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_DEFI, MNG_LC_START)
2571
#endif
2572
2573
  if (!pData->iDEFIobjectid)           /* object id=0 ? */
2574
  {
2575
    pImage             = (mng_imagep)pData->pObjzero;
2576
2577
    if (pData->bDEFIhasdonotshow)
2578
      pImage->bVisible = (mng_bool)(pData->iDEFIdonotshow == 0);
2579
2580
    if (pData->bDEFIhasloca)
2581
    {
2582
      pImage->iPosx    = pData->iDEFIlocax;
2583
      pImage->iPosy    = pData->iDEFIlocay;
2584
    }
2585
2586
    if (pData->bDEFIhasclip)
2587
    {
2588
      pImage->bClipped = pData->bDEFIhasclip;
2589
      pImage->iClipl   = pData->iDEFIclipl;
2590
      pImage->iClipr   = pData->iDEFIclipr;
2591
      pImage->iClipt   = pData->iDEFIclipt;
2592
      pImage->iClipb   = pData->iDEFIclipb;
2593
    }
2594
2595
    pData->pCurrentobj = 0;            /* not a real object ! */
2596
  }
2597
  else
2598
  {                                    /* already exists ? */
2599
    pImage = (mng_imagep)find_imageobject (pData, pData->iDEFIobjectid);
2600
2601
    if (!pImage)                       /* if not; create new */
2602
    {
2603
      mng_retcode iRetcode = create_imageobject (pData, pData->iDEFIobjectid,
2604
                                                 (mng_bool)(pData->iDEFIconcrete == 1),
2605
                                                 (mng_bool)(pData->iDEFIdonotshow == 0),
2606
                                                 MNG_FALSE, 0, 0, 0, 0, 0, 0, 0,
2607
                                                 pData->iDEFIlocax, pData->iDEFIlocay,
2608
                                                 pData->bDEFIhasclip,
2609
                                                 pData->iDEFIclipl, pData->iDEFIclipr,
2610
                                                 pData->iDEFIclipt, pData->iDEFIclipb,
2611
                                                 &pImage);
2612
2613
      if (iRetcode)                    /* on error bail out */
2614
        return iRetcode;
2615
    }
2616
    else
2617
    {                                  /* exists; then set new info */
2618
      if (pData->bDEFIhasdonotshow)
2619
        pImage->bVisible = (mng_bool)(pData->iDEFIdonotshow == 0);
2620
2621
      pImage->bViewable  = MNG_FALSE;
2622
2623
      if (pData->bDEFIhasloca)
2624
      {
2625
        pImage->iPosx    = pData->iDEFIlocax;
2626
        pImage->iPosy    = pData->iDEFIlocay;
2627
      }
2628
2629
      if (pData->bDEFIhasclip)
2630
      {
2631
        pImage->bClipped = pData->bDEFIhasclip;
2632
        pImage->iClipl   = pData->iDEFIclipl;
2633
        pImage->iClipr   = pData->iDEFIclipr;
2634
        pImage->iClipt   = pData->iDEFIclipt;
2635
        pImage->iClipb   = pData->iDEFIclipb;
2636
      }
2637
2638
      if (pData->bDEFIhasconcrete)
2639
        pImage->pImgbuf->bConcrete = (mng_bool)(pData->iDEFIconcrete == 1);
2640
    }
2641
2642
    pData->pCurrentobj = pImage;       /* others may want to know this */
2643
  }
2644
2645
#ifdef MNG_SUPPORT_TRACE
2646
  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_DEFI, MNG_LC_END)
2647
#endif
2648
2649
  return MNG_NOERROR;
2650
}
2651
2652
/* ************************************************************************** */
2653
2654
mng_retcode process_display_basi (mng_datap  pData,
2655
                                  mng_uint16 iRed,
2656
                                  mng_uint16 iGreen,
2657
                                  mng_uint16 iBlue,
2658
                                  mng_bool   bHasalpha,
2659
                                  mng_uint16 iAlpha,
2660
                                  mng_uint8  iViewable)
2661
{                                      /* address the current "object" if any */
2662
  mng_imagep     pImage = (mng_imagep)pData->pCurrentobj;
2663
  mng_uint8p     pWork;
2664
  mng_uint32     iX;
2665
  mng_imagedatap pBuf;
2666
  mng_retcode    iRetcode;
2667
2668
#ifdef MNG_SUPPORT_TRACE
2669
  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_BASI, MNG_LC_START)
2670
#endif
2671
2672
  if (!pImage)                         /* or is it an "on-the-fly" image ? */
2673
    pImage = (mng_imagep)pData->pObjzero;
2674
                                       /* address the object-buffer */
2675
  pBuf               = pImage->pImgbuf;
2676
2677
  pData->fDisplayrow = MNG_NULL;       /* do nothing by default */
2678
  pData->fCorrectrow = MNG_NULL;
2679
  pData->fStorerow   = MNG_NULL;
2680
  pData->fProcessrow = MNG_NULL;
2681
                                       /* set parms now that they're known */
2682
  iRetcode = reset_object_details (pData, pImage, pData->iDatawidth,
2683
                                   pData->iDataheight, pData->iBitdepth,
2684
                                   pData->iColortype, pData->iCompression,
2685
                                   pData->iFilter, pData->iInterlace, MNG_FALSE);
2686
  if (iRetcode)                        /* on error bail out */
2687
    return iRetcode;
2688
                                       /* save the viewable flag */
2689
  pImage->bViewable = (mng_bool)(iViewable == 1);
2690
  pBuf->bViewable   = pImage->bViewable;
2691
  pData->pStoreobj  = pImage;          /* let row-routines know which object */
2692
2693
  pWork = pBuf->pImgdata;              /* fill the object-buffer with the specified
2694
                                          "color" sample */
2695
  switch (pData->iColortype)           /* depending on color_type & bit_depth */
2696
  {
2697
    case 0 : {                         /* gray */
2698
               if (pData->iBitdepth == 16)
2699
               {
2700
                 for (iX = 0; iX < pData->iDatawidth * pData->iDataheight; iX++)
2701
                 {
2702
                   mng_put_uint16 (pWork, iRed);
2703
                   pWork += 2;
2704
                 }
2705
               }
2706
               else
2707
               {
2708
                 for (iX = 0; iX < pData->iDatawidth * pData->iDataheight; iX++)
2709
                 {
2710
                   *pWork = (mng_uint8)iRed;
2711
                   pWork++;
2712
                 }
2713
               }
2714
                                       /* force tRNS ? */
2715
               if ((bHasalpha) && (!iAlpha))
2716
               {
2717
                 pBuf->bHasTRNS  = MNG_TRUE;
2718
                 pBuf->iTRNSgray = iRed;
2719
               }
2720
2721
               break;
2722
             }
2723
2724
    case 2 : {                         /* rgb */
2725
               if (pData->iBitdepth == 16)
2726
               {
2727
                 for (iX = 0; iX < pData->iDatawidth * pData->iDataheight; iX++)
2728
                 {
2729
                   mng_put_uint16 (pWork,   iRed  );
2730
                   mng_put_uint16 (pWork+2, iGreen);
2731
                   mng_put_uint16 (pWork+4, iBlue );
2732
                   pWork += 6;
2733
                 }
2734
               }
2735
               else
2736
               {
2737
                 for (iX = 0; iX < pData->iDatawidth * pData->iDataheight; iX++)
2738
                 {
2739
                   *pWork     = (mng_uint8)iRed;
2740
                   *(pWork+1) = (mng_uint8)iGreen;
2741
                   *(pWork+2) = (mng_uint8)iBlue;
2742
                   pWork += 3;
2743
                 }
2744
               }
2745
                                       /* force tRNS ? */
2746
               if ((bHasalpha) && (!iAlpha))
2747
               {
2748
                 pBuf->bHasTRNS   = MNG_TRUE;
2749
                 pBuf->iTRNSred   = iRed;
2750
                 pBuf->iTRNSgreen = iGreen;
2751
                 pBuf->iTRNSblue  = iBlue;
2752
               }
2753
2754
               break;
2755
             }
2756
2757
    case 3 : {                         /* indexed */
2758
               pBuf->bHasPLTE = MNG_TRUE;
2759
2760
               switch (pData->iBitdepth)
2761
               {
2762
                 case 1  : { pBuf->iPLTEcount =   2; break; }
2763
                 case 2  : { pBuf->iPLTEcount =   4; break; }
2764
                 case 4  : { pBuf->iPLTEcount =  16; break; }
2765
                 case 8  : { pBuf->iPLTEcount = 256; break; }
2766
                 default : { pBuf->iPLTEcount =   1; break; }
2767
               }
2768
2769
               pBuf->aPLTEentries [0].iRed   = (mng_uint8)iRed;
2770
               pBuf->aPLTEentries [0].iGreen = (mng_uint8)iGreen;
2771
               pBuf->aPLTEentries [0].iBlue  = (mng_uint8)iBlue;
2772
2773
               for (iX = 1; iX < pBuf->iPLTEcount; iX++)
2774
               {
2775
                 pBuf->aPLTEentries [iX].iRed   = 0;
2776
                 pBuf->aPLTEentries [iX].iGreen = 0;
2777
                 pBuf->aPLTEentries [iX].iBlue  = 0;
2778
               }
2779
                                       /* force tRNS ? */
2780
               if ((bHasalpha) && (iAlpha < 255))
2781
               {
2782
                 pBuf->bHasTRNS         = MNG_TRUE;
2783
                 pBuf->iTRNScount       = 1;
2784
                 pBuf->aTRNSentries [0] = (mng_uint8)iAlpha;
2785
               }
2786
2787
               break;
2788
             }
2789
2790
    case 4 : {                         /* gray+alpha */
2791
               if (pData->iBitdepth == 16)
2792
               {
2793
                 for (iX = 0; iX < pData->iDatawidth * pData->iDataheight; iX++)
2794
                 {
2795
                   mng_put_uint16 (pWork,   iRed);
2796
                   mng_put_uint16 (pWork+2, iAlpha);
2797
                   pWork += 4;
2798
                 }
2799
               }
2800
               else
2801
               {
2802
                 for (iX = 0; iX < pData->iDatawidth * pData->iDataheight; iX++)
2803
                 {
2804
                   *pWork     = (mng_uint8)iRed;
2805
                   *(pWork+1) = (mng_uint8)iAlpha;
2806
                   pWork += 2;
2807
                 }
2808
               }
2809
2810
               break;
2811
             }
2812
2813
    case 6 : {                         /* rgb+alpha */
2814
               if (pData->iBitdepth == 16)
2815
               {
2816
                 for (iX = 0; iX < pData->iDatawidth * pData->iDataheight; iX++)
2817
                 {
2818
                   mng_put_uint16 (pWork,   iRed);
2819
                   mng_put_uint16 (pWork+2, iGreen);
2820
                   mng_put_uint16 (pWork+4, iBlue);
2821
                   mng_put_uint16 (pWork+6, iAlpha);
2822
                   pWork += 8;
2823
                 }
2824
               }
2825
               else
2826
               {
2827
                 for (iX = 0; iX < pData->iDatawidth * pData->iDataheight; iX++)
2828
                 {
2829
                   *pWork     = (mng_uint8)iRed;
2830
                   *(pWork+1) = (mng_uint8)iGreen;
2831
                   *(pWork+2) = (mng_uint8)iBlue;
2832
                   *(pWork+3) = (mng_uint8)iAlpha;
2833
                   pWork += 4;
2834
                 }
2835
               }
2836
2837
               break;
2838
             }
2839
2840
  }
2841
2842
  switch (pData->iColortype)           /* determine row initialization routine */
2843
  {                                    /* just to accomodate IDAT if it arrives */
2844
    case 0 : {                         /* gray */
2845
               switch (pData->iBitdepth)
2846
               {
2847
                 case  1 : {
2848
                             if (!pData->iInterlace)
2849
                               pData->fInitrowproc = (mng_fptr)init_g1_ni;
2850
                             else
2851
                               pData->fInitrowproc = (mng_fptr)init_g1_i;
2852
2853
                             break;
2854
                           }
2855
                 case  2 : {
2856
                             if (!pData->iInterlace)
2857
                               pData->fInitrowproc = (mng_fptr)init_g2_ni;
2858
                             else
2859
                               pData->fInitrowproc = (mng_fptr)init_g2_i;
2860
2861
                             break;
2862
                           }
2863
                 case  4 : {
2864
                             if (!pData->iInterlace)
2865
                               pData->fInitrowproc = (mng_fptr)init_g4_ni;
2866
                             else
2867
                               pData->fInitrowproc = (mng_fptr)init_g4_i;
2868
2869
                             break;
2870
                           }
2871
                 case  8 : {
2872
                             if (!pData->iInterlace)
2873
                               pData->fInitrowproc = (mng_fptr)init_g8_ni;
2874
                             else
2875
                               pData->fInitrowproc = (mng_fptr)init_g8_i;
2876
2877
                             break;
2878
                           }
2879
                 case 16 : {
2880
                             if (!pData->iInterlace)
2881
                               pData->fInitrowproc = (mng_fptr)init_g16_ni;
2882
                             else
2883
                               pData->fInitrowproc = (mng_fptr)init_g16_i;
2884
2885
                             break;
2886
                           }
2887
               }
2888
2889
               break;
2890
             }
2891
    case 2 : {                         /* rgb */
2892
               switch (pData->iBitdepth)
2893
               {
2894
                 case  8 : {
2895
                             if (!pData->iInterlace)
2896
                               pData->fInitrowproc = (mng_fptr)init_rgb8_ni;
2897
                             else
2898
                               pData->fInitrowproc = (mng_fptr)init_rgb8_i;
2899
2900
                             break;
2901
                           }
2902
                 case 16 : {
2903
                             if (!pData->iInterlace)
2904
                               pData->fInitrowproc = (mng_fptr)init_rgb16_ni;
2905
                             else
2906
                               pData->fInitrowproc = (mng_fptr)init_rgb16_i;
2907
2908
                             break;
2909
                           }
2910
               }
2911
2912
               break;
2913
             }
2914
    case 3 : {                         /* indexed */
2915
               switch (pData->iBitdepth)
2916
               {
2917
                 case  1 : {
2918
                             if (!pData->iInterlace)
2919
                               pData->fInitrowproc = (mng_fptr)init_idx1_ni;
2920
                             else
2921
                               pData->fInitrowproc = (mng_fptr)init_idx1_i;
2922
2923
                             break;
2924
                           }
2925
                 case  2 : {
2926
                             if (!pData->iInterlace)
2927
                               pData->fInitrowproc = (mng_fptr)init_idx2_ni;
2928
                             else
2929
                               pData->fInitrowproc = (mng_fptr)init_idx2_i;
2930
2931
                             break;
2932
                           }
2933
                 case  4 : {
2934
                             if (!pData->iInterlace)
2935
                               pData->fInitrowproc = (mng_fptr)init_idx4_ni;
2936
                             else
2937
                               pData->fInitrowproc = (mng_fptr)init_idx4_i;
2938
2939
                             break;
2940
                           }
2941
                 case  8 : {
2942
                             if (!pData->iInterlace)
2943
                               pData->fInitrowproc = (mng_fptr)init_idx8_ni;
2944
                             else
2945
                               pData->fInitrowproc = (mng_fptr)init_idx8_i;
2946
2947
                             break;
2948
                           }
2949
               }
2950
2951
               break;
2952
             }
2953
    case 4 : {                         /* gray+alpha */
2954
               switch (pData->iBitdepth)
2955
               {
2956
                 case  8 : {
2957
                             if (!pData->iInterlace)
2958
                               pData->fInitrowproc = (mng_fptr)init_ga8_ni;
2959
                             else
2960
                               pData->fInitrowproc = (mng_fptr)init_ga8_i;
2961
2962
                             break;
2963
                           }
2964
                 case 16 : {
2965
                             if (!pData->iInterlace)
2966
                               pData->fInitrowproc = (mng_fptr)init_ga16_ni;
2967
                             else
2968
                               pData->fInitrowproc = (mng_fptr)init_ga16_i;
2969
2970
                             break;
2971
                           }
2972
               }
2973
2974
               break;
2975
             }
2976
    case 6 : {                         /* rgb+alpha */
2977
               switch (pData->iBitdepth)
2978
               {
2979
                 case  8 : {
2980
                             if (!pData->iInterlace)
2981
                               pData->fInitrowproc = (mng_fptr)init_rgba8_ni;
2982
                             else
2983
                               pData->fInitrowproc = (mng_fptr)init_rgba8_i;
2984
2985
                             break;
2986
                           }
2987
                 case 16 : {
2988
                             if (!pData->iInterlace)
2989
                               pData->fInitrowproc = (mng_fptr)init_rgba16_ni;
2990
                             else
2991
                               pData->fInitrowproc = (mng_fptr)init_rgba16_i;
2992
2993
                             break;
2994
                           }
2995
               }
2996
2997
               break;
2998
             }
2999
  }
3000
3001
  pData->iFilterofs = 0;               /* determine filter characteristics */
3002
  pData->iLevel0    = 0;               /* default levels */
3003
  pData->iLevel1    = 0;
3004
  pData->iLevel2    = 0;
3005
  pData->iLevel3    = 0;
3006
                                       /* leveling & differing ? */
3007
/*  if (pData->iFilter & 0x40)
3008
  {
3009
    switch (pData->iColortype)
3010
    {
3011
      case 0 : {
3012
                 if (pData->iBitdepth <= 8)
3013
                   pData->iFilterofs = 1;
3014
                 else
3015
                   pData->iFilterofs = 2;
3016
3017
                 break;
3018
               }
3019
      case 2 : {
3020
                 if (pData->iBitdepth <= 8)
3021
                   pData->iFilterofs = 3;
3022
                 else
3023
                   pData->iFilterofs = 6;
3024
3025
                 break;
3026
               }
3027
      case 3 : {
3028
                 pData->iFilterofs = 1;
3029
                 break;
3030
               }
3031
      case 4 : {
3032
                 if (pData->iBitdepth <= 8)
3033
                   pData->iFilterofs = 2;
3034
                 else
3035
                   pData->iFilterofs = 4;
3036
3037
                 break;
3038
               }
3039
      case 6 : {
3040
                 if (pData->iBitdepth <= 8)
3041
                   pData->iPixelofs  = 5;
3042
                 else
3043
                   pData->iFilterofs = 8;
3044
3045
                 break;
3046
               }
3047
    }
3048
  } */
3049
                                       /* no adaptive filtering ? */
3050
/*  if (pData->iFilter & 0x01)
3051
    pData->iPixelofs = pData->iFilterofs;
3052
  else */
3053
    pData->iPixelofs = pData->iFilterofs + 1;
3054
3055
#ifdef MNG_SUPPORT_TRACE
3056
  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_BASI, MNG_LC_END)
3057
#endif
3058
3059
  return MNG_NOERROR;
3060
}
3061
3062
/* ************************************************************************** */
3063
3064
mng_retcode process_display_clon (mng_datap  pData,
3065
                                  mng_uint16 iSourceid,
3066
                                  mng_uint16 iCloneid,
3067
                                  mng_uint8  iClonetype,
3068
                                  mng_bool   bHasdonotshow,
3069
                                  mng_uint8  iDonotshow,
3070
                                  mng_uint8  iConcrete,
3071
                                  mng_bool   bHasloca,
3072
                                  mng_uint8  iLocationtype,
3073
                                  mng_int32  iLocationx,
3074
                                  mng_int32  iLocationy)
3075
{
3076
  mng_imagep  pSource, pClone;
3077
  mng_bool    bVisible, bAbstract;
3078
  mng_retcode iRetcode = MNG_NOERROR;
3079
3080
#ifdef MNG_SUPPORT_TRACE
3081
  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_CLON, MNG_LC_START)
3082
#endif
3083
                                       /* locate the source object first */
3084
  pSource = find_imageobject (pData, iSourceid);
3085
                                       /* check if the clone exists */
3086
  pClone  = find_imageobject (pData, iCloneid);
3087
3088
  if (!pSource)                        /* source must exist ! */
3089
    MNG_ERROR (pData, MNG_OBJECTUNKNOWN);
3090
3091
  if (pClone)                          /* clone must not exist ! */
3092
    MNG_ERROR (pData, MNG_OBJECTEXISTS);
3093
3094
  if (bHasdonotshow)                   /* DoNotShow flag filled ? */
3095
    bVisible = (mng_bool)(iDonotshow == 0);
3096
  else
3097
    bVisible = pSource->bVisible;
3098
3099
  bAbstract  = (mng_bool)(iConcrete == 1);
3100
3101
  switch (iClonetype)                  /* determine action to take */
3102
  {
3103
    case 0 : {                         /* full clone */
3104
               iRetcode = clone_imageobject (pData, iCloneid, MNG_FALSE,
3105
                                             bVisible, bAbstract, bHasloca,
3106
                                             iLocationtype, iLocationx, iLocationy,
3107
                                             pSource, &pClone);
3108
               break;
3109
             }
3110
3111
    case 1 : {                         /* partial clone */
3112
               iRetcode = clone_imageobject (pData, iCloneid, MNG_TRUE,
3113
                                             bVisible, bAbstract, bHasloca,
3114
                                             iLocationtype, iLocationx, iLocationy,
3115
                                             pSource, &pClone);
3116
               break;
3117
             }
3118
3119
    case 2 : {                         /* renumber object */
3120
               iRetcode = renum_imageobject (pData, pSource, iCloneid,
3121
                                             bVisible, bAbstract, bHasloca,
3122
                                             iLocationtype, iLocationx, iLocationy);
3123
               pClone   = pSource;
3124
               break;
3125
             }
3126
3127
  }
3128
3129
  if (iRetcode)                        /* on error bail out */
3130
    return iRetcode;
3131
3132
                                       /* display on the fly ? */
3133
  if ((pClone->bViewable) && (pClone->bVisible))
3134
  {
3135
    pData->pLastclone = pClone;        /* remember in case of timer break ! */
3136
                                       /* display it */
3137
    display_image (pData, pClone, MNG_FALSE);
3138
3139
    if (pData->bTimerset)              /* timer break ? */
3140
      pData->iBreakpoint = 5;
3141
  }
3142
3143
#ifdef MNG_SUPPORT_TRACE
3144
  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_CLON, MNG_LC_END)
3145
#endif
3146
3147
  return MNG_NOERROR;
3148
}
3149
3150
/* ************************************************************************** */
3151
3152
mng_retcode process_display_clon2 (mng_datap pData)
3153
{
3154
#ifdef MNG_SUPPORT_TRACE
3155
  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_CLON, MNG_LC_START)
3156
#endif
3157
                                       /* only called after timer break ! */
3158
  display_image (pData, (mng_imagep)pData->pLastclone, MNG_FALSE);
3159
  pData->iBreakpoint = 0;
3160
3161
#ifdef MNG_SUPPORT_TRACE
3162
  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_CLON, MNG_LC_END)
3163
#endif
3164
3165
  return MNG_NOERROR;
3166
}
3167
3168
/* ************************************************************************** */
3169
3170
mng_retcode process_display_disc (mng_datap   pData,
3171
                                  mng_uint32  iCount,
3172
                                  mng_uint16p pIds)
3173
{
3174
  mng_uint32 iX;
3175
  mng_imagep pImage;
3176
  mng_uint32 iRetcode;
3177
#ifdef MNG_SUPPORT_TRACE
3178
  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_DISC, MNG_LC_START)
3179
#endif
3180
3181
  if (iCount)                          /* specific list ? */
3182
  {
3183
    mng_uint16p pWork = pIds;
3184
3185
    for (iX = 0; iX < iCount; iX++)    /* iterate the list */
3186
    {
3187
      pImage = find_imageobject (pData, *pWork++);
3188
3189
      if (pImage)                      /* found the object ? */
3190
      {                                /* then drop it */
3191
        iRetcode = free_imageobject (pData, pImage);
3192
3193
        if (iRetcode)                  /* on error bail out */
3194
          return iRetcode;
3195
      }
3196
    }
3197
  }
3198
  else                                 /* empty: drop all un-frozen objects */
3199
  {
3200
    mng_imagep pNext = (mng_imagep)pData->pFirstimgobj;
3201
3202
    while (pNext)                      /* any left ? */
3203
    {
3204
      pImage = pNext;
3205
      pNext  = pImage->sHeader.pNext;
3206
3207
      if (!pImage->bFrozen)            /* not frozen ? */
3208
      {                                /* then drop it */
3209
        iRetcode = free_imageobject (pData, pImage);
3210
3211
        if (iRetcode)                  /* on error bail out */
3212
          return iRetcode;
3213
      }
3214
    }
3215
  }
3216
3217
#ifdef MNG_SUPPORT_TRACE
3218
  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_DISC, MNG_LC_END)
3219
#endif
3220
3221
  return MNG_NOERROR;
3222
}
3223
3224
/* ************************************************************************** */
3225
3226
mng_retcode process_display_fram (mng_datap  pData,
3227
                                  mng_uint8  iFramemode,
3228
                                  mng_uint8  iChangedelay,
3229
                                  mng_uint32 iDelay,
3230
                                  mng_uint8  iChangetimeout,
3231
                                  mng_uint32 iTimeout,
3232
                                  mng_uint8  iChangeclipping,
3233
                                  mng_uint8  iCliptype,
3234
                                  mng_int32  iClipl,
3235
                                  mng_int32  iClipr,
3236
                                  mng_int32  iClipt,
3237
                                  mng_int32  iClipb)
3238
{
3239
  mng_retcode iRetcode;
3240
3241
#ifdef MNG_SUPPORT_TRACE
3242
  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_FRAM, MNG_LC_START)
3243
#endif
3244
                                       /* advance a frame then */
3245
  iRetcode = next_frame (pData, iFramemode, iChangedelay, iDelay,
3246
                         iChangetimeout, iTimeout, iChangeclipping,
3247
                         iCliptype, iClipl, iClipr, iClipt, iClipb);
3248
3249
  if (pData->bTimerset)                /* timer break ? */
3250
    pData->iBreakpoint = 1;
3251
3252
#ifdef MNG_SUPPORT_TRACE
3253
  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_FRAM, MNG_LC_END)
3254
#endif
3255
3256
  return iRetcode;
3257
}
3258
3259
/* ************************************************************************** */
3260
3261
mng_retcode process_display_fram2 (mng_datap pData)
3262
{
3263
  mng_retcode iRetcode;
3264
3265
#ifdef MNG_SUPPORT_TRACE
3266
  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_FRAM, MNG_LC_START)
3267
#endif
3268
                                       /* again; after the break */
3269
  iRetcode = next_frame (pData, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
3270
  pData->iBreakpoint = 0;              /* not again! */
3271
3272
#ifdef MNG_SUPPORT_TRACE
3273
  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_FRAM, MNG_LC_END)
3274
#endif
3275
3276
  return iRetcode;
3277
}
3278
3279
/* ************************************************************************** */
3280
3281
mng_retcode process_display_move (mng_datap  pData,
3282
                                  mng_uint16 iFromid,
3283
                                  mng_uint16 iToid,
3284
                                  mng_uint8  iMovetype,
3285
                                  mng_int32  iMovex,
3286
                                  mng_int32  iMovey)
3287
{
3288
  mng_uint16 iX;
3289
  mng_imagep pImage;
3290
3291
#ifdef MNG_SUPPORT_TRACE
3292
  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_MOVE, MNG_LC_START)
3293
#endif
3294
                                       /* iterate the list */
3295
  for (iX = iFromid; iX <= iToid; iX++)
3296
  {
3297
    if (!iX)                           /* object id=0 ? */
3298
      pImage = (mng_imagep)pData->pObjzero;
3299
    else
3300
      pImage = find_imageobject (pData, iX);
3301
3302
    if (pImage)                        /* object exists ? */
3303
    {
3304
      switch (iMovetype)
3305
      {
3306
        case 0 : {                     /* absolute */
3307
                   pImage->iPosx = iMovex;
3308
                   pImage->iPosy = iMovey;
3309
                   break;
3310
                 }
3311
        case 1 : {                     /* relative */
3312
                   pImage->iPosx = pImage->iPosx + iMovex;
3313
                   pImage->iPosy = pImage->iPosy + iMovey;
3314
                   break;
3315
                 }
3316
      }
3317
    }
3318
  }
3319
3320
#ifdef MNG_SUPPORT_TRACE
3321
  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_MOVE, MNG_LC_END)
3322
#endif
3323
3324
  return MNG_NOERROR;
3325
}
3326
3327
/* ************************************************************************** */
3328
3329
mng_retcode process_display_clip (mng_datap  pData,
3330
                                  mng_uint16 iFromid,
3331
                                  mng_uint16 iToid,
3332
                                  mng_uint8  iCliptype,
3333
                                  mng_int32  iClipl,
3334
                                  mng_int32  iClipr,
3335
                                  mng_int32  iClipt,
3336
                                  mng_int32  iClipb)
3337
{
3338
  mng_uint16 iX;
3339
  mng_imagep pImage;
3340
3341
#ifdef MNG_SUPPORT_TRACE
3342
  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_CLIP, MNG_LC_START)
3343
#endif
3344
                                       /* iterate the list */
3345
  for (iX = iFromid; iX <= iToid; iX++)
3346
  {
3347
    if (!iX)                           /* object id=0 ? */
3348
      pImage = (mng_imagep)pData->pObjzero;
3349
    else
3350
      pImage = find_imageobject (pData, iX);
3351
3352
    if (pImage)                        /* object exists ? */
3353
    {
3354
      switch (iCliptype)
3355
      {
3356
        case 0 : {                     /* absolute */
3357
                   pImage->bClipped = MNG_TRUE;
3358
                   pImage->iClipl   = iClipl;
3359
                   pImage->iClipr   = iClipr;
3360
                   pImage->iClipt   = iClipt;
3361
                   pImage->iClipb   = iClipb;
3362
                   break;
3363
                 }
3364
        case 1 : {                    /* relative */
3365
                   pImage->bClipped = MNG_TRUE;
3366
                   pImage->iClipl   = pImage->iClipl + iClipl;
3367
                   pImage->iClipr   = pImage->iClipr + iClipr;
3368
                   pImage->iClipt   = pImage->iClipt + iClipt;
3369
                   pImage->iClipb   = pImage->iClipb + iClipb;
3370
                   break;
3371
                 }
3372
      }
3373
    }
3374
  }
3375
3376
#ifdef MNG_SUPPORT_TRACE
3377
  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_CLIP, MNG_LC_END)
3378
#endif
3379
3380
  return MNG_NOERROR;
3381
}
3382
3383
/* ************************************************************************** */
3384
3385
mng_retcode process_display_show (mng_datap pData)
3386
{
3387
  mng_int16  iX, iS, iFrom, iTo;
3388
  mng_imagep pImage;
3389
3390
#ifdef MNG_SUPPORT_TRACE
3391
  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_SHOW, MNG_LC_START)
3392
#endif
3393
3394
  /* TODO: optimization for the cases where "abs (iTo - iFrom)" is rather high;
3395
     especially where ((iFrom==1) && (iTo==65535)); eg. an empty SHOW !!! */
3396
3397
  if (pData->iBreakpoint == 3)         /* previously broken during cycle-mode ? */
3398
  {
3399
    pImage = find_imageobject (pData, pData->iSHOWnextid);
3400
3401
    if (pImage)                        /* still there ? */
3402
      display_image (pData, pImage, MNG_FALSE);
3403
3404
    pData->iBreakpoint = 0;            /* let's not go through this again! */
3405
  }
3406
  else
3407
  {
3408
    if (pData->iBreakpoint)            /* previously broken at other point ? */
3409
    {                                  /* restore last parms */
3410
      iFrom = (mng_int16)pData->iSHOWfromid;
3411
      iTo   = (mng_int16)pData->iSHOWtoid;
3412
      iX    = (mng_int16)pData->iSHOWnextid;
3413
      iS    = (mng_int16)pData->iSHOWskip;
3414
    }
3415
    else
3416
    {                                  /* regular sequence ? */
3417
      if (pData->iSHOWtoid >= pData->iSHOWfromid)
3418
        iS  = 1;
3419
      else                             /* reverse sequence ! */
3420
        iS  = -1;
3421
3422
      iFrom = (mng_int16)pData->iSHOWfromid;
3423
      iTo   = (mng_int16)pData->iSHOWtoid;
3424
      iX    = iFrom;
3425
3426
      pData->iSHOWfromid = (mng_uint16)iFrom;
3427
      pData->iSHOWtoid   = (mng_uint16)iTo;
3428
      pData->iSHOWskip   = iS;
3429
    }
3430
                                       /* cycle mode ? */
3431
    if ((pData->iSHOWmode == 6) || (pData->iSHOWmode == 7))
3432
    {
3433
      mng_uint16 iTrigger = 0;
3434
      mng_uint16 iFound   = 0;
3435
      mng_uint16 iPass    = 0;
3436
      mng_imagep pFound   = 0;
3437
3438
      do
3439
      {
3440
        iPass++;                       /* lets prevent endless loops when there
3441
                                          are no potential candidates in the list! */
3442
3443
        if (iS > 0)                    /* forward ? */
3444
        {
3445
          for (iX = iFrom; iX <= iTo; iX += iS)
3446
          {
3447
            pImage = find_imageobject (pData, (mng_uint16)iX);
3448
3449
            if (pImage)                  /* object exists ? */
3450
            {
3451
              if (iFound)                /* already found a candidate ? */
3452
                pImage->bVisible = MNG_FALSE;
3453
              else
3454
              if (iTrigger)              /* found the trigger ? */
3455
              {
3456
                pImage->bVisible = MNG_TRUE;
3457
                iFound           = iX;
3458
                pFound           = pImage;
3459
              }
3460
              else
3461
              if (pImage->bVisible)      /* ok, this is the trigger */
3462
              {
3463
                pImage->bVisible = MNG_FALSE;
3464
                iTrigger         = iX;
3465
              }
3466
            }
3467
          }
3468
        }
3469
        else
3470
        {
3471
          for (iX = iFrom; iX >= iTo; iX += iS)
3472
          {
3473
            pImage = find_imageobject (pData, (mng_uint16)iX);
3474
3475
            if (pImage)                  /* object exists ? */
3476
            {
3477
              if (iFound)                /* already found a candidate ? */
3478
                pImage->bVisible = MNG_FALSE;
3479
              else
3480
              if (iTrigger)              /* found the trigger ? */
3481
              {
3482
                pImage->bVisible = MNG_TRUE;
3483
                iFound           = iX;
3484
                pFound           = pImage;
3485
              }
3486
              else
3487
              if (pImage->bVisible)      /* ok, this is the trigger */
3488
              {
3489
                pImage->bVisible = MNG_FALSE;
3490
                iTrigger         = iX;
3491
              }
3492
            }
3493
          }
3494
        }
3495
3496
        if (!iTrigger)                 /* did not find a trigger ? */
3497
          iTrigger = 1;                /* then fake it so the first image
3498
                                          gets nominated */
3499
      }                                /* cycle back to beginning ? */
3500
      while ((iPass < 2) && (iTrigger) && (!iFound));
3501
3502
      pData->iBreakpoint = 0;          /* just a sanity precaution */
3503
                                       /* display it ? */
3504
      if ((pData->iSHOWmode == 6) && (pFound))
3505
      {
3506
        display_image (pData, pFound, MNG_FALSE);
3507
3508
        if (pData->bTimerset)          /* timer set ? */
3509
        {
3510
          pData->iBreakpoint = 3;
3511
          pData->iSHOWnextid = iFound; /* save it for after the break */
3512
        }
3513
      }
3514
    }
3515
    else
3516
    {
3517
      do
3518
      {
3519
        pImage = find_imageobject (pData, iX);
3520
3521
        if (pImage)                    /* object exists ? */
3522
        {
3523
          if (pData->iBreakpoint)      /* did we get broken last time ? */
3524
          {                            /* could only happen in the display routine */
3525
            display_image (pData, pImage, MNG_FALSE);
3526
            pData->iBreakpoint = 0;    /* only once inside this loop please ! */
3527
          }
3528
          else
3529
          {
3530
            switch (pData->iSHOWmode)  /* do what ? */
3531
            {
3532
              case 0 : {
3533
                         pImage->bVisible = MNG_TRUE;
3534
                         display_image (pData, pImage, MNG_FALSE);
3535
                         break;
3536
                       }
3537
              case 1 : {
3538
                         pImage->bVisible = MNG_FALSE;
3539
                         break;
3540
                       }
3541
              case 2 : {
3542
                         if (pImage->bVisible)
3543
                           display_image (pData, pImage, MNG_FALSE);
3544
                         break;
3545
                       }
3546
              case 3 : {
3547
                         pImage->bVisible = MNG_TRUE;
3548
                         break;
3549
                       }
3550
              case 4 : {
3551
                         pImage->bVisible = (mng_bool)(!pImage->bVisible);
3552
                         if (pImage->bVisible)
3553
                           display_image (pData, pImage, MNG_FALSE);
3554
                         break;
3555
                       }
3556
              case 5 : {
3557
                         pImage->bVisible = (mng_bool)(!pImage->bVisible);
3558
                       }
3559
            }
3560
          }
3561
        }
3562
3563
        if (!pData->bTimerset)         /* next ? */
3564
          iX += iS;
3565
3566
      }                                /* continue ? */
3567
      while ((!pData->bTimerset) && (((iS > 0) && (iX <= iTo)) ||
3568
                                     ((iS < 0) && (iX >= iTo))    ));
3569
3570
      if (pData->bTimerset)            /* timer set ? */
3571
      {
3572
        pData->iBreakpoint = 4;
3573
        pData->iSHOWnextid = iX;       /* save for next time */
3574
      }
3575
      else
3576
        pData->iBreakpoint = 0;
3577
        
3578
    }
3579
  }
3580
3581
#ifdef MNG_SUPPORT_TRACE
3582
  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_SHOW, MNG_LC_END)
3583
#endif
3584
3585
  return MNG_NOERROR;
3586
}
3587
3588
/* ************************************************************************** */
3589
3590
mng_retcode process_display_save (mng_datap pData)
3591
{
3592
  mng_retcode iRetcode;
3593
3594
#ifdef MNG_SUPPORT_TRACE
3595
  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_SAVE, MNG_LC_START)
3596
#endif
3597
3598
  iRetcode = save_state (pData);       /* save the current state */
3599
3600
  if (iRetcode)                        /* on error bail out */
3601
    return iRetcode;
3602
3603
#ifdef MNG_SUPPORT_TRACE
3604
  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_SAVE, MNG_LC_END)
3605
#endif
3606
3607
  return MNG_NOERROR;
3608
}
3609
3610
/* ************************************************************************** */
3611
3612
mng_retcode process_display_seek (mng_datap pData)
3613
{
3614
  mng_retcode iRetcode;
3615
3616
#ifdef MNG_SUPPORT_TRACE
3617
  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_SEEK, MNG_LC_START)
3618
#endif
3619
3620
  iRetcode = restore_state (pData);    /* restore the initial or SAVE state */
3621
3622
  if (iRetcode)                        /* on error bail out */
3623
    return iRetcode;
3624
3625
#ifdef MNG_SUPPORT_TRACE
3626
  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_SEEK, MNG_LC_END)
3627
#endif
3628
3629
  return MNG_NOERROR;
3630
}
3631
3632
/* ************************************************************************** */
3633
3634
#ifdef MNG_INCLUDE_JNG
3635
mng_retcode process_display_jhdr (mng_datap pData)
3636
{                                      /* address the current "object" if any */
3637
  mng_imagep  pImage   = (mng_imagep)pData->pCurrentobj;
3638
  mng_retcode iRetcode = MNG_NOERROR;
3639
3640
#ifdef MNG_SUPPORT_TRACE
3641
  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_JHDR, MNG_LC_START)
3642
#endif
3643
3644
  if (!pData->bHasDHDR)
3645
  {
3646
    pData->fInitrowproc  = MNG_NULL;   /* do nothing by default */
3647
    pData->fDisplayrow   = MNG_NULL;
3648
    pData->fCorrectrow   = MNG_NULL;
3649
    pData->fStorerow     = MNG_NULL;
3650
    pData->fProcessrow   = MNG_NULL;
3651
    pData->fDifferrow    = MNG_NULL;
3652
    pData->fStorerow2    = MNG_NULL;
3653
    pData->fStorerow3    = MNG_NULL;
3654
3655
    pData->pStoreobj     = MNG_NULL;   /* initialize important work-parms */
3656
3657
    pData->iJPEGrow      = 0;
3658
    pData->iJPEGalpharow = 0;
3659
    pData->iJPEGrgbrow   = 0;
3660
    pData->iRowmax       = 0;          /* so init_rowproc does the right thing ! */
3661
  }
3662
3663
  if (!pData->iBreakpoint)             /* not previously broken ? */
3664
  {
3665
    if (pData->bHasDHDR)               /* delta-image ? */
3666
    {
3667
      if (pData->iDeltatype == MNG_DELTATYPE_REPLACE)
3668
      {
3669
        iRetcode = reset_object_details (pData, (mng_imagep)pData->pDeltaImage,
3670
                                         pData->iDatawidth, pData->iDataheight,
3671
                                         pData->iJHDRimgbitdepth, pData->iJHDRcolortype,
3672
                                         pData->iJHDRalphacompression, pData->iJHDRalphafilter,
3673
                                         pData->iJHDRalphainterlace, MNG_TRUE);
3674
3675
        ((mng_imagep)pData->pDeltaImage)->pImgbuf->iAlphabitdepth    = pData->iJHDRalphabitdepth;
3676
        ((mng_imagep)pData->pDeltaImage)->pImgbuf->iJHDRcompression  = pData->iJHDRimgcompression;
3677
        ((mng_imagep)pData->pDeltaImage)->pImgbuf->iJHDRinterlace    = pData->iJHDRimginterlace;
3678
        ((mng_imagep)pData->pDeltaImage)->pImgbuf->iAlphasampledepth = pData->iJHDRalphabitdepth;
3679
      }
3680
      else
3681
      if ((pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD    ) ||
3682
          (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)    )
3683
      {
3684
        ((mng_imagep)pData->pDeltaImage)->pImgbuf->iPixelsampledepth = pData->iJHDRimgbitdepth;
3685
        ((mng_imagep)pData->pDeltaImage)->pImgbuf->iAlphasampledepth = pData->iJHDRalphabitdepth;
3686
      }
3687
      else
3688
      if ((pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAADD    ) ||
3689
          (pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAREPLACE)    )
3690
        ((mng_imagep)pData->pDeltaImage)->pImgbuf->iAlphasampledepth = pData->iJHDRalphabitdepth;
3691
      else
3692
      if ((pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORADD    ) ||
3693
          (pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORREPLACE)    )
3694
        ((mng_imagep)pData->pDeltaImage)->pImgbuf->iPixelsampledepth = pData->iJHDRimgbitdepth;
3695
        
3696
    }
3697
    else
3698
    {
3699
      if (pImage)                      /* update object buffer ? */
3700
      {
3701
        iRetcode = reset_object_details (pData, pImage,
3702
                                         pData->iDatawidth, pData->iDataheight,
3703
                                         pData->iJHDRimgbitdepth, pData->iJHDRcolortype,
3704
                                         pData->iJHDRalphacompression, pData->iJHDRalphafilter,
3705
                                         pData->iJHDRalphainterlace, MNG_TRUE);
3706
3707
        pImage->pImgbuf->iAlphabitdepth    = pData->iJHDRalphabitdepth;
3708
        pImage->pImgbuf->iJHDRcompression  = pData->iJHDRimgcompression;
3709
        pImage->pImgbuf->iJHDRinterlace    = pData->iJHDRimginterlace;
3710
        pImage->pImgbuf->iAlphasampledepth = pData->iJHDRalphabitdepth;
3711
      }
3712
      else                             /* update object 0 */
3713
      {
3714
        iRetcode = reset_object_details (pData, (mng_imagep)pData->pObjzero,
3715
                                         pData->iDatawidth, pData->iDataheight,
3716
                                         pData->iJHDRimgbitdepth, pData->iJHDRcolortype,
3717
                                         pData->iJHDRalphacompression, pData->iJHDRalphafilter,
3718
                                         pData->iJHDRalphainterlace, MNG_TRUE);
3719
3720
        ((mng_imagep)pData->pObjzero)->pImgbuf->iAlphabitdepth    = pData->iJHDRalphabitdepth;
3721
        ((mng_imagep)pData->pObjzero)->pImgbuf->iJHDRcompression  = pData->iJHDRimgcompression;
3722
        ((mng_imagep)pData->pObjzero)->pImgbuf->iJHDRinterlace    = pData->iJHDRimginterlace;
3723
        ((mng_imagep)pData->pObjzero)->pImgbuf->iAlphasampledepth = pData->iJHDRalphabitdepth;
3724
      }
3725
    }
3726
3727
    if (iRetcode)                      /* on error bail out */
3728
      return iRetcode;
3729
  }
3730
3731
  if (!pData->bHasDHDR)
3732
  {                                    /* we're always storing a JPEG */
3733
    if (pImage)                        /* real object ? */
3734
      pData->pStoreobj = pImage;       /* tell the row routines */
3735
    else                               /* otherwise use object 0 */
3736
      pData->pStoreobj = pData->pObjzero;
3737
                                       /* display "on-the-fly" ? */
3738
    if ( (((mng_imagep)pData->pStoreobj)->iMAGN_MethodX == 0) &&
3739
         (((mng_imagep)pData->pStoreobj)->iMAGN_MethodY == 0) &&
3740
         ( (pData->eImagetype == mng_it_jng         ) ||
3741
           (((mng_imagep)pData->pStoreobj)->bVisible)    )       )
3742
    {
3743
      next_layer (pData);              /* that's a new layer then ! */
3744
3745
      if (pData->bTimerset)            /* timer break ? */
3746
        pData->iBreakpoint = 7;
3747
      else
3748
      {
3749
        pData->iBreakpoint = 0;
3750
                                       /* anything to display ? */
3751
        if ((pData->iDestr > pData->iDestl) && (pData->iDestb > pData->iDestt))
3752
        {
3753
          set_display_routine (pData); /* then determine display routine */
3754
                                       /* display from the object we store in */
3755
          pData->pRetrieveobj = pData->pStoreobj;
3756
        }
3757
      }
3758
    }
3759
  }
3760
3761
  if (!pData->bTimerset)               /* no timer break ? */
3762
  {                                    /* default row initialization ! */
3763
    pData->fInitrowproc = (mng_fptr)init_rowproc;
3764
3765
    if ((!pData->bHasDHDR) || (pData->iDeltatype == MNG_DELTATYPE_REPLACE))
3766
    {                                  /* 8-bit JPEG ? */
3767
      if (pData->iJHDRimgbitdepth == 8)
3768
      {                                /* intermediate row is 8-bit deep */
3769
        pData->bIsRGBA16   = MNG_FALSE;
3770
        pData->iRowsamples = pData->iDatawidth;
3771
3772
        switch (pData->iJHDRcolortype) /* determine pixel processing routines */
3773
        {
3774
          case MNG_COLORTYPE_JPEGGRAY :
3775
               {
3776
                 pData->fStorerow2   = (mng_fptr)store_jpeg_g8;
3777
                 pData->fRetrieverow = (mng_fptr)retrieve_g8;
3778
                 pData->bIsOpaque    = MNG_TRUE;
3779
                 break;
3780
               }
3781
          case MNG_COLORTYPE_JPEGCOLOR :
3782
               {
3783
                 pData->fStorerow2   = (mng_fptr)store_jpeg_rgb8;
3784
                 pData->fRetrieverow = (mng_fptr)retrieve_rgb8;
3785
                 pData->bIsOpaque    = MNG_TRUE;
3786
                 break;
3787
               }
3788
          case MNG_COLORTYPE_JPEGGRAYA :
3789
               {
3790
                 pData->fStorerow2   = (mng_fptr)store_jpeg_ga8;
3791
                 pData->fRetrieverow = (mng_fptr)retrieve_ga8;
3792
                 pData->bIsOpaque    = MNG_FALSE;
3793
                 break;
3794
               }
3795
          case MNG_COLORTYPE_JPEGCOLORA :
3796
               {
3797
                 pData->fStorerow2   = (mng_fptr)store_jpeg_rgba8;
3798
                 pData->fRetrieverow = (mng_fptr)retrieve_rgba8;
3799
                 pData->bIsOpaque    = MNG_FALSE;
3800
                 break;
3801
               }
3802
        }
3803
      }
3804
      else
3805
      {
3806
        pData->bIsRGBA16 = MNG_TRUE;   /* intermediate row is 16-bit deep */
3807
3808
        /* TODO: 12-bit JPEG */
3809
        /* TODO: 8- + 12-bit JPEG (eg. type=20) */
3810
3811
      }
3812
                                       /* possible IDAT alpha-channel ? */
3813
      if (pData->iJHDRalphacompression == MNG_COMPRESSION_DEFLATE)
3814
      {
3815
                                       /* determine alpha processing routine */
3816
        switch (pData->iJHDRalphabitdepth)
3817
        {
3818
          case  1 : { pData->fInitrowproc = (mng_fptr)init_jpeg_a1_ni;  break; }
3819
          case  2 : { pData->fInitrowproc = (mng_fptr)init_jpeg_a2_ni;  break; }
3820
          case  4 : { pData->fInitrowproc = (mng_fptr)init_jpeg_a4_ni;  break; }
3821
          case  8 : { pData->fInitrowproc = (mng_fptr)init_jpeg_a8_ni;  break; }
3822
          case 16 : { pData->fInitrowproc = (mng_fptr)init_jpeg_a16_ni; break; }
3823
        }                                        
3824
      }
3825
      else                             /* possible JDAA alpha-channel ? */
3826
      if (pData->iJHDRalphacompression == MNG_COMPRESSION_BASELINEJPEG)
3827
      {                                /* 8-bit JPEG ? */
3828
        if (pData->iJHDRimgbitdepth == 8)
3829
        {
3830
          if (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGGRAYA)
3831
            pData->fStorerow3 = (mng_fptr)store_jpeg_g8_alpha;
3832
          else
3833
          if (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGCOLORA)
3834
            pData->fStorerow3 = (mng_fptr)store_jpeg_rgb8_alpha;
3835
        }
3836
        else
3837
        {
3838
          /* TODO: 12-bit JPEG with 8-bit JDAA */
3839
        }
3840
      }  
3841
                                       /* initialize JPEG library */
3842
      iRetcode = mngjpeg_initialize (pData);
3843
3844
      if (iRetcode)                    /* on error bail out */
3845
        return iRetcode;
3846
    }
3847
    else
3848
    {                                  /* must be alpha add/replace !! */
3849
      if ((pData->iDeltatype != MNG_DELTATYPE_BLOCKALPHAADD    ) &&
3850
          (pData->iDeltatype != MNG_DELTATYPE_BLOCKALPHAREPLACE)    )
3851
        MNG_ERROR (pData, MNG_INVDELTATYPE)
3852
                                       /* determine alpha processing routine */
3853
      switch (pData->iJHDRalphabitdepth)
3854
      {
3855
        case  1 : { pData->fInitrowproc = (mng_fptr)init_g1_ni;  break; }
3856
        case  2 : { pData->fInitrowproc = (mng_fptr)init_g2_ni;  break; }
3857
        case  4 : { pData->fInitrowproc = (mng_fptr)init_g4_ni;  break; }
3858
        case  8 : { pData->fInitrowproc = (mng_fptr)init_g8_ni;  break; }
3859
        case 16 : { pData->fInitrowproc = (mng_fptr)init_g16_ni; break; }
3860
      }
3861
    }
3862
3863
    pData->iFilterofs = 0;             /* determine filter characteristics */
3864
    pData->iLevel0    = 0;             /* default levels */
3865
    pData->iLevel1    = 0;    
3866
    pData->iLevel2    = 0;
3867
    pData->iLevel3    = 0;
3868
                                       /* leveling & differing ? */
3869
/*    if (pData->iJHDRalphafilter & 0x40)
3870
    {
3871
       if (pData->iJHDRalphabitdepth <= 8)
3872
         pData->iFilterofs = 1;
3873
       else
3874
         pData->iFilterofs = 2;
3875
3876
    } */
3877
                                       /* no adaptive filtering ? */
3878
/*    if (pData->iJHDRalphafilter & 0x01)
3879
      pData->iPixelofs = pData->iFilterofs;
3880
    else */
3881
      pData->iPixelofs = pData->iFilterofs + 1;
3882
3883
  }
3884
3885
#ifdef MNG_SUPPORT_TRACE
3886
  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_JHDR, MNG_LC_END)
3887
#endif
3888
3889
  return MNG_NOERROR;
3890
}
3891
#endif /* MNG_INCLUDE_JNG */
3892
3893
/* ************************************************************************** */
3894
3895
#ifdef MNG_INCLUDE_JNG
3896
mng_retcode process_display_jdaa (mng_datap  pData,
3897
                                  mng_uint32 iRawlen,
3898
                                  mng_uint8p pRawdata)
3899
{
3900
  mng_retcode iRetcode = MNG_NOERROR;
3901
3902
#ifdef MNG_SUPPORT_TRACE
3903
  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_JDAA, MNG_LC_START)
3904
#endif
3905
3906
  if (!pData->bJPEGdecompress2)        /* if we're not decompressing already */
3907
  {
3908
    if (pData->fInitrowproc)           /* initialize row-processing? */
3909
    {
3910
      iRetcode = ((mng_initrowproc)pData->fInitrowproc) (pData);
3911
      pData->fInitrowproc = MNG_NULL;  /* only call this once !!! */
3912
    }
3913
3914
    if (!iRetcode)                     /* initialize decompress */
3915
      iRetcode = mngjpeg_decompressinit2 (pData);
3916
  }
3917
3918
  if (!iRetcode)                       /* all ok? then decompress, my man */
3919
    iRetcode = mngjpeg_decompressdata2 (pData, iRawlen, pRawdata);
3920
3921
  if (iRetcode)
3922
    return iRetcode;
3923
3924
#ifdef MNG_SUPPORT_TRACE
3925
  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_JDAA, MNG_LC_END)
3926
#endif
3927
3928
  return MNG_NOERROR;
3929
}
3930
#endif /* MNG_INCLUDE_JNG */
3931
3932
/* ************************************************************************** */
3933
3934
#ifdef MNG_INCLUDE_JNG
3935
mng_retcode process_display_jdat (mng_datap  pData,
3936
                                  mng_uint32 iRawlen,
3937
                                  mng_uint8p pRawdata)
3938
{
3939
  mng_retcode iRetcode = MNG_NOERROR;
3940
3941
#ifdef MNG_SUPPORT_TRACE
3942
  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_JDAT, MNG_LC_START)
3943
#endif
3944
3945
  if (pData->bRestorebkgd)             /* need to restore the background ? */
3946
  {
3947
    pData->bRestorebkgd = MNG_FALSE;
3948
    iRetcode            = load_bkgdlayer (pData);
3949
3950
    if ((pData->bDisplaying) && (pData->bRunning))
3951
      pData->iLayerseq++;              /* and it counts as a layer then ! */
3952
3953
    if (iRetcode)                      /* on error bail out */
3954
      return iRetcode;
3955
  }
3956
3957
  if (!pData->bJPEGdecompress)         /* if we're not decompressing already */
3958
  {
3959
    if (pData->fInitrowproc)           /* initialize row-processing? */
3960
    {
3961
      iRetcode = ((mng_initrowproc)pData->fInitrowproc) (pData);
3962
      pData->fInitrowproc = MNG_NULL;  /* only call this once !!! */
3963
    }
3964
3965
    if (!iRetcode)                     /* initialize decompress */
3966
      iRetcode = mngjpeg_decompressinit (pData);
3967
  }
3968
3969
  if (!iRetcode)                       /* all ok? then decompress, my man */
3970
    iRetcode = mngjpeg_decompressdata (pData, iRawlen, pRawdata);
3971
3972
  if (iRetcode)
3973
    return iRetcode;
3974
3975
#ifdef MNG_SUPPORT_TRACE
3976
  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_JDAT, MNG_LC_END)
3977
#endif
3978
3979
  return MNG_NOERROR;
3980
}
3981
#endif /* MNG_INCLUDE_JNG */
3982
3983
/* ************************************************************************** */
3984
3985
mng_retcode process_display_dhdr (mng_datap  pData,
3986
                                  mng_uint16 iObjectid,
3987
                                  mng_uint8  iImagetype,
3988
                                  mng_uint8  iDeltatype,
3989
                                  mng_uint32 iBlockwidth,
3990
                                  mng_uint32 iBlockheight,
3991
                                  mng_uint32 iBlockx,
3992
                                  mng_uint32 iBlocky)
3993
{
3994
  mng_imagep  pImage;
3995
  mng_retcode iRetcode;
3996
3997
#ifdef MNG_SUPPORT_TRACE
3998
  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_DHDR, MNG_LC_START)
3999
#endif
4000
4001
  pData->fInitrowproc     = MNG_NULL;  /* do nothing by default */
4002
  pData->fDisplayrow      = MNG_NULL;
4003
  pData->fCorrectrow      = MNG_NULL;
4004
  pData->fStorerow        = MNG_NULL;
4005
  pData->fProcessrow      = MNG_NULL;
4006
  pData->pStoreobj        = MNG_NULL;
4007
4008
  pData->fDeltagetrow     = MNG_NULL;
4009
  pData->fDeltaaddrow     = MNG_NULL;
4010
  pData->fDeltareplacerow = MNG_NULL;
4011
  pData->fDeltaputrow     = MNG_NULL;
4012
4013
  pImage = find_imageobject (pData, iObjectid);
4014
4015
  if (pImage)                          /* object exists ? */
4016
  {
4017
    if (pImage->pImgbuf->bConcrete)    /* is it concrete ? */
4018
    {                                  /* previous magnification to be done ? */
4019
      if ((pImage->iMAGN_MethodX) || (pImage->iMAGN_MethodY))
4020
      {
4021
        iRetcode = magnify_imageobject (pData, pImage);
4022
4023
        if (iRetcode)                  /* on error bail out */
4024
          return iRetcode;
4025
      }
4026
                                       /* save delta fields */
4027
      pData->pDeltaImage           = (mng_ptr)pImage;
4028
      pData->iDeltaImagetype       = iImagetype;
4029
      pData->iDeltatype            = iDeltatype;
4030
      pData->iDeltaBlockwidth      = iBlockwidth;
4031
      pData->iDeltaBlockheight     = iBlockheight;
4032
      pData->iDeltaBlockx          = iBlockx;
4033
      pData->iDeltaBlocky          = iBlocky;
4034
                                       /* restore target-object fields */
4035
      pData->iDatawidth            = pImage->pImgbuf->iWidth;
4036
      pData->iDataheight           = pImage->pImgbuf->iHeight;
4037
      pData->iBitdepth             = pImage->pImgbuf->iBitdepth;
4038
      pData->iColortype            = pImage->pImgbuf->iColortype;
4039
      pData->iCompression          = pImage->pImgbuf->iCompression;
4040
      pData->iFilter               = pImage->pImgbuf->iFilter;
4041
      pData->iInterlace            = pImage->pImgbuf->iInterlace;
4042
4043
#ifdef MNG_INCLUDE_JNG
4044
      pData->iJHDRimgbitdepth      = pImage->pImgbuf->iBitdepth;
4045
      pData->iJHDRcolortype        = pImage->pImgbuf->iColortype;
4046
      pData->iJHDRimgcompression   = pImage->pImgbuf->iJHDRcompression;
4047
      pData->iJHDRimginterlace     = pImage->pImgbuf->iJHDRinterlace;
4048
      pData->iJHDRalphacompression = pImage->pImgbuf->iCompression;
4049
      pData->iJHDRalphafilter      = pImage->pImgbuf->iFilter;
4050
      pData->iJHDRalphainterlace   = pImage->pImgbuf->iInterlace;
4051
      pData->iJHDRalphabitdepth    = pImage->pImgbuf->iAlphabitdepth;
4052
#endif
4053
                                       /* block size specified ? */
4054
      if (iDeltatype != MNG_DELTATYPE_NOCHANGE)
4055
      {
4056
        pData->iDatawidth          = iBlockwidth;
4057
        pData->iDataheight         = iBlockheight;
4058
      }
4059
4060
      switch (iDeltatype)              /* determine nr of delta-channels */
4061
      {
4062
         case MNG_DELTATYPE_BLOCKALPHAADD : ;
4063
         case MNG_DELTATYPE_BLOCKALPHAREPLACE :
4064
              {
4065
#ifdef MNG_INCLUDE_JNG
4066
                if ((pData->iColortype     == MNG_COLORTYPE_GRAYA    ) ||
4067
                    (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGGRAYA)    )
4068
                {
4069
                  pData->iColortype     = MNG_COLORTYPE_GRAY;
4070
                  pData->iJHDRcolortype = MNG_COLORTYPE_JPEGGRAY;
4071
                }
4072
                else
4073
                if ((pData->iColortype     == MNG_COLORTYPE_RGBA      ) ||
4074
                    (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGCOLORA)    )
4075
                {
4076
                  pData->iColortype     = MNG_COLORTYPE_GRAY;
4077
                  pData->iJHDRcolortype = MNG_COLORTYPE_JPEGGRAY;
4078
                }
4079
#else
4080
                if (pData->iColortype      == MNG_COLORTYPE_GRAYA)
4081
                  pData->iColortype     = MNG_COLORTYPE_GRAY;
4082
                else
4083
                if (pData->iColortype      == MNG_COLORTYPE_RGBA)
4084
                  pData->iColortype     = MNG_COLORTYPE_GRAY;
4085
#endif
4086
                else                   /* target has no alpha; that sucks! */
4087
                  MNG_ERROR (pData, MNG_TARGETNOALPHA)
4088
4089
                break;
4090
              }
4091
4092
         case MNG_DELTATYPE_BLOCKCOLORADD : ;
4093
         case MNG_DELTATYPE_BLOCKCOLORREPLACE :
4094
              {
4095
#ifdef MNG_INCLUDE_JNG
4096
                if ((pData->iColortype     == MNG_COLORTYPE_GRAYA    ) ||
4097
                    (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGGRAYA)    )
4098
                {
4099
                  pData->iColortype     = MNG_COLORTYPE_GRAY;
4100
                  pData->iJHDRcolortype = MNG_COLORTYPE_JPEGGRAY;
4101
                }
4102
                else
4103
                if ((pData->iColortype     == MNG_COLORTYPE_RGBA      ) ||
4104
                    (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGCOLORA)    )
4105
                {
4106
                  pData->iColortype     = MNG_COLORTYPE_RGB;
4107
                  pData->iJHDRcolortype = MNG_COLORTYPE_JPEGCOLOR;
4108
                }
4109
#else
4110
                if (pData->iColortype == MNG_COLORTYPE_GRAYA)
4111
                  pData->iColortype = MNG_COLORTYPE_GRAY;
4112
                else
4113
                if (pData->iColortype == MNG_COLORTYPE_RGBA)
4114
                  pData->iColortype = MNG_COLORTYPE_RGB;
4115
#endif                  
4116
                else                   /* target has no alpha; that sucks! */
4117
                  MNG_ERROR (pData, MNG_TARGETNOALPHA)
4118
4119
                break;
4120
              }
4121
4122
      }
4123
                                       /* full image replace ? */
4124
      if (iDeltatype == MNG_DELTATYPE_REPLACE)
4125
      {
4126
        iRetcode = reset_object_details (pData, pImage,
4127
                                         pData->iDatawidth, pData->iDataheight,
4128
                                         pData->iBitdepth, pData->iColortype,
4129
                                         pData->iCompression, pData->iFilter,
4130
                                         pData->iInterlace, MNG_FALSE);
4131
4132
        if (iRetcode)                  /* on error bail out */
4133
          return iRetcode;
4134
4135
        pData->pStoreobj = pImage;     /* and store straight into this object */
4136
      }
4137
      else
4138
      {
4139
        mng_imagedatap pBufzero, pBuf;
4140
                                       /* we store in object 0 and process it later */
4141
        pData->pStoreobj = pData->pObjzero;
4142
                                       /* make sure to initialize object 0 then */
4143
        iRetcode = reset_object_details (pData, (mng_imagep)pData->pObjzero,
4144
                                         pData->iDatawidth, pData->iDataheight,
4145
                                         pData->iBitdepth, pData->iColortype,
4146
                                         pData->iCompression, pData->iFilter,
4147
                                         pData->iInterlace, MNG_TRUE);
4148
4149
        if (iRetcode)                  /* on error bail out */
4150
          return iRetcode;
4151
4152
        pBuf     = pImage->pImgbuf;    /* copy possible palette & cheap transparency */
4153
        pBufzero = ((mng_imagep)pData->pObjzero)->pImgbuf;
4154
4155
        pBufzero->bHasPLTE = pBuf->bHasPLTE;
4156
        pBufzero->bHasTRNS = pBuf->bHasTRNS;
4157
4158
        if (pBufzero->bHasPLTE)        /* copy palette ? */
4159
        {
4160
          mng_uint32 iX;
4161
4162
          pBufzero->iPLTEcount = pBuf->iPLTEcount;
4163
4164
          for (iX = 0; iX < pBuf->iPLTEcount; iX++)
4165
          {
4166
            pBufzero->aPLTEentries [iX].iRed   = pBuf->aPLTEentries [iX].iRed;
4167
            pBufzero->aPLTEentries [iX].iGreen = pBuf->aPLTEentries [iX].iGreen;
4168
            pBufzero->aPLTEentries [iX].iBlue  = pBuf->aPLTEentries [iX].iBlue;
4169
          }
4170
        }
4171
4172
        if (pBufzero->bHasTRNS)        /* copy cheap transparency ? */
4173
        {
4174
          pBufzero->iTRNSgray  = pBuf->iTRNSgray;
4175
          pBufzero->iTRNSred   = pBuf->iTRNSred;
4176
          pBufzero->iTRNSgreen = pBuf->iTRNSgreen;
4177
          pBufzero->iTRNSblue  = pBuf->iTRNSblue;
4178
          pBufzero->iTRNScount = pBuf->iTRNScount;
4179
4180
          MNG_COPY (pBufzero->aTRNSentries, pBuf->aTRNSentries,
4181
                    sizeof (pBufzero->aTRNSentries))
4182
        }
4183
                                       /* process immediatly if bitdepth & colortype are equal */
4184
        pData->bDeltaimmediate =
4185
          (mng_bool)((pData->bDisplaying) && (pData->bRunning) &&
4186
                     (pData->iBitdepth  == ((mng_imagep)pData->pDeltaImage)->pImgbuf->iBitdepth ) &&
4187
                     (pData->iColortype == ((mng_imagep)pData->pDeltaImage)->pImgbuf->iColortype)    );
4188
      }
4189
4190
      switch (pData->iColortype)       /* determine row initialization routine */
4191
      {
4192
        case 0 : {                     /* gray */
4193
                   switch (pData->iBitdepth)
4194
                   {
4195
                     case  1 : {
4196
                                 if (!pData->iInterlace)
4197
                                   pData->fInitrowproc = (mng_fptr)init_g1_ni;
4198
                                 else
4199
                                   pData->fInitrowproc = (mng_fptr)init_g1_i;
4200
4201
                                 break;
4202
                               }
4203
                     case  2 : {
4204
                                 if (!pData->iInterlace)
4205
                                   pData->fInitrowproc = (mng_fptr)init_g2_ni;
4206
                                 else
4207
                                   pData->fInitrowproc = (mng_fptr)init_g2_i;
4208
4209
                                 break;
4210
                               }
4211
                     case  4 : {
4212
                                 if (!pData->iInterlace)
4213
                                   pData->fInitrowproc = (mng_fptr)init_g4_ni;
4214
                                 else
4215
                                   pData->fInitrowproc = (mng_fptr)init_g4_i;
4216
4217
                                 break;
4218
                               }
4219
                     case  8 : {
4220
                                 if (!pData->iInterlace)
4221
                                   pData->fInitrowproc = (mng_fptr)init_g8_ni;
4222
                                 else
4223
                                   pData->fInitrowproc = (mng_fptr)init_g8_i;
4224
4225
                                 break;
4226
                               }
4227
                     case 16 : {
4228
                                 if (!pData->iInterlace)
4229
                                   pData->fInitrowproc = (mng_fptr)init_g16_ni;
4230
                                 else
4231
                                   pData->fInitrowproc = (mng_fptr)init_g16_i;
4232
4233
                                 break;
4234
                               }
4235
                   }
4236
4237
                   break;
4238
                 }
4239
        case 2 : {                     /* rgb */
4240
                   switch (pData->iBitdepth)
4241
                   {
4242
                     case  8 : {
4243
                                 if (!pData->iInterlace)
4244
                                   pData->fInitrowproc = (mng_fptr)init_rgb8_ni;
4245
                                 else
4246
                                   pData->fInitrowproc = (mng_fptr)init_rgb8_i;
4247
4248
                                 break;
4249
                               }
4250
                     case 16 : {
4251
                                 if (!pData->iInterlace)
4252
                                   pData->fInitrowproc = (mng_fptr)init_rgb16_ni;
4253
                                 else
4254
                                   pData->fInitrowproc = (mng_fptr)init_rgb16_i;
4255
4256
                                 break;
4257
                               }
4258
                   }
4259
4260
                   break;
4261
                 }
4262
        case 3 : {                     /* indexed */
4263
                   switch (pData->iBitdepth)
4264
                   {
4265
                     case  1 : {
4266
                                 if (!pData->iInterlace)
4267
                                   pData->fInitrowproc = (mng_fptr)init_idx1_ni;
4268
                                 else
4269
                                   pData->fInitrowproc = (mng_fptr)init_idx1_i;
4270
4271
                                 break;
4272
                               }
4273
                     case  2 : {
4274
                                 if (!pData->iInterlace)
4275
                                   pData->fInitrowproc = (mng_fptr)init_idx2_ni;
4276
                                 else
4277
                                   pData->fInitrowproc = (mng_fptr)init_idx2_i;
4278
4279
                                 break;
4280
                               }
4281
                     case  4 : {
4282
                                 if (!pData->iInterlace)
4283
                                   pData->fInitrowproc = (mng_fptr)init_idx4_ni;
4284
                                 else
4285
                                   pData->fInitrowproc = (mng_fptr)init_idx4_i;
4286
4287
                                 break;
4288
                               }
4289
                     case  8 : {
4290
                                 if (!pData->iInterlace)
4291
                                   pData->fInitrowproc = (mng_fptr)init_idx8_ni;
4292
                                 else
4293
                                   pData->fInitrowproc = (mng_fptr)init_idx8_i;
4294
4295
                                 break;
4296
                               }
4297
                   }
4298
4299
                   break;
4300
                 }
4301
        case 4 : {                     /* gray+alpha */
4302
                   switch (pData->iBitdepth)
4303
                   {
4304
                     case  8 : {
4305
                                 if (!pData->iInterlace)
4306
                                   pData->fInitrowproc = (mng_fptr)init_ga8_ni;
4307
                                 else
4308
                                   pData->fInitrowproc = (mng_fptr)init_ga8_i;
4309
4310
                                 break;
4311
                               }
4312
                     case 16 : {
4313
                                 if (!pData->iInterlace)
4314
                                   pData->fInitrowproc = (mng_fptr)init_ga16_ni;
4315
                                 else
4316
                                   pData->fInitrowproc = (mng_fptr)init_ga16_i;
4317
4318
                                 break;
4319
                               }
4320
                   }
4321
4322
                   break;
4323
                 }
4324
        case 6 : {                     /* rgb+alpha */
4325
                   switch (pData->iBitdepth)
4326
                   {
4327
                     case  8 : {
4328
                                 if (!pData->iInterlace)
4329
                                   pData->fInitrowproc = (mng_fptr)init_rgba8_ni;
4330
                                 else
4331
                                   pData->fInitrowproc = (mng_fptr)init_rgba8_i;
4332
4333
                                 break;
4334
                               }
4335
                     case 16 : {
4336
                                 if (!pData->iInterlace)
4337
                                   pData->fInitrowproc = (mng_fptr)init_rgba16_ni;
4338
                                 else
4339
                                   pData->fInitrowproc = (mng_fptr)init_rgba16_i;
4340
4341
                                 break;
4342
                               }
4343
                   }
4344
4345
                   break;
4346
                 }
4347
      }
4348
    }
4349
    else
4350
      MNG_ERROR (pData, MNG_OBJNOTCONCRETE)
4351
4352
  }
4353
  else
4354
    MNG_ERROR (pData, MNG_OBJECTUNKNOWN)
4355
4356
#ifdef MNG_SUPPORT_TRACE
4357
  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_DHDR, MNG_LC_END)
4358
#endif
4359
4360
  return MNG_NOERROR;
4361
}
4362
4363
/* ************************************************************************** */
4364
4365
mng_retcode process_display_prom (mng_datap  pData,
4366
                                  mng_uint8  iBitdepth,
4367
                                  mng_uint8  iColortype,
4368
                                  mng_uint8  iFilltype)
4369
{
4370
#ifdef MNG_SUPPORT_TRACE
4371
  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_PROM, MNG_LC_START)
4372
#endif
4373
4374
4375
  /* TODO: everything */
4376
  
4377
4378
#ifdef MNG_SUPPORT_TRACE
4379
  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_PROM, MNG_LC_END)
4380
#endif
4381
4382
  return MNG_NOERROR;
4383
}
4384
4385
/* ************************************************************************** */
4386
4387
mng_retcode process_display_ipng (mng_datap pData)
4388
{
4389
#ifdef MNG_SUPPORT_TRACE
4390
  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_IPNG, MNG_LC_START)
4391
#endif
4392
                                       /* indicate it for what it is now */
4393
  pData->iDeltaImagetype = MNG_IMAGETYPE_PNG;
4394
4395
#ifdef MNG_SUPPORT_TRACE
4396
  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_IPNG, MNG_LC_END)
4397
#endif
4398
4399
  return MNG_NOERROR;
4400
}
4401
4402
/* ************************************************************************** */
4403
4404
mng_retcode process_display_ijng (mng_datap pData)
4405
{
4406
#ifdef MNG_SUPPORT_TRACE
4407
  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_IJNG, MNG_LC_START)
4408
#endif
4409
                                       /* indicate it for what it is now */
4410
  pData->iDeltaImagetype = MNG_IMAGETYPE_JNG;
4411
4412
#ifdef MNG_SUPPORT_TRACE
4413
  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_IJNG, MNG_LC_END)
4414
#endif
4415
4416
  return MNG_NOERROR;
4417
}
4418
4419
/* ************************************************************************** */
4420
4421
mng_retcode process_display_pplt (mng_datap      pData,
4422
                                  mng_uint8      iType,
4423
                                  mng_uint32     iCount,
4424
                                  mng_palette8ep paIndexentries,
4425
                                  mng_uint8p     paAlphaentries,
4426
                                  mng_uint8p     paUsedentries)
4427
{
4428
  mng_uint32     iX;
4429
  mng_imagep     pImage = (mng_imagep)pData->pObjzero;
4430
  mng_imagedatap pBuf   = pImage->pImgbuf;
4431
4432
#ifdef MNG_SUPPORT_TRACE
4433
  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_PPLT, MNG_LC_START)
4434
#endif
4435
4436
  switch (iType)
4437
  {
4438
    case MNG_DELTATYPE_REPLACERGB :
4439
      {
4440
        for (iX = 0; iX < iCount; iX++)
4441
        {
4442
          if (paUsedentries [iX])
4443
          {
4444
            pBuf->aPLTEentries [iX].iRed   = paIndexentries [iX].iRed;
4445
            pBuf->aPLTEentries [iX].iGreen = paIndexentries [iX].iGreen;
4446
            pBuf->aPLTEentries [iX].iBlue  = paIndexentries [iX].iBlue;
4447
          }
4448
        }
4449
4450
        break;
4451
      }
4452
    case MNG_DELTATYPE_DELTARGB :
4453
      {
4454
        for (iX = 0; iX < iCount; iX++)
4455
        {
4456
          if (paUsedentries [iX])
4457
          {
4458
            pBuf->aPLTEentries [iX].iRed   =
4459
                               (mng_uint8)(pBuf->aPLTEentries [iX].iRed   +
4460
                                           paIndexentries [iX].iRed  );
4461
            pBuf->aPLTEentries [iX].iGreen =
4462
                               (mng_uint8)(pBuf->aPLTEentries [iX].iGreen +
4463
                                           paIndexentries [iX].iGreen);
4464
            pBuf->aPLTEentries [iX].iBlue  =
4465
                               (mng_uint8)(pBuf->aPLTEentries [iX].iBlue  +
4466
                                           paIndexentries [iX].iBlue );
4467
          }
4468
        }
4469
4470
        break;
4471
      }
4472
    case MNG_DELTATYPE_REPLACEALPHA :
4473
      {
4474
        for (iX = 0; iX < iCount; iX++)
4475
        {
4476
          if (paUsedentries [iX])
4477
            pBuf->aTRNSentries [iX] = paAlphaentries [iX];
4478
        }
4479
4480
        break;
4481
      }
4482
    case MNG_DELTATYPE_DELTAALPHA :
4483
      {
4484
        for (iX = 0; iX < iCount; iX++)
4485
        {
4486
          if (paUsedentries [iX])
4487
            pBuf->aTRNSentries [iX] =
4488
                               (mng_uint8)(pBuf->aTRNSentries [iX] +
4489
                                           paAlphaentries [iX]);
4490
        }
4491
4492
        break;
4493
      }
4494
    case MNG_DELTATYPE_REPLACERGBA :
4495
      {
4496
        for (iX = 0; iX < iCount; iX++)
4497
        {
4498
          if (paUsedentries [iX])
4499
          {
4500
            pBuf->aPLTEentries [iX].iRed   = paIndexentries [iX].iRed;
4501
            pBuf->aPLTEentries [iX].iGreen = paIndexentries [iX].iGreen;
4502
            pBuf->aPLTEentries [iX].iBlue  = paIndexentries [iX].iBlue;
4503
            pBuf->aTRNSentries [iX]        = paAlphaentries [iX];
4504
          }
4505
        }
4506
4507
        break;
4508
      }
4509
    case MNG_DELTATYPE_DELTARGBA :
4510
      {
4511
        for (iX = 0; iX < iCount; iX++)
4512
        {
4513
          if (paUsedentries [iX])
4514
          {
4515
            pBuf->aPLTEentries [iX].iRed   =
4516
                               (mng_uint8)(pBuf->aPLTEentries [iX].iRed   +
4517
                                           paIndexentries [iX].iRed  );
4518
            pBuf->aPLTEentries [iX].iGreen =
4519
                               (mng_uint8)(pBuf->aPLTEentries [iX].iGreen +
4520
                                           paIndexentries [iX].iGreen);
4521
            pBuf->aPLTEentries [iX].iBlue  =
4522
                               (mng_uint8)(pBuf->aPLTEentries [iX].iBlue  +
4523
                                           paIndexentries [iX].iBlue );
4524
            pBuf->aTRNSentries [iX] =
4525
                               (mng_uint8)(pBuf->aTRNSentries [iX] +
4526
                                           paAlphaentries [iX]);
4527
          }
4528
        }
4529
4530
        break;
4531
      }
4532
  }
4533
4534
  if ((iType != MNG_DELTATYPE_REPLACERGB) && (iType != MNG_DELTATYPE_DELTARGB))
4535
  {
4536
    if (pBuf->bHasTRNS)
4537
    {
4538
      if (iCount > pBuf->iTRNScount)
4539
        pBuf->iTRNScount = iCount;
4540
    }
4541
    else
4542
    {
4543
      pBuf->iTRNScount = iCount;
4544
      pBuf->bHasTRNS   = MNG_TRUE;
4545
    }
4546
  }
4547
4548
  if ((iType != MNG_DELTATYPE_REPLACEALPHA) && (iType != MNG_DELTATYPE_DELTAALPHA))
4549
  {
4550
    if (iCount > pBuf->iPLTEcount)
4551
      pBuf->iPLTEcount = iCount;
4552
  }
4553
4554
#ifdef MNG_SUPPORT_TRACE
4555
  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_PPLT, MNG_LC_END)
4556
#endif
4557
4558
  return MNG_NOERROR;
4559
}
4560
4561
/* ************************************************************************** */
4562
4563
mng_retcode process_display_magn (mng_datap  pData,
4564
                                  mng_uint16 iFirstid,
4565
                                  mng_uint16 iLastid,
4566
                                  mng_uint16 iMethodX,
4567
                                  mng_uint16 iMX,
4568
                                  mng_uint16 iMY,
4569
                                  mng_uint16 iML,
4570
                                  mng_uint16 iMR,
4571
                                  mng_uint16 iMT,
4572
                                  mng_uint16 iMB,
4573
                                  mng_uint16 iMethodY)
4574
{
4575
  mng_uint16 iX;
4576
  mng_imagep pImage;
4577
4578
#ifdef MNG_SUPPORT_TRACE
4579
  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_MAGN, MNG_LC_START)
4580
#endif
4581
                                       /* iterate the object-ids */
4582
  for (iX = iFirstid; iX <= iLastid; iX++)
4583
  {
4584
    if (iX == 0)                       /* process object 0 ? */
4585
    {
4586
      pImage = (mng_imagep)pData->pObjzero;
4587
4588
      pImage->iMAGN_MethodX = iMethodX;
4589
      pImage->iMAGN_MethodY = iMethodY;
4590
      pImage->iMAGN_MX      = iMX;
4591
      pImage->iMAGN_MY      = iMY;
4592
      pImage->iMAGN_ML      = iML;
4593
      pImage->iMAGN_MR      = iMR;
4594
      pImage->iMAGN_MT      = iMT;
4595
      pImage->iMAGN_MB      = iMB;
4596
    }
4597
    else
4598
    {
4599
      pImage = find_imageobject (pData, iX);
4600
                                       /* object exists & is not frozen ? */
4601
      if ((pImage) && (!pImage->bFrozen))
4602
      {                                /* previous magnification to be done ? */
4603
        if ((pImage->iMAGN_MethodX) || (pImage->iMAGN_MethodY))
4604
        {
4605
          mng_retcode iRetcode = magnify_imageobject (pData, pImage);
4606
4607
          if (iRetcode)                /* on error bail out */
4608
            return iRetcode;
4609
        }
4610
4611
        pImage->iMAGN_MethodX = iMethodX;
4612
        pImage->iMAGN_MethodY = iMethodY;
4613
        pImage->iMAGN_MX      = iMX;
4614
        pImage->iMAGN_MY      = iMY;
4615
        pImage->iMAGN_ML      = iML;
4616
        pImage->iMAGN_MR      = iMR;
4617
        pImage->iMAGN_MT      = iMT;
4618
        pImage->iMAGN_MB      = iMB;
4619
      }
4620
    }
4621
  }
4622
4623
  iX = iFirstid;
4624
                                       /* iterate again for showing */
4625
  while ((iX <= iLastid) && (!pData->bTimerset))
4626
  {
4627
    if (iX)                            /* only real objects ! */
4628
    {
4629
      pImage = find_imageobject (pData, iX);
4630
                                       /* object exists & is not frozen  &
4631
                                          is visible & is viewable ? */
4632
      if ((pImage) && (!pImage->bFrozen) &&
4633
          (pImage->bVisible) && (pImage->bViewable))
4634
        display_image (pData, pImage, MNG_FALSE);
4635
    }
4636
4637
    iX++;
4638
  }
4639
4640
  if (pData->bTimerset)                /* broken ? */
4641
  {
4642
    pData->iMAGNfromid = iFirstid;
4643
    pData->iMAGNtoid   = iLastid;
4644
    pData->iBreakpoint = 9;
4645
  }
4646
4647
#ifdef MNG_SUPPORT_TRACE
4648
  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_MAGN, MNG_LC_END)
4649
#endif
4650
4651
  return MNG_NOERROR;
4652
}
4653
4654
/* ************************************************************************** */
4655
4656
mng_retcode process_display_magn2 (mng_datap pData)
4657
{
4658
  mng_uint16 iX;
4659
  mng_imagep pImage;
4660
4661
#ifdef MNG_SUPPORT_TRACE
4662
  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_MAGN, MNG_LC_START)
4663
#endif
4664
4665
  iX = pData->iMAGNfromid;
4666
                                       /* iterate again for showing */
4667
  while ((iX <= pData->iMAGNtoid) && (!pData->bTimerset))
4668
  {
4669
    if (iX)                            /* only real objects ! */
4670
    {
4671
      pImage = find_imageobject (pData, iX);
4672
                                       /* object exists & is not frozen  &
4673
                                          is visible & is viewable ? */
4674
      if ((pImage) && (!pImage->bFrozen) &&
4675
          (pImage->bVisible) && (pImage->bViewable))
4676
        display_image (pData, pImage, MNG_FALSE);
4677
    }
4678
4679
    iX++;
4680
  }
4681
4682
  if (pData->bTimerset)                /* broken ? */
4683
    pData->iBreakpoint = 9;
4684
4685
#ifdef MNG_SUPPORT_TRACE
4686
  MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_MAGN, MNG_LC_END)
4687
#endif
4688
4689
  return MNG_NOERROR;
4690
}
4691
4692
/* ************************************************************************** */
4693
4694
#endif /* MNG_INCLUDE_DISPLAY_PROCS */
4695
4696
/* ************************************************************************** */
4697
/* * end of file                                                            * */
4698
/* ************************************************************************** */
4699