1 /* ************************************************************************** */
2 /* *             For conditions of distribution and use,                    * */
3 /* *                see copyright notice in libmng.h                        * */
4 /* ************************************************************************** */
5 /* *                                                                        * */
6 /* * project   : libmng                                                     * */
7 /* * file      : libmng_pixels.c           copyright (c) 2000-2005 G.Juyn   * */
8 /* * version   : 1.0.10                                                     * */
9 /* *                                                                        * */
10 /* * purpose   : Pixel-row management routines (implementation)             * */
11 /* *                                                                        * */
12 /* * author    : G.Juyn                                                     * */
13 /* *                                                                        * */
14 /* * comment   : implementation of the pixel-row management routines        * */
15 /* *                                                                        * */
16 /* *             the dual alpha-composing for RGBA/BGRA/etc output-canvas'  * */
17 /* *             is based on the Note on Compositing chapter of the         * */
18 /* *             DOH-3 draft, noted to me by Adam M. Costello               * */
19 /* *                                                                        * */
20 /* * changes   : 0.5.1 - 05/08/2000 - G.Juyn                                * */
21 /* *             - changed strict-ANSI stuff                                * */
22 /* *             0.5.1 - 05/11/2000 - G.Juyn                                * */
23 /* *             - added callback error-reporting support                   * */
24 /* *             0.5.1 - 05/12/2000 - G.Juyn                                * */
25 /* *             - changed trace to macro for callback error-reporting      * */
26 /* *                                                                        * */
27 /* *             0.5.2 - 05/22/2000 - G.Juyn                                * */
28 /* *             - added JNG support                                        * */
29 /* *             0.5.2 - 05/30/2000 - G.Juyn                                * */
30 /* *             - fixed minor bugs 16-bit pixel-handling                   * */
31 /* *             - added delta-image row-processing routines                * */
32 /* *             0.5.2 - 06/02/2000 - G.Juyn                                * */
33 /* *             - fixed endian support (hopefully)                         * */
34 /* *             0.5.2 - 06/03/2000 - G.Juyn                                * */
35 /* *             - fixed makeup for Linux gcc compile                       * */
36 /* *             0.5.2 - 06/05/2000 - G.Juyn                                * */
37 /* *             - implemented app bkgd restore routines                    * */
38 /* *             - implemented RGBA8, ARGB8, BGRA8 & ABGR8 display routines * */
39 /* *             - added support for RGB8_A8 canvasstyle                    * */
40 /* *             0.5.2 - 06/09/2000 - G.Juyn                                * */
41 /* *             - fixed alpha-handling for alpha canvasstyles              * */
42 /* *                                                                        * */
43 /* *             0.5.3 - 06/16/2000 - G.Juyn                                * */
44 /* *             - changed progressive-display processing                   * */
45 /* *             0.5.3 - 06/17/2000 - G.Juyn                                * */
46 /* *             - changed to support delta-images                          * */
47 /* *             - optimized some store_xxx routines                        * */
48 /* *             0.5.3 - 06/20/2000 - G.Juyn                                * */
49 /* *             - fixed nasty bug with embedded PNG after delta-image      * */
50 /* *             0.5.3 - 06/24/2000 - G.Juyn                                * */
51 /* *             - fixed problem with 16-bit GA format                      * */
52 /* *             0.5.3 - 06/25/2000 - G.Juyn                                * */
53 /* *             - fixed problem with cheap transparency for 4-bit gray     * */
54 /* *             - fixed display_xxxx routines for interlaced images        * */
55 /* *             0.5.3 - 06/28/2000 - G.Juyn                                * */
56 /* *             - fixed compiler-warning for non-initialized iB variable   * */
57 /* *                                                                        * */
58 /* *             0.9.1 - 07/05/2000 - G.Juyn                                * */
59 /* *             - fixed mandatory BACK color to be opaque                  * */
60 /* *                                                                        * */
61 /* *             0.9.2 - 07/31/2000 - G.Juyn                                * */
62 /* *             - B110547 - fixed bug in interlace code                    * */
63 /* *             0.9.2 - 08/05/2000 - G.Juyn                                * */
64 /* *             - changed file-prefixes                                    * */
65 /* *                                                                        * */
66 /* *             0.9.3 - 08/20/2000 - G.Juyn                                * */
67 /* *             - fixed app-supplied background restore                    * */
68 /* *             0.9.3 - 08/26/2000 - G.Juyn                                * */
69 /* *             - added MAGN chunk                                         * */
70 /* *             0.9.3 - 09/07/2000 - G.Juyn                                * */
71 /* *             - added support for new filter_types                       * */
72 /* *             0.9.3 - 09/30/2000 - G.Juyn                                * */
73 /* *             - fixed MAGN rounding errors (thanks Matthias!)            * */
74 /* *             0.9.3 - 10/10/2000 - G.Juyn                                * */
75 /* *             - fixed alpha-blending for RGBA canvasstyle                * */
76 /* *             0.9.3 - 10/11/2000 - G.Juyn                                * */
77 /* *             - fixed alpha-blending for other alpha-canvasstyles        * */
78 /* *             0.9.3 - 10/16/2000 - G.Juyn                                * */
79 /* *             - added optional support for bKGD for PNG images           * */
80 /* *             - added support for JDAA                                   * */
81 /* *             0.9.3 - 10/17/2000 - G.Juyn                                * */
82 /* *             - fixed support for bKGD                                   * */
83 /* *             0.9.3 - 10/19/2000 - G.Juyn                                * */
84 /* *             - implemented delayed delta-processing                     * */
85 /* *             0.9.3 - 10/28/2000 - G.Juyn                                * */
86 /* *             - fixed tRNS processing for gray-image < 8-bits            * */
87 /* *                                                                        * */
88 /* *             0.9.4 - 12/16/2000 - G.Juyn                                * */
89 /* *             - fixed mixup of data- & function-pointers (thanks Dimitri)* */
90 /* *             0.9.4 -  1/18/2001 - G.Juyn                                * */
91 /* *             - removed "old" MAGN methods 3 & 4                         * */
92 /* *             - added "new" MAGN methods 3, 4 & 5                        * */
93 /* *             - removed test filter-methods 1 & 65                       * */
94 /* *                                                                        * */
95 /* *             1.0.1 - 04/21/2001 - G.Juyn (code by G.Kelly)              * */
96 /* *             - added BGRA8 canvas with premultiplied alpha              * */
97 /* *             1.0.1 - 04/25/2001 - G.Juyn                                * */
98 /* *             - moved mng_clear_cms to libmng_cms                        * */
99 /* *                                                                        * */
100 /* *             1.0.2 - 06/25/2001 - G.Juyn                                * */
101 /* *             - added option to turn off progressive refresh             * */
102 /* *                                                                        * */
103 /* *             1.0.4 - 11/04/2001 - G.Juyn                                * */
104 /* *             - fixed possible compile-problem in cleanup_rowproc        * */
105 /* *             1.0.4 - 06/22/2002 - G.Juyn                                * */
106 /* *             - B558212 - off by one error                               * */
107 /* *             - MNG subimage alpha composite wrong for rgba8 images      * */
108 /* *                                                                        * */
109 /* *             1.0.5 - 08/07/2002 - G.Juyn                                * */
110 /* *             - added test-option for PNG filter method 193 (=no filter) * */
111 /* *             1.0.5 - 08/15/2002 - G.Juyn                                * */
112 /* *             - completed PROM support                                   * */
113 /* *             - completed delta-image support                            * */
114 /* *             1.0.5 - 08/16/2002 - G.Juyn                                * */
115 /* *             - completed MAGN support (16-bit functions)                * */
116 /* *             1.0.5 - 08/19/2002 - G.Juyn                                * */
117 /* *             - B597134 - libmng pollutes the linker namespace           * */
118 /* *             1.0.5 - 09/19/2002 - G.Juyn                                * */
119 /* *             - optimized restore-background for bKGD cases              * */
120 /* *             1.0.5 - 09/20/2002 - G.Juyn                                * */
121 /* *             - finished support for BACK image & tiling                 * */
122 /* *             1.0.5 - 09/22/2002 - G.Juyn                                * */
123 /* *             - added bgrx8 canvas (filler byte)                         * */
124 /* *             1.0.5 - 09/23/2002 - G.Juyn                                * */
125 /* *             - added compose over/under routines for PAST processing    * */
126 /* *             - added flip & tile routines for PAST processing           * */
127 /* *                                                                        * */
128 /* *             1.0.6 - 03/09/2003 - G.Juyn                                * */
129 /* *             - hiding 12-bit JPEG stuff                                 * */
130 /* *             1.0.6 - 05/11/2003 - Glenn RP                              * */
131 /* *             - added size-optimization COMPOSE routine usage            * */
132 /* *             1.0.6 - 05/11/2003 - G. Juyn                               * */
133 /* *             - added conditionals around canvas update routines         * */
134 /* *             1.0.6 - 05/25/2003 - Glenn RP                              * */
135 /* *             - added size-optimization DIV255B8 routine usage           * */
136 /* *             1.0.6 - 06/09/2003 - G. R-P                                * */
137 /* *             - added conditionals around 8-bit magn routines            * */
138 /* *             1.0.6 - 07/07/2003 - G. R-P                                * */
139 /* *             - removed conditionals around 8-bit magn routines          * */
140 /* *             - added MNG_NO_16BIT_SUPPORT and MNG_NO_DELTA_PNG          * */
141 /* *               conditionals                                             * */
142 /* *             - reversed many loops to use decrementing counter          * */
143 /* *             - combined init functions                                  * */
144 /* *             - converted some switches to array references              * */
145 /* *             1.0.6 - 07/29/2003 - G.Juyn                                * */
146 /* *             - fixed duplicate for-loop                                 * */
147 /* *             1.0.6 - 07/29/2003 - G.R-P                                 * */
148 /* *             - added SKIPCHUNK conditionals around PAST chunk support   * */
149 /* *             - fixed "FOOTPRINT_COMPOSEIV" typo (now "FOOTPRINT_DIV")   * */
150 /* *             1.0.6 - 08/17/2003 - G.R-P                                 * */
151 /* *             - added more conditionals around "promote" functions       * */
152 /* *                                                                        * */
153 /* *             1.0.7 - 11/27/2003 - R.A                                   * */
154 /* *             - added CANVAS_RGB565 and CANVAS_BGR565                    * */
155 /* *             1.0.7 - 12/06/2003 - R.A                                   * */
156 /* *             - added CANVAS_RGBA565 and CANVAS_BGRA565                  * */
157 /* *             1.0.7 - 01/25/2004 - J.S                                   * */
158 /* *             - added premultiplied alpha canvas' for RGBA, ARGB, ABGR   * */
159 /* *             1.0.7 - 03/08/2004 - G.R-P                                 * */
160 /* *             - added more conditionals around 16-bit-supporting code    * */
161 /* *             1.0.7 - 03/09/2004 - G.Juyn                                * */
162 /* *             - fixed bug in promote_g8_g8 with 16bit support off        * */
163 /* *             1.0.7 - 03/09/2004 - G.R-P                                 * */
164 /* *             - more optimizations with 16bit support off                * */
165 /* *             1.0.7 - 03/10/2004 - G.Juyn                                * */
166 /* *             - fixed some warnings for 16bit optimizations              * */
167 /* *             1.0.7 - 03/21/2004 - G.Juyn                                * */
168 /* *             - fixed some 64-bit platform compiler warnings             * */
169 /* *                                                                        * */
170 /* *             1.0.8 - 06/20/2004 - G.Juyn                                * */
171 /* *             - some speed optimizations (thanks to John Stiles)         * */
172 /* *             1.0.8 - 08/01/2004 - G.Juyn                                * */
173 /* *             - added support for 3+byte pixelsize for JPEG's            * */
174 /* *                                                                        * */
175 /* *             1.0.9 - 10/10/2004 - G.R-P.                                * */
176 /* *             - added MNG_NO_1_2_4BIT_SUPPORT                            * */
177 /* *             1.0.9 - 10/14/2004 - G.Juyn                                * */
178 /* *             - added bgr565_a8 canvas-style (thanks to J. Elvander)     * */
179 /* *             1.0.9 - 12/05/2004 - G.Juyn                                * */
180 /* *             - added LITTLEENDIAN/BIGENDIAN fixtures (thanks J.Stiles)  * */
181 /* *             - fixed MNG_NO_1_2_4BIT_SUPPORT for TBBN1G04.PNG           * */
182 /* *             1.0.9 - 12/31/2004 - G.R-P.                                * */
183 /* *             - fixed warnings about C++ style (//) comments             * */
184 /* *                                                                        * */
185 /* *             1.0.10 - 07/06/2005 - G.R-P.                               * */
186 /* *             - added MORE MNG_NO_1_2_4BIT_SUPPORT                       * */
187 /* *             1.0.10 - 10/06/2005 - G.R-P.                               * */
188 /* *             - alloc more memory for MNG_NO_1_2_4BIT_SUPPORT            * */
189 /* *             1.0.10 - 12/07/2005 - G.R-P.                               * */
190 /* *             - optimized footprint of 16bit support                     * */
191 /* *             1.0.10 - 03/07/2006 - (thanks to W. Manthey)               * */
192 /* *             - added CANVAS_RGB555 and CANVAS_BGR555                    * */
193 /* *                                                                        * */
194 /* ************************************************************************** */
195 
196 #include "libmng.h"
197 #include "libmng_data.h"
198 #include "libmng_error.h"
199 #include "libmng_trace.h"
200 #ifdef __BORLANDC__
201 #pragma hdrstop
202 #endif
203 #include "libmng_objects.h"
204 #include "libmng_object_prc.h"
205 #include "libmng_memory.h"
206 #include "libmng_cms.h"
207 #include "libmng_filter.h"
208 #include "libmng_pixels.h"
209 
210 #if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
211 #pragma option -A                      /* force ANSI-C */
212 #endif
213 
214 /* ************************************************************************** */
215 
216 #ifdef MNG_INCLUDE_DISPLAY_PROCS
217 
218 /* TODO: magnification & canvas-positioning/-clipping */
219 
220 /* TODO: major optimization of pixel-loops by using assembler (?) */
221 
222 /* ************************************************************************** */
223 /* *                                                                        * */
224 /* * Interlace tables                                                       * */
225 /* *                                                                        * */
226 /* ************************************************************************** */
227 
228 MNG_LOCAL mng_uint32 const interlace_row      [7] = { 0, 0, 4, 0, 2, 0, 1 };
229 MNG_LOCAL mng_uint32 const interlace_rowskip  [7] = { 8, 8, 8, 4, 4, 2, 2 };
230 MNG_LOCAL mng_uint32 const interlace_col      [7] = { 0, 4, 0, 2, 0, 1, 0 };
231 MNG_LOCAL mng_uint32 const interlace_colskip  [7] = { 8, 8, 4, 4, 2, 2, 1 };
232 MNG_LOCAL mng_uint32 const interlace_roundoff [7] = { 7, 7, 3, 3, 1, 1, 0 };
233 MNG_LOCAL mng_uint32 const interlace_divider  [7] = { 3, 3, 2, 2, 1, 1, 0 };
234 
235 /* ************************************************************************** */
236 /* *                                                                        * */
237 /* * Alpha composing macros                                                 * */
238 /* * the code below is slightly modified from the libpng package            * */
239 /* * the original was last optimized by Greg Roelofs & Mark Adler           * */
240 /* *                                                                        * */
241 /* ************************************************************************** */
242 
243 #define MNG_COMPOSE8(RET,FG,ALPHA,BG) {                                    \
244        mng_uint16 iH = (mng_uint16)((mng_uint16)(FG) * (mng_uint16)(ALPHA) \
245                         + (mng_uint16)(BG)*(mng_uint16)(255 -              \
246                           (mng_uint16)(ALPHA)) + (mng_uint16)128);         \
247        (RET) = (mng_uint8)((iH + (iH >> 8)) >> 8); }
248 
249 #define MNG_COMPOSE16(RET,FG,ALPHA,BG) {                                   \
250        mng_uint32 iH = (mng_uint32)((mng_uint32)(FG) * (mng_uint32)(ALPHA) \
251                         + (mng_uint32)(BG)*(mng_uint32)(65535L -           \
252                           (mng_uint32)(ALPHA)) + (mng_uint32)32768L);      \
253        (RET) = (mng_uint16)((iH + (iH >> 16)) >> 16); }
254 
255 /* ************************************************************************** */
256 /* *                                                                        * */
257 /* * Alpha blending macros                                                  * */
258 /* * this code is based on Adam Costello's "Note on Compositing" from the   * */
259 /* * mng-list which gives the following formula:                            * */
260 /* *                                                                        * */
261 /* * top pixel       = (Rt, Gt, Bt, At)                                     * */
262 /* * bottom pixel    = (Rb, Gb, Bb, Ab)                                     * */
263 /* * composite pixel = (Rc, Gc, Bc, Ac)                                     * */
264 /* *                                                                        * */
265 /* * all values in the range 0..1                                           * */
266 /* *                                                                        * */
267 /* * Ac = 1 - (1 - At)(1 - Ab)                                              * */
268 /* * s = At / Ac                                                            * */
269 /* * t = (1 - At) Ab / Ac                                                   * */
270 /* * Rc = s Rt + t Rb                                                       * */
271 /* * Gc = s Gt + t Gb                                                       * */
272 /* * Bc = s Bt + t Bb                                                       * */
273 /* *                                                                        * */
274 /* * (I just hope I coded it correctly in integer arithmetic...)            * */
275 /* *                                                                        * */
276 /* ************************************************************************** */
277 
278 #define MNG_BLEND8(RT, GT, BT, AT, RB, GB, BB, AB, RC, GC, BC, AC) {         \
279        mng_uint32 S, T;                                                      \
280        (AC) = (mng_uint8)((mng_uint32)255 -                                  \
281                           ((((mng_uint32)255 - (mng_uint32)(AT)) *           \
282                             ((mng_uint32)255 - (mng_uint32)(AB))   ) >> 8)); \
283        S    = (mng_uint32)(((mng_uint32)(AT) << 8) /                         \
284                            (mng_uint32)(AC));                                \
285        T    = (mng_uint32)(((mng_uint32)255 - (mng_uint32)(AT)) *            \
286                             (mng_uint32)(AB) / (mng_uint32)(AC));            \
287        (RC) = (mng_uint8)((S * (mng_uint32)(RT) +                            \
288                            T * (mng_uint32)(RB) + (mng_uint32)127) >> 8);    \
289        (GC) = (mng_uint8)((S * (mng_uint32)(GT) +                            \
290                            T * (mng_uint32)(GB) + (mng_uint32)127) >> 8);    \
291        (BC) = (mng_uint8)((S * (mng_uint32)(BT) +                            \
292                            T * (mng_uint32)(BB) + (mng_uint32)127) >> 8); }
293 
294 #define MNG_BLEND16(RT, GT, BT, AT, RB, GB, BB, AB, RC, GC, BC, AC) {            \
295        mng_uint32 S, T;                                                          \
296        (AC) = (mng_uint16)((mng_uint32)65535 -                                   \
297                            ((((mng_uint32)65535 - (mng_uint32)(AT)) *            \
298                              ((mng_uint32)65535 - (mng_uint32)(AB))   ) >> 16)); \
299        S    = (mng_uint32)(((mng_uint32)(AT) << 16) /                            \
300                             (mng_uint32)(AC));                                   \
301        T    = (mng_uint32)(((mng_uint32)65535 - (mng_uint32)(AT)) *              \
302                             (mng_uint32)(AB) / (mng_uint32)(AC));                \
303        (RC) = (mng_uint16)((S * (mng_uint32)(RT) +                               \
304                             T * (mng_uint32)(RB) + (mng_uint32)32767) >> 16);    \
305        (GC) = (mng_uint16)((S * (mng_uint32)(GT) +                               \
306                             T * (mng_uint32)(GB) + (mng_uint32)32767) >> 16);    \
307        (BC) = (mng_uint16)((S * (mng_uint32)(BT) +                               \
308                             T * (mng_uint32)(BB) + (mng_uint32)32767) >> 16); }
309 
310 /* ************************************************************************** */
311 
312 /* note a good optimizing compiler will optimize this */
313 #define DIV255B8(x) (mng_uint8)(((x) + 127) / 255)
314 #define DIV255B16(x) (mng_uint16)(((x) + 32767) / 65535)
315 
316 /* ************************************************************************** */
317 /* *                                                                        * */
318 /* * Progressive display check - checks to see if progressive display is    * */
319 /* * in order & indicates so                                                * */
320 /* *                                                                        * */
321 /* * The routine is called after a call to one of the display_xxx routines  * */
322 /* * if appropriate                                                         * */
323 /* *                                                                        * */
324 /* * The refresh is warrented in the read_chunk routine (mng_read.c)        * */
325 /* * and only during read&display processing, since there's not much point  * */
326 /* * doing it from memory!                                                  * */
327 /* *                                                                        * */
328 /* ************************************************************************** */
329 
mng_display_progressive_check(mng_datap pData)330 mng_retcode mng_display_progressive_check (mng_datap pData)
331 {
332   if ((pData->bDoProgressive) &&       /* need progressive display? */
333       ((pData->eImagetype != mng_it_mng) || (pData->iDataheight > 300)) &&
334       (pData->iDestb - pData->iDestt > 50) && (!pData->pCurraniobj))
335   {
336     mng_int32 iC = pData->iRow + pData->iDestt - pData->iSourcet;
337 
338     if (iC % 20 == 0)                  /* every 20th line */
339       pData->bNeedrefresh = MNG_TRUE;
340 
341   }
342 
343   return MNG_NOERROR;
344 }
345 
346 /* ************************************************************************** */
347 /* *                                                                        * */
348 /* * Display routines - convert rowdata (which is already color-corrected)  * */
349 /* * to the output canvas, respecting the opacity information               * */
350 /* *                                                                        * */
351 /* ************************************************************************** */
352 
check_update_region(mng_datap pData)353 MNG_LOCAL void check_update_region (mng_datap pData)
354 {                                      /* determine actual canvas row */
355   mng_int32 iRow = pData->iRow + pData->iDestt - pData->iSourcet;
356                                        /* check for change in update-region */
357   if ((pData->iDestl < (mng_int32)pData->iUpdateleft) || (pData->iUpdateright == 0))
358     pData->iUpdateleft   = pData->iDestl;
359 
360   if (pData->iDestr > (mng_int32)pData->iUpdateright)
361     pData->iUpdateright  = pData->iDestr;
362 
363   if ((iRow < (mng_int32)pData->iUpdatetop) || (pData->iUpdatebottom == 0))
364     pData->iUpdatetop    = iRow;
365 
366   if (iRow+1 > (mng_int32)pData->iUpdatebottom)
367     pData->iUpdatebottom = iRow+1;
368 
369   return;
370 }
371 
372 /* ************************************************************************** */
373 
374 #ifndef MNG_SKIPCANVAS_RGB8
375 #ifndef MNG_NO_16BIT_SUPPORT
376 #ifndef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
mng_display_rgb8(mng_datap pData)377 mng_retcode mng_display_rgb8 (mng_datap pData)
378 {
379   mng_uint8p pScanline;
380   mng_uint8p pDataline;
381   mng_int32  iX;
382   mng_uint16 iA16;
383   mng_uint16 iFGr16, iFGg16, iFGb16;
384   mng_uint16 iBGr16, iBGg16, iBGb16;
385   mng_uint8  iA8;
386 
387 #ifdef MNG_SUPPORT_TRACE
388   MNG_TRACE (pData, MNG_FN_DISPLAY_RGB8, MNG_LC_START);
389 #endif
390                                        /* viewable row ? */
391   if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
392   {                                    /* address destination row */
393     pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
394                                                    pData->iRow + pData->iDestt -
395                                                    pData->iSourcet);
396                                        /* adjust destination row starting-point */
397     pScanline = pScanline + (pData->iCol * 3) + (pData->iDestl * 3);
398     pDataline = pData->pRGBArow;       /* address source row */
399 
400     if (pData->bIsRGBA16)              /* adjust source row starting-point */
401       pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 3);
402     else
403       pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
404 
405     if (pData->bIsOpaque)              /* forget about transparency ? */
406     {
407       if (pData->bIsRGBA16)            /* 16-bit input row ? */
408       {
409         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
410              iX += pData->iColinc)
411         {                              /* scale down by dropping the LSB */
412           *pScanline     = *pDataline;
413           *(pScanline+1) = *(pDataline+2);
414           *(pScanline+2) = *(pDataline+4);
415 
416           pScanline += (pData->iColinc * 3);
417           pDataline += 8;
418         }
419       }
420       else
421       {
422         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
423              iX += pData->iColinc)
424         {                              /* copy the values */
425           *pScanline     = *pDataline;
426           *(pScanline+1) = *(pDataline+1);
427           *(pScanline+2) = *(pDataline+2);
428 
429           pScanline += (pData->iColinc * 3);
430           pDataline += 4;
431         }
432       }
433     }
434     else
435     {
436       if (pData->bIsRGBA16)            /* 16-bit input row ? */
437       {
438         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
439              iX += pData->iColinc)
440         {
441           iA16 = mng_get_uint16 (pDataline+6);
442 
443           if (iA16)                    /* any opacity at all ? */
444           {
445             if (iA16 == 0xFFFF)        /* fully opaque ? */
446             {                          /* scale down by dropping the LSB */
447               *pScanline     = *pDataline;
448               *(pScanline+1) = *(pDataline+2);
449               *(pScanline+2) = *(pDataline+4);
450             }
451             else
452             {                          /* get the proper values */
453               iFGr16 = mng_get_uint16 (pDataline  );
454               iFGg16 = mng_get_uint16 (pDataline+2);
455               iFGb16 = mng_get_uint16 (pDataline+4);
456                                        /* scale background up */
457               iBGr16 = (mng_uint16)(*pScanline    );
458               iBGg16 = (mng_uint16)(*(pScanline+1));
459               iBGb16 = (mng_uint16)(*(pScanline+2));
460               iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
461               iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
462               iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
463                                        /* now compose */
464               MNG_COMPOSE16(iFGr16, iFGr16, iA16, iBGr16);
465               MNG_COMPOSE16(iFGg16, iFGg16, iA16, iBGg16);
466               MNG_COMPOSE16(iFGb16, iFGb16, iA16, iBGb16);
467                                        /* and return the composed values */
468               *pScanline     = (mng_uint8)(iFGr16 >> 8);
469               *(pScanline+1) = (mng_uint8)(iFGg16 >> 8);
470               *(pScanline+2) = (mng_uint8)(iFGb16 >> 8);
471             }
472           }
473 
474           pScanline += (pData->iColinc * 3);
475           pDataline += 8;
476         }
477       }
478       else
479       {
480         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
481              iX += pData->iColinc)
482         {
483           iA8 = *(pDataline+3);        /* get alpha value */
484 
485           if (iA8)                     /* any opacity at all ? */
486           {
487             if (iA8 == 0xFF)           /* fully opaque ? */
488             {                          /* then simply copy the values */
489               *pScanline     = *pDataline;
490               *(pScanline+1) = *(pDataline+1);
491               *(pScanline+2) = *(pDataline+2);
492             }
493             else
494             {                          /* do alpha composing */
495               MNG_COMPOSE8 (*pScanline,     *pDataline,     iA8, *pScanline    );
496               MNG_COMPOSE8 (*(pScanline+1), *(pDataline+1), iA8, *(pScanline+1));
497               MNG_COMPOSE8 (*(pScanline+2), *(pDataline+2), iA8, *(pScanline+2));
498             }
499           }
500 
501           pScanline += (pData->iColinc * 3);
502           pDataline += 4;
503         }
504       }
505     }
506   }
507 
508   check_update_region (pData);
509 
510 #ifdef MNG_SUPPORT_TRACE
511   MNG_TRACE (pData, MNG_FN_DISPLAY_RGB8, MNG_LC_END);
512 #endif
513 
514   return MNG_NOERROR;
515 }
516 #else /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
mng_display_rgb8(mng_datap pData)517 mng_retcode mng_display_rgb8 (mng_datap pData)
518 {
519   mng_uint8p pScanline;
520   mng_uint8p pDataline;
521   mng_int32  iX;
522   mng_uint16 iA16;
523   mng_uint16 iFGg16;
524   mng_uint16 iBGg16;
525   mng_uint8  iA8;
526   mng_uint8  iBps;
527 
528 #ifdef MNG_SUPPORT_TRACE
529   MNG_TRACE (pData, MNG_FN_DISPLAY_RGB8, MNG_LC_START);
530 #endif
531 
532   iBps=(mng_uint8)(pData->bIsRGBA16 ? 2:1);
533                                        /* viewable row ? */
534   if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
535   {                                    /* address destination row */
536     pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
537                                                    pData->iRow + pData->iDestt -
538                                                    pData->iSourcet);
539                                        /* adjust destination row starting-point */
540     pScanline = pScanline + (pData->iCol * 3) + (pData->iDestl * 3);
541     pDataline = pData->pRGBArow;       /* address source row */
542 
543     /* adjust source row starting-point */
544     pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << (iBps+1));
545 
546     if (pData->bIsOpaque)              /* forget about transparency ? */
547     {
548       {
549         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
550              iX += pData->iColinc)
551         {                              /* scale down by dropping the LSB */
552           *pScanline     = *pDataline;
553           *(pScanline+1) = *(pDataline+iBps);
554           *(pScanline+2) = *(pDataline+2*iBps);
555 
556           pScanline += (pData->iColinc * 3);
557           pDataline += 4*iBps;
558         }
559       }
560     }
561     else
562     {
563       if (pData->bIsRGBA16)            /* 16-bit input row ? */
564       {
565         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
566              iX += pData->iColinc)
567         {
568           iA16 = mng_get_uint16 (pDataline+6);
569 
570           if (iA16)                    /* any opacity at all ? */
571           {
572             if (iA16 == 0xFFFF)        /* fully opaque ? */
573             {                          /* scale down by dropping the LSB */
574               *pScanline     = *pDataline;
575               *(pScanline+1) = *(pDataline+2);
576               *(pScanline+2) = *(pDataline+4);
577             }
578             else
579             {                          /* get the proper values */
580               int i;
581               for (i=2; i >= 0; i--)
582               {
583                 iFGg16 = mng_get_uint16 (pDataline+i+i);
584                                          /* scale background up */
585                 iBGg16 = (mng_uint16)(*(pScanline+i));
586                 iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
587                                          /* now compose */
588                 MNG_COMPOSE16(iFGg16, iFGg16, iA16, iBGg16);
589                                          /* and return the composed values */
590                 *(pScanline+i) = (mng_uint8)(iFGg16 >> 8);
591               }
592             }
593           }
594 
595           pScanline += (pData->iColinc * 3);
596           pDataline += 8;
597         }
598       }
599       else
600       {
601         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
602              iX += pData->iColinc)
603         {
604           iA8 = *(pDataline+3);        /* get alpha value */
605 
606           if (iA8)                     /* any opacity at all ? */
607           {
608             if (iA8 == 0xFF)           /* fully opaque ? */
609             {                          /* then simply copy the values */
610               *pScanline     = *pDataline;
611               *(pScanline+1) = *(pDataline+1);
612               *(pScanline+2) = *(pDataline+2);
613             }
614             else
615             {                          /* do alpha composing */
616               int i;
617               for (i=2; i >= 0; i--)
618               {
619               MNG_COMPOSE8 (*(pScanline+i), *(pDataline+i), iA8, *(pScanline+i));
620               }
621             }
622           }
623 
624           pScanline += (pData->iColinc * 3);
625           pDataline += 4;
626         }
627       }
628     }
629   }
630 
631   check_update_region (pData);
632 
633 #ifdef MNG_SUPPORT_TRACE
634   MNG_TRACE (pData, MNG_FN_DISPLAY_RGB8, MNG_LC_END);
635 #endif
636 
637   return MNG_NOERROR;
638 }
639 #endif /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
640 #else /* MNG_NO_16BIT_SUPPORT */
mng_display_rgb8(mng_datap pData)641 mng_retcode mng_display_rgb8 (mng_datap pData)
642 {
643   mng_uint8p pScanline;
644   mng_uint8p pDataline;
645   mng_int32  iX;
646   mng_uint8  iA8;
647 
648 #ifdef MNG_SUPPORT_TRACE
649   MNG_TRACE (pData, MNG_FN_DISPLAY_RGB8, MNG_LC_START);
650 #endif
651                                        /* viewable row ? */
652   if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
653   {                                    /* address destination row */
654     pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
655                                                    pData->iRow + pData->iDestt -
656                                                    pData->iSourcet);
657                                        /* adjust destination row starting-point */
658     pScanline = pScanline + (pData->iCol * 3) + (pData->iDestl * 3);
659     pDataline = pData->pRGBArow;       /* address source row */
660 
661       pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
662 
663     if (pData->bIsOpaque)              /* forget about transparency ? */
664     {
665       {
666         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
667              iX += pData->iColinc)
668         {                              /* copy the values */
669           *pScanline     = *pDataline;
670           *(pScanline+1) = *(pDataline+1);
671           *(pScanline+2) = *(pDataline+2);
672 
673           pScanline += (pData->iColinc * 3);
674           pDataline += 4;
675         }
676       }
677     }
678     else
679     {
680       {
681         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
682              iX += pData->iColinc)
683         {
684           iA8 = *(pDataline+3);        /* get alpha value */
685 
686           if (iA8)                     /* any opacity at all ? */
687           {
688             if (iA8 == 0xFF)           /* fully opaque ? */
689             {                          /* then simply copy the values */
690               *pScanline     = *pDataline;
691               *(pScanline+1) = *(pDataline+1);
692               *(pScanline+2) = *(pDataline+2);
693             }
694             else
695             {                          /* do alpha composing */
696 #ifdef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
697               int i;
698               for (i=2; i >= 0; i--)
699               {
700               MNG_COMPOSE8 (*(pScanline+i), *(pDataline+i), iA8, *(pScanline+i));
701               }
702 #else
703               MNG_COMPOSE8 (*pScanline,     *pDataline,     iA8, *pScanline    );
704               MNG_COMPOSE8 (*(pScanline+1), *(pDataline+1), iA8, *(pScanline+1));
705               MNG_COMPOSE8 (*(pScanline+2), *(pDataline+2), iA8, *(pScanline+2));
706 #endif
707             }
708           }
709 
710           pScanline += (pData->iColinc * 3);
711           pDataline += 4;
712         }
713       }
714     }
715   }
716 
717   check_update_region (pData);
718 
719 #ifdef MNG_SUPPORT_TRACE
720   MNG_TRACE (pData, MNG_FN_DISPLAY_RGB8, MNG_LC_END);
721 #endif
722 
723   return MNG_NOERROR;
724 }
725 #endif /* MNG_NO_16BIT_SUPPORT */
726 #endif /* MNG_SKIPCANVAS_RGB8 */
727 
728 /* ************************************************************************** */
729 
730 #ifndef MNG_SKIPCANVAS_RGBA8
731 #ifndef MNG_NO_16BIT_SUPPORT
732 #ifndef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
mng_display_rgba8(mng_datap pData)733 mng_retcode mng_display_rgba8 (mng_datap pData)
734 {
735   mng_uint8p pScanline;
736   mng_uint8p pDataline;
737   mng_int32  iX;
738   mng_uint8  iFGa8, iBGa8, iCa8;
739   mng_uint16 iFGa16, iBGa16, iCa16;
740   mng_uint16 iFGr16, iFGg16, iFGb16;
741   mng_uint16 iBGr16, iBGg16, iBGb16;
742   mng_uint16 iCr16, iCg16, iCb16;
743   mng_uint8  iCr8, iCg8, iCb8;
744 
745 #ifdef MNG_SUPPORT_TRACE
746   MNG_TRACE (pData, MNG_FN_DISPLAY_RGBA8, MNG_LC_START);
747 #endif
748                                        /* viewable row ? */
749   if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
750   {                                    /* address destination row */
751     pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
752                                                    pData->iRow + pData->iDestt -
753                                                    pData->iSourcet);
754                                        /* adjust destination row starting-point */
755     pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
756     pDataline = pData->pRGBArow;       /* address source row */
757 
758     if (pData->bIsRGBA16)              /* adjust source row starting-point */
759       pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 3);
760     else
761       pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
762 
763     if (pData->bIsOpaque)              /* forget about transparency ? */
764     {
765       if (pData->bIsRGBA16)            /* 16-bit input row ? */
766       {
767         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
768              iX += pData->iColinc)
769         {                              /* scale down by dropping the LSB */
770           *pScanline     = *pDataline;
771           *(pScanline+1) = *(pDataline+2);
772           *(pScanline+2) = *(pDataline+4);
773           *(pScanline+3) = *(pDataline+6);
774 
775           pScanline += (pData->iColinc << 2);
776           pDataline += 8;
777         }
778       }
779       else
780       {
781         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
782              iX += pData->iColinc)
783         {                              /* copy the values */
784           *pScanline     = *pDataline;
785           *(pScanline+1) = *(pDataline+1);
786           *(pScanline+2) = *(pDataline+2);
787           *(pScanline+3) = *(pDataline+3);
788 
789           pScanline += (pData->iColinc << 2);
790           pDataline += 4;
791         }
792       }
793     }
794     else
795     {
796       if (pData->bIsRGBA16)            /* 16-bit input row ? */
797       {
798         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
799              iX += pData->iColinc)
800         {                              /* get alpha values */
801           iFGa16 = mng_get_uint16 (pDataline+6);
802           iBGa16 = (mng_uint16)(*(pScanline+3));
803           iBGa16 = (mng_uint16)(iBGa16 << 8) | iBGa16;
804 
805           if (iFGa16)                  /* any opacity at all ? */
806           {                            /* fully opaque or background fully transparent ? */
807             if ((iFGa16 == 0xFFFF) || (iBGa16 == 0))
808             {                          /* plain copy it */
809               *pScanline     = *pDataline;
810               *(pScanline+1) = *(pDataline+2);
811               *(pScanline+2) = *(pDataline+4);
812               *(pScanline+3) = *(pDataline+6);
813             }
814             else
815             {
816               if (iBGa16 == 0xFFFF)    /* background fully opaque ? */
817               {                        /* get the proper values */
818                 iFGr16 = mng_get_uint16 (pDataline  );
819                 iFGg16 = mng_get_uint16 (pDataline+2);
820                 iFGb16 = mng_get_uint16 (pDataline+4);
821                                        /* scale background up */
822                 iBGr16 = (mng_uint16)(*pScanline    );
823                 iBGg16 = (mng_uint16)(*(pScanline+1));
824                 iBGb16 = (mng_uint16)(*(pScanline+2));
825                 iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
826                 iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
827                 iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
828                                        /* now compose */
829                 MNG_COMPOSE16(iFGr16, iFGr16, iFGa16, iBGr16);
830                 MNG_COMPOSE16(iFGg16, iFGg16, iFGa16, iBGg16);
831                 MNG_COMPOSE16(iFGb16, iFGb16, iFGa16, iBGb16);
832                                        /* and return the composed values */
833                 *pScanline     = (mng_uint8)(iFGr16 >> 8);
834                 *(pScanline+1) = (mng_uint8)(iFGg16 >> 8);
835                 *(pScanline+2) = (mng_uint8)(iFGb16 >> 8);
836                                        /* alpha remains fully opaque !!! */
837               }
838               else
839               {                        /* scale background up */
840                 iBGr16 = (mng_uint16)(*pScanline    );
841                 iBGg16 = (mng_uint16)(*(pScanline+1));
842                 iBGb16 = (mng_uint16)(*(pScanline+2));
843                 iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
844                 iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
845                 iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
846                                        /* let's blend */
847                 MNG_BLEND16 (mng_get_uint16 (pDataline  ),
848                              mng_get_uint16 (pDataline+2),
849                              mng_get_uint16 (pDataline+4), iFGa16,
850                              iBGr16, iBGg16, iBGb16, iBGa16,
851                              iCr16,  iCg16,  iCb16,  iCa16);
852                                        /* and return the composed values */
853                 *pScanline     = (mng_uint8)(iCr16 >> 8);
854                 *(pScanline+1) = (mng_uint8)(iCg16 >> 8);
855                 *(pScanline+2) = (mng_uint8)(iCb16 >> 8);
856                 *(pScanline+3) = (mng_uint8)(iCa16 >> 8);
857               }
858             }
859           }
860 
861           pScanline += (pData->iColinc << 2);
862           pDataline += 8;
863         }
864       }
865       else
866       {
867         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
868              iX += pData->iColinc)
869         {
870           iFGa8 = *(pDataline+3);      /* get alpha values */
871           iBGa8 = *(pScanline+3);
872 
873           if (iFGa8)                   /* any opacity at all ? */
874           {                            /* fully opaque or background fully transparent ? */
875             if ((iFGa8 == 0xFF) || (iBGa8 == 0))
876             {                          /* then simply copy the values */
877               *pScanline     = *pDataline;
878               *(pScanline+1) = *(pDataline+1);
879               *(pScanline+2) = *(pDataline+2);
880               *(pScanline+3) = *(pDataline+3);
881             }
882             else
883             {
884               if (iBGa8 == 0xFF)       /* background fully opaque ? */
885               {                        /* do alpha composing */
886                 MNG_COMPOSE8 (*pScanline,     *pDataline,     iFGa8, *pScanline    );
887                 MNG_COMPOSE8 (*(pScanline+1), *(pDataline+1), iFGa8, *(pScanline+1));
888                 MNG_COMPOSE8 (*(pScanline+2), *(pDataline+2), iFGa8, *(pScanline+2));
889                                        /* alpha remains fully opaque !!! */
890               }
891               else
892               {                        /* now blend */
893                 MNG_BLEND8 (*pDataline, *(pDataline+1), *(pDataline+2), iFGa8,
894                             *pScanline, *(pScanline+1), *(pScanline+2), iBGa8,
895                             iCr8, iCg8, iCb8, iCa8);
896                                        /* and return the composed values */
897                 *pScanline     = iCr8;
898                 *(pScanline+1) = iCg8;
899                 *(pScanline+2) = iCb8;
900                 *(pScanline+3) = iCa8;
901               }
902             }
903           }
904 
905           pScanline += (pData->iColinc << 2);
906           pDataline += 4;
907         }
908       }
909     }
910   }
911 
912   check_update_region (pData);
913 
914 #ifdef MNG_SUPPORT_TRACE
915   MNG_TRACE (pData, MNG_FN_DISPLAY_RGBA8, MNG_LC_END);
916 #endif
917 
918   return MNG_NOERROR;
919 }
920 #else /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
mng_display_rgba8(mng_datap pData)921 mng_retcode mng_display_rgba8 (mng_datap pData)
922 {
923   mng_uint8p pScanline;
924   mng_uint8p pDataline;
925   mng_int32  iX;
926   mng_uint8  iFGa8, iBGa8, iCa8;
927   mng_uint16 iFGa16, iBGa16, iCa16;
928   mng_uint16 iFGg16;
929   mng_uint16 iBGr16, iBGg16, iBGb16;
930   mng_uint16 iCr16, iCg16, iCb16;
931   mng_uint8  iCr8, iCg8, iCb8;
932   mng_uint8  iBps;
933 
934 #ifdef MNG_SUPPORT_TRACE
935   MNG_TRACE (pData, MNG_FN_DISPLAY_RGBA8, MNG_LC_START);
936 #endif
937 
938   iBps=(mng_uint8)(pData->bIsRGBA16 ? 2:1);
939                                        /* viewable row ? */
940   if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
941   {                                    /* address destination row */
942     pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
943                                                    pData->iRow + pData->iDestt -
944                                                    pData->iSourcet);
945                                        /* adjust destination row starting-point */
946     pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
947     pDataline = pData->pRGBArow;       /* address source row */
948 
949     /* adjust source row starting-point */
950     pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << (iBps+1));
951 
952     if (pData->bIsOpaque)              /* forget about transparency ? */
953     {
954         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
955              iX += pData->iColinc)
956         {                              /* scale down by dropping the LSB */
957           *pScanline     = *pDataline;
958           *(pScanline+1) = *(pDataline+iBps);
959           *(pScanline+2) = *(pDataline+2*iBps);
960           *(pScanline+3) = *(pDataline+3*iBps);
961 
962           pScanline += (pData->iColinc << 2);
963           pDataline += 4*iBps;
964         }
965     }
966     else
967     {
968       if (pData->bIsRGBA16)            /* 16-bit input row ? */
969       {
970         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
971              iX += pData->iColinc)
972         {                              /* get alpha values */
973           iFGa16 = mng_get_uint16 (pDataline+6);
974           iBGa16 = (mng_uint16)(*(pScanline+3));
975           iBGa16 = (mng_uint16)(iBGa16 << 8) | iBGa16;
976 
977           if (iFGa16)                  /* any opacity at all ? */
978           {                            /* fully opaque or background fully transparent ? */
979             if ((iFGa16 == 0xFFFF) || (iBGa16 == 0))
980             {                          /* plain copy it */
981               *pScanline     = *pDataline;
982               *(pScanline+1) = *(pDataline+2);
983               *(pScanline+2) = *(pDataline+4);
984               *(pScanline+3) = *(pDataline+6);
985             }
986             else
987             {
988               if (iBGa16 == 0xFFFF)    /* background fully opaque ? */
989               {                        /* get the proper values */
990               int i;
991               for (i=2; i >= 0; i--)
992               {
993                 iFGg16 = mng_get_uint16 (pDataline+i+i);
994                                        /* scale background up */
995                 iBGg16 = (mng_uint16)(*(pScanline+i));
996                 iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
997                                        /* now compose */
998                 MNG_COMPOSE16(iFGg16, iFGg16, iFGa16, iBGg16);
999                                        /* and return the composed values */
1000                 *(pScanline+i) = (mng_uint8)(iFGg16 >> 8);
1001                                        /* alpha remains fully opaque !!! */
1002               }
1003               }
1004               else
1005               {                        /* scale background up */
1006                 iBGr16 = (mng_uint16)(*pScanline    );
1007                 iBGg16 = (mng_uint16)(*(pScanline+1));
1008                 iBGb16 = (mng_uint16)(*(pScanline+2));
1009                 iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
1010                 iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
1011                 iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
1012                                        /* let's blend */
1013                 MNG_BLEND16 (mng_get_uint16 (pDataline  ),
1014                              mng_get_uint16 (pDataline+2),
1015                              mng_get_uint16 (pDataline+4), iFGa16,
1016                              iBGr16, iBGg16, iBGb16, iBGa16,
1017                              iCr16,  iCg16,  iCb16,  iCa16);
1018                                        /* and return the composed values */
1019                 *pScanline     = (mng_uint8)(iCr16 >> 8);
1020                 *(pScanline+1) = (mng_uint8)(iCg16 >> 8);
1021                 *(pScanline+2) = (mng_uint8)(iCb16 >> 8);
1022                 *(pScanline+3) = (mng_uint8)(iCa16 >> 8);
1023               }
1024             }
1025           }
1026 
1027           pScanline += (pData->iColinc << 2);
1028           pDataline += 8;
1029         }
1030       }
1031       else
1032       {
1033         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
1034              iX += pData->iColinc)
1035         {
1036           iFGa8 = *(pDataline+3);      /* get alpha values */
1037           iBGa8 = *(pScanline+3);
1038 
1039           if (iFGa8)                   /* any opacity at all ? */
1040           {                            /* fully opaque or background fully transparent ? */
1041             if ((iFGa8 == 0xFF) || (iBGa8 == 0))
1042             {                          /* then simply copy the values */
1043               *pScanline     = *pDataline;
1044               *(pScanline+1) = *(pDataline+1);
1045               *(pScanline+2) = *(pDataline+2);
1046               *(pScanline+3) = *(pDataline+3);
1047             }
1048             else
1049             {
1050               if (iBGa8 == 0xFF)       /* background fully opaque ? */
1051               {                        /* do alpha composing */
1052               int i;
1053               for (i=2; i >= 0; i--)
1054               {
1055               MNG_COMPOSE8 (*(pScanline+i), *(pDataline+i), iFGa8, *(pScanline+i));
1056               }
1057                                        /* alpha remains fully opaque !!! */
1058               }
1059               else
1060               {                        /* now blend */
1061                 MNG_BLEND8 (*pDataline, *(pDataline+1), *(pDataline+2), iFGa8,
1062                             *pScanline, *(pScanline+1), *(pScanline+2), iBGa8,
1063                             iCr8, iCg8, iCb8, iCa8);
1064                                        /* and return the composed values */
1065                 *pScanline     = iCr8;
1066                 *(pScanline+1) = iCg8;
1067                 *(pScanline+2) = iCb8;
1068                 *(pScanline+3) = iCa8;
1069               }
1070             }
1071           }
1072 
1073           pScanline += (pData->iColinc << 2);
1074           pDataline += 4;
1075         }
1076       }
1077     }
1078   }
1079 
1080   check_update_region (pData);
1081 
1082 #ifdef MNG_SUPPORT_TRACE
1083   MNG_TRACE (pData, MNG_FN_DISPLAY_RGBA8, MNG_LC_END);
1084 #endif
1085 
1086   return MNG_NOERROR;
1087 }
1088 #endif /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
1089 #else /* MNG_NO_16BIT_SUPPORT */
mng_display_rgba8(mng_datap pData)1090 mng_retcode mng_display_rgba8 (mng_datap pData)
1091 {
1092   mng_uint8p pScanline;
1093   mng_uint8p pDataline;
1094   mng_int32  iX;
1095   mng_uint8  iFGa8, iBGa8, iCa8;
1096   mng_uint8  iCr8, iCg8, iCb8;
1097 
1098 #ifdef MNG_SUPPORT_TRACE
1099   MNG_TRACE (pData, MNG_FN_DISPLAY_RGBA8, MNG_LC_START);
1100 #endif
1101                                        /* viewable row ? */
1102   if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
1103   {                                    /* address destination row */
1104     pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
1105                                                    pData->iRow + pData->iDestt -
1106                                                    pData->iSourcet);
1107                                        /* adjust destination row starting-point */
1108     pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
1109     pDataline = pData->pRGBArow;       /* address source row */
1110 
1111       pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
1112 
1113     if (pData->bIsOpaque)              /* forget about transparency ? */
1114     {
1115       {
1116         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
1117              iX += pData->iColinc)
1118         {                              /* copy the values */
1119           *pScanline     = *pDataline;
1120           *(pScanline+1) = *(pDataline+1);
1121           *(pScanline+2) = *(pDataline+2);
1122           *(pScanline+3) = *(pDataline+3);
1123 
1124           pScanline += (pData->iColinc << 2);
1125           pDataline += 4;
1126         }
1127       }
1128     }
1129     else
1130     {
1131       {
1132         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
1133              iX += pData->iColinc)
1134         {
1135           iFGa8 = *(pDataline+3);      /* get alpha values */
1136           iBGa8 = *(pScanline+3);
1137 
1138           if (iFGa8)                   /* any opacity at all ? */
1139           {                            /* fully opaque or background fully transparent ? */
1140             if ((iFGa8 == 0xFF) || (iBGa8 == 0))
1141             {                          /* then simply copy the values */
1142               *pScanline     = *pDataline;
1143               *(pScanline+1) = *(pDataline+1);
1144               *(pScanline+2) = *(pDataline+2);
1145               *(pScanline+3) = *(pDataline+3);
1146             }
1147             else
1148             {
1149               if (iBGa8 == 0xFF)       /* background fully opaque ? */
1150               {                        /* do alpha composing */
1151 #ifdef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
1152               int i;
1153               for (i=2; i >= 0; i--)
1154               {
1155               MNG_COMPOSE8 (*(pScanline+i), *(pDataline+i), iFGa8, *(pScanline+i));
1156               }
1157 #else
1158                 MNG_COMPOSE8 (*pScanline,     *pDataline,     iFGa8, *pScanline    );
1159                 MNG_COMPOSE8 (*(pScanline+1), *(pDataline+1), iFGa8, *(pScanline+1));
1160                 MNG_COMPOSE8 (*(pScanline+2), *(pDataline+2), iFGa8, *(pScanline+2));
1161 #endif
1162                                        /* alpha remains fully opaque !!! */
1163               }
1164               else
1165               {                        /* now blend */
1166                 MNG_BLEND8 (*pDataline, *(pDataline+1), *(pDataline+2), iFGa8,
1167                             *pScanline, *(pScanline+1), *(pScanline+2), iBGa8,
1168                             iCr8, iCg8, iCb8, iCa8);
1169                                        /* and return the composed values */
1170                 *pScanline     = iCr8;
1171                 *(pScanline+1) = iCg8;
1172                 *(pScanline+2) = iCb8;
1173                 *(pScanline+3) = iCa8;
1174               }
1175             }
1176           }
1177 
1178           pScanline += (pData->iColinc << 2);
1179           pDataline += 4;
1180         }
1181       }
1182     }
1183   }
1184 
1185   check_update_region (pData);
1186 
1187 #ifdef MNG_SUPPORT_TRACE
1188   MNG_TRACE (pData, MNG_FN_DISPLAY_RGBA8, MNG_LC_END);
1189 #endif
1190 
1191   return MNG_NOERROR;
1192 }
1193 #endif /* MNG_NO_16BIT_SUPPORT */
1194 #endif /* MNG_SKIPCANVAS_RGBA8 */
1195 
1196 /* ************************************************************************** */
1197 
1198 #ifndef MNG_SKIPCANVAS_RGBA8_PM
1199 #ifndef MNG_NO_16BIT_SUPPORT
1200 #ifndef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
mng_display_rgba8_pm(mng_datap pData)1201 mng_retcode mng_display_rgba8_pm (mng_datap pData)
1202 {
1203   mng_uint8p pScanline;
1204   mng_uint8p pDataline;
1205   mng_int32  iX;
1206   mng_uint32 s, t;
1207 
1208 #ifdef MNG_SUPPORT_TRACE
1209   MNG_TRACE (pData, MNG_FN_DISPLAY_RGBA8_PM, MNG_LC_START);
1210 #endif
1211                                        /* viewable row ? */
1212   if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
1213   {                                    /* address destination row */
1214     pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
1215                                                    pData->iRow + pData->iDestt -
1216                                                    pData->iSourcet);
1217                                        /* adjust destination row starting-point */
1218     pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
1219     pDataline = pData->pRGBArow;       /* address source row */
1220 
1221     if (pData->bIsRGBA16)              /* adjust source row starting-point */
1222       pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 3);
1223     else
1224       pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
1225 
1226     if (pData->bIsOpaque)              /* forget about transparency ? */
1227     {
1228       if (pData->bIsRGBA16)            /* 16-bit input row ? */
1229       {
1230         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
1231              iX += pData->iColinc)
1232         {                              /* scale down by dropping the LSB */
1233 		  if ((s = pDataline[6]) == 0)
1234 			*(mng_uint32*) pScanline = 0; /* set all components = 0 */
1235 		  else
1236 		  {
1237 			if (s == 255)
1238 			{
1239               pScanline[0] = pDataline[0];
1240               pScanline[1] = pDataline[2];
1241 		      pScanline[2] = pDataline[4];
1242               pScanline[3] = 255;
1243 			}
1244 			else
1245 			{
1246 #ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
1247               int i;
1248               for (i=2; i >= 0; i--)
1249               {
1250                 pScanline[2-i] = DIV255B8(s * pDataline[4-i-i]);
1251               }
1252 #else
1253               pScanline[0] = DIV255B8(s * pDataline[0]);
1254               pScanline[1] = DIV255B8(s * pDataline[2]);
1255               pScanline[2] = DIV255B8(s * pDataline[4]);
1256 #endif
1257               pScanline[3] = (mng_uint8)s;
1258 			}
1259 		  }
1260           pScanline += (pData->iColinc << 2);
1261           pDataline += 8;
1262         }
1263       }
1264       else
1265       {
1266         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
1267              iX += pData->iColinc)
1268         {                              /* copy the values and premultiply */
1269 		  if ((s = pDataline[3]) == 0)
1270 			*(mng_uint32*) pScanline = 0; /* set all components = 0 */
1271 		  else
1272 		  {
1273 			if (s == 255)
1274 			{
1275 #ifdef MNG_BIGENDIAN_SUPPORTED
1276               *(mng_uint32*)pScanline = (*(mng_uint32*)pDataline) | 0x000000FF;
1277 #else
1278               pScanline[0] = pDataline[0];
1279               pScanline[1] = pDataline[1];
1280 		      pScanline[2] = pDataline[2];
1281               pScanline[3] = 255;
1282 #endif
1283 			}
1284 			else
1285 			{
1286 #ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
1287               int i;
1288               for (i=2; i >= 0; i--)
1289               {
1290                 pScanline[2-i] = DIV255B8(s * pDataline[2-i]);
1291               }
1292 #else
1293               pScanline[0] = DIV255B8(s * pDataline[0]);
1294               pScanline[1] = DIV255B8(s * pDataline[1]);
1295 		      pScanline[2] = DIV255B8(s * pDataline[2]);
1296 #endif
1297               pScanline[3] = (mng_uint8)s;
1298 			}
1299 		  }
1300 
1301           pScanline += (pData->iColinc << 2);
1302           pDataline += 4;
1303         }
1304       }
1305     }
1306     else
1307     {
1308       if (pData->bIsRGBA16)            /* 16-bit input row ? */
1309       {
1310         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
1311              iX += pData->iColinc)
1312         {                              /* get alpha values */
1313           if ((s = pDataline[6]) != 0)       /* any opacity at all ? */
1314           {                            /* fully opaque or background fully transparent ? */
1315             if (s == 255)
1316             {                          /* plain copy it */
1317               pScanline[0] = pDataline[0];
1318               pScanline[1] = pDataline[2];
1319               pScanline[2] = pDataline[4];
1320               pScanline[3] = 255;
1321             }
1322             else
1323             {                          /* now blend (premultiplied) */
1324 			  t = 255 - s;
1325 #ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
1326               {
1327                 int i;
1328                 for (i=2; i >= 0; i--)
1329                 {
1330                   pScanline[2-i] = DIV255B8(s * pDataline[4-i-i] + t *
1331                      pScanline[2-i]);
1332                 }
1333               }
1334 #else
1335               pScanline[0] = DIV255B8(s * pDataline[0] + t * pScanline[0]);
1336               pScanline[1] = DIV255B8(s * pDataline[2] + t * pScanline[1]);
1337 			  pScanline[2] = DIV255B8(s * pDataline[4] + t * pScanline[2]);
1338 #endif
1339               pScanline[3] = (mng_uint8)(255 - DIV255B8(t * (255 - pScanline[3])));
1340             }
1341           }
1342 
1343           pScanline += (pData->iColinc << 2);
1344           pDataline += 8;
1345         }
1346       }
1347       else
1348       {
1349         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
1350              iX += pData->iColinc)
1351         {
1352           if ((s = pDataline[3]) != 0) /* any opacity at all ? */
1353           {                            /* fully opaque ? */
1354             if (s == 255)
1355             {                          /* then simply copy the values */
1356 #ifdef MNG_BIGENDIAN_SUPPORTED
1357               *(mng_uint32*)pScanline = (*(mng_uint32*)pDataline) | 0x000000FF;
1358 #else
1359               pScanline[0] = pDataline[0];
1360               pScanline[1] = pDataline[1];
1361               pScanline[2] = pDataline[2];
1362               pScanline[3] = 255;
1363 #endif
1364             }
1365             else
1366             {                          /* now blend (premultiplied) */
1367 			  t = 255 - s;
1368 #ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
1369               {
1370                 int i;
1371                 for (i=2; i >= 0; i--)
1372                 {
1373                   pScanline[2-i] = DIV255B8(s * pDataline[2-i] + t *
1374                      pScanline[2-i]);
1375                 }
1376               }
1377 #else
1378               pScanline[0] = DIV255B8(s * pDataline[0] + t * pScanline[0]);
1379               pScanline[1] = DIV255B8(s * pDataline[1] + t * pScanline[1]);
1380 			  pScanline[2] = DIV255B8(s * pDataline[2] + t * pScanline[2]);
1381 #endif
1382               pScanline[3] = (mng_uint8)(255 - DIV255B8(t * (255 - pScanline[3])));
1383             }
1384           }
1385 
1386           pScanline += (pData->iColinc << 2);
1387           pDataline += 4;
1388         }
1389       }
1390     }
1391   }
1392 
1393   check_update_region (pData);
1394 
1395 #ifdef MNG_SUPPORT_TRACE
1396   MNG_TRACE (pData, MNG_FN_DISPLAY_RGBA8_PM, MNG_LC_END);
1397 #endif
1398 
1399   return MNG_NOERROR;
1400 }
1401 #else /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
mng_display_rgba8_pm(mng_datap pData)1402 mng_retcode mng_display_rgba8_pm (mng_datap pData)
1403 {
1404   mng_uint8p pScanline;
1405   mng_uint8p pDataline;
1406   mng_int32  iX;
1407   mng_uint32 s, t;
1408   mng_uint8  iBps;
1409 
1410 #ifdef MNG_SUPPORT_TRACE
1411   MNG_TRACE (pData, MNG_FN_DISPLAY_RGBA8_PM, MNG_LC_START);
1412 #endif
1413 
1414   iBps=(mng_uint8)(pData->bIsRGBA16 ? 2:1);
1415                                        /* viewable row ? */
1416   if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
1417   {                                    /* address destination row */
1418     pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
1419                                                    pData->iRow + pData->iDestt -
1420                                                    pData->iSourcet);
1421                                        /* adjust destination row starting-point */
1422     pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
1423     pDataline = pData->pRGBArow;       /* address source row */
1424 
1425     /* adjust source row starting-point */
1426     pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << (iBps+1));
1427 
1428     if (pData->bIsOpaque)              /* forget about transparency ? */
1429     {
1430       if (pData->bIsRGBA16)            /* 16-bit input row ? */
1431       {
1432         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
1433              iX += pData->iColinc)
1434         {                              /* scale down by dropping the LSB */
1435 		  if ((s = pDataline[6]) == 0)
1436 			*(mng_uint32*) pScanline = 0; /* set all components = 0 */
1437 		  else
1438 		  {
1439 			if (s == 255)
1440 			{
1441               pScanline[0] = pDataline[0];
1442               pScanline[1] = pDataline[2];
1443 		      pScanline[2] = pDataline[4];
1444               pScanline[3] = 255;
1445 			}
1446 			else
1447 			{
1448 #ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
1449               int i;
1450               for (i=2; i >= 0; i--)
1451               {
1452                 pScanline[2-i] = DIV255B8(s * pDataline[4-i-i]);
1453               }
1454 #else
1455               pScanline[0] = DIV255B8(s * pDataline[0]);
1456               pScanline[1] = DIV255B8(s * pDataline[2]);
1457               pScanline[2] = DIV255B8(s * pDataline[4]);
1458 #endif
1459               pScanline[3] = (mng_uint8)s;
1460 			}
1461 		  }
1462           pScanline += (pData->iColinc << 2);
1463           pDataline += 8;
1464         }
1465       }
1466       else
1467       {
1468         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
1469              iX += pData->iColinc)
1470         {                              /* copy the values and premultiply */
1471 		  if ((s = pDataline[3]) == 0)
1472 			*(mng_uint32*) pScanline = 0; /* set all components = 0 */
1473 		  else
1474 		  {
1475 			if (s == 255)
1476 			{
1477 #ifdef MNG_BIGENDIAN_SUPPORTED
1478               *(mng_uint32*)pScanline = (*(mng_uint32*)pDataline) | 0x000000FF;
1479 #else
1480               pScanline[0] = pDataline[0];
1481               pScanline[1] = pDataline[1];
1482 		      pScanline[2] = pDataline[2];
1483               pScanline[3] = 255;
1484 #endif
1485 			}
1486 			else
1487 			{
1488 #ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
1489               int i;
1490               for (i=2; i >= 0; i--)
1491               {
1492                 pScanline[2-i] = DIV255B8(s * pDataline[2-i]);
1493               }
1494 #else
1495               pScanline[0] = DIV255B8(s * pDataline[0]);
1496               pScanline[1] = DIV255B8(s * pDataline[1]);
1497 		      pScanline[2] = DIV255B8(s * pDataline[2]);
1498 #endif
1499               pScanline[3] = (mng_uint8)s;
1500 			}
1501 		  }
1502 
1503           pScanline += (pData->iColinc << 2);
1504           pDataline += 4;
1505         }
1506       }
1507     }
1508     else
1509     {
1510       if (pData->bIsRGBA16)            /* 16-bit input row ? */
1511       {
1512         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
1513              iX += pData->iColinc)
1514         {                              /* get alpha values */
1515           if ((s = pDataline[6]) != 0)       /* any opacity at all ? */
1516           {                            /* fully opaque or background fully transparent ? */
1517             if (s == 255)
1518             {                          /* plain copy it */
1519               pScanline[0] = pDataline[0];
1520               pScanline[1] = pDataline[2];
1521               pScanline[2] = pDataline[4];
1522               pScanline[3] = 255;
1523             }
1524             else
1525             {                          /* now blend (premultiplied) */
1526 			  t = 255 - s;
1527 #ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
1528               {
1529                 int i;
1530                 for (i=2; i >= 0; i--)
1531                 {
1532                   pScanline[2-i] = DIV255B8(s * pDataline[4-i-i] + t *
1533                      pScanline[2-i]);
1534                 }
1535               }
1536 #else
1537               pScanline[0] = DIV255B8(s * pDataline[0] + t * pScanline[0]);
1538               pScanline[1] = DIV255B8(s * pDataline[2] + t * pScanline[1]);
1539 			  pScanline[2] = DIV255B8(s * pDataline[4] + t * pScanline[2]);
1540 #endif
1541               pScanline[3] = (mng_uint8)(255 - DIV255B8(t * (255 - pScanline[3])));
1542             }
1543           }
1544 
1545           pScanline += (pData->iColinc << 2);
1546           pDataline += 8;
1547         }
1548       }
1549       else
1550       {
1551         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
1552              iX += pData->iColinc)
1553         {
1554           if ((s = pDataline[3]) != 0) /* any opacity at all ? */
1555           {                            /* fully opaque ? */
1556             if (s == 255)
1557             {                          /* then simply copy the values */
1558 #ifdef MNG_BIGENDIAN_SUPPORTED
1559               *(mng_uint32*)pScanline = (*(mng_uint32*)pDataline) | 0x000000FF;
1560 #else
1561               pScanline[0] = pDataline[0];
1562               pScanline[1] = pDataline[1];
1563               pScanline[2] = pDataline[2];
1564               pScanline[3] = 255;
1565 #endif
1566             }
1567             else
1568             {                          /* now blend (premultiplied) */
1569 			  t = 255 - s;
1570 #ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
1571               {
1572                 int i;
1573                 for (i=2; i >= 0; i--)
1574                 {
1575                   pScanline[2-i] = DIV255B8(s * pDataline[2-i] + t *
1576                      pScanline[2-i]);
1577                 }
1578               }
1579 #else
1580               pScanline[0] = DIV255B8(s * pDataline[0] + t * pScanline[0]);
1581               pScanline[1] = DIV255B8(s * pDataline[1] + t * pScanline[1]);
1582 			  pScanline[2] = DIV255B8(s * pDataline[2] + t * pScanline[2]);
1583 #endif
1584               pScanline[3] = (mng_uint8)(255 - DIV255B8(t * (255 - pScanline[3])));
1585             }
1586           }
1587 
1588           pScanline += (pData->iColinc << 2);
1589           pDataline += 4;
1590         }
1591       }
1592     }
1593   }
1594 
1595   check_update_region (pData);
1596 
1597 #ifdef MNG_SUPPORT_TRACE
1598   MNG_TRACE (pData, MNG_FN_DISPLAY_RGBA8_PM, MNG_LC_END);
1599 #endif
1600 
1601   return MNG_NOERROR;
1602 }
1603 #endif /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
1604 #else /* MNG_NO_16BIT_SUPPORT */
mng_display_rgba8_pm(mng_datap pData)1605 mng_retcode mng_display_rgba8_pm (mng_datap pData)
1606 {
1607   mng_uint8p pScanline;
1608   mng_uint8p pDataline;
1609   mng_int32  iX;
1610   mng_uint32 s, t;
1611 
1612 #ifdef MNG_SUPPORT_TRACE
1613   MNG_TRACE (pData, MNG_FN_DISPLAY_RGBA8_PM, MNG_LC_START);
1614 #endif
1615                                        /* viewable row ? */
1616   if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
1617   {                                    /* address destination row */
1618     pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
1619                                                    pData->iRow + pData->iDestt -
1620                                                    pData->iSourcet);
1621                                        /* adjust destination row starting-point */
1622     pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
1623     pDataline = pData->pRGBArow;       /* address source row */
1624 
1625       pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
1626 
1627     if (pData->bIsOpaque)              /* forget about transparency ? */
1628     {
1629       {
1630         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
1631              iX += pData->iColinc)
1632         {                              /* copy the values and premultiply */
1633 		  if ((s = pDataline[3]) == 0)
1634 			*(mng_uint32*) pScanline = 0; /* set all components = 0 */
1635 		  else
1636 		  {
1637 			if (s == 255)
1638 			{
1639 #ifdef MNG_BIGENDIAN_SUPPORTED
1640               *(mng_uint32*)pScanline = (*(mng_uint32*)pDataline) | 0x000000FF;
1641 #else
1642               pScanline[0] = pDataline[0];
1643               pScanline[1] = pDataline[1];
1644 		      pScanline[2] = pDataline[2];
1645               pScanline[3] = 255;
1646 #endif
1647 			}
1648 			else
1649 			{
1650 #ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
1651               int i;
1652               for (i=2; i >= 0; i--)
1653               {
1654                 pScanline[2-i] = DIV255B8(s * pDataline[2-i]);
1655               }
1656 #else
1657               pScanline[0] = DIV255B8(s * pDataline[0]);
1658               pScanline[1] = DIV255B8(s * pDataline[1]);
1659 		      pScanline[2] = DIV255B8(s * pDataline[2]);
1660 #endif
1661               pScanline[3] = (mng_uint8)s;
1662 			}
1663 		  }
1664 
1665           pScanline += (pData->iColinc << 2);
1666           pDataline += 4;
1667         }
1668       }
1669     }
1670     else
1671     {
1672       {
1673         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
1674              iX += pData->iColinc)
1675         {
1676           if ((s = pDataline[3]) != 0) /* any opacity at all ? */
1677           {                            /* fully opaque ? */
1678             if (s == 255)
1679             {                          /* then simply copy the values */
1680 #ifdef MNG_BIGENDIAN_SUPPORTED
1681               *(mng_uint32*)pScanline = (*(mng_uint32*)pDataline) | 0x000000FF;
1682 #else
1683               pScanline[0] = pDataline[0];
1684               pScanline[1] = pDataline[1];
1685               pScanline[2] = pDataline[2];
1686               pScanline[3] = 255;
1687 #endif
1688             }
1689             else
1690             {                          /* now blend (premultiplied) */
1691 			  t = 255 - s;
1692 #ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
1693               {
1694                 int i;
1695                 for (i=2; i >= 0; i--)
1696                 {
1697                   pScanline[2-i] = DIV255B8(s * pDataline[2-i] + t *
1698                      pScanline[2-i]);
1699                 }
1700               }
1701 #else
1702               pScanline[0] = DIV255B8(s * pDataline[0] + t * pScanline[0]);
1703               pScanline[1] = DIV255B8(s * pDataline[1] + t * pScanline[1]);
1704 			  pScanline[2] = DIV255B8(s * pDataline[2] + t * pScanline[2]);
1705 #endif
1706               pScanline[3] = (mng_uint8)(255 - DIV255B8(t * (255 - pScanline[3])));
1707             }
1708           }
1709 
1710           pScanline += (pData->iColinc << 2);
1711           pDataline += 4;
1712         }
1713       }
1714     }
1715   }
1716 
1717   check_update_region (pData);
1718 
1719 #ifdef MNG_SUPPORT_TRACE
1720   MNG_TRACE (pData, MNG_FN_DISPLAY_RGBA8_PM, MNG_LC_END);
1721 #endif
1722 
1723   return MNG_NOERROR;
1724 }
1725 #endif /* MNG_NO_16BIT_SUPPORT */
1726 #endif /* MNG_SKIPCANVAS_RGBA8_PM */
1727 
1728 /* ************************************************************************** */
1729 
1730 #ifndef MNG_SKIPCANVAS_ARGB8
1731 #ifndef MNG_NO_16BIT_SUPPORT
1732 #ifndef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
mng_display_argb8(mng_datap pData)1733 mng_retcode mng_display_argb8 (mng_datap pData)
1734 {
1735   mng_uint8p pScanline;
1736   mng_uint8p pDataline;
1737   mng_int32  iX;
1738   mng_uint8  iFGa8, iBGa8, iCa8;
1739   mng_uint16 iFGa16, iBGa16, iCa16;
1740   mng_uint16 iFGr16, iFGg16, iFGb16;
1741   mng_uint16 iBGr16, iBGg16, iBGb16;
1742   mng_uint16 iCr16, iCg16, iCb16;
1743   mng_uint8  iCr8, iCg8, iCb8;
1744 
1745 #ifdef MNG_SUPPORT_TRACE
1746   MNG_TRACE (pData, MNG_FN_DISPLAY_ARGB8, MNG_LC_START);
1747 #endif
1748 
1749                                        /* viewable row ? */
1750   if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
1751   {                                    /* address destination row */
1752     pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
1753                                                    pData->iRow + pData->iDestt -
1754                                                    pData->iSourcet);
1755                                        /* adjust destination row starting-point */
1756     pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
1757     pDataline = pData->pRGBArow;       /* address source row */
1758 
1759     if (pData->bIsRGBA16)              /* adjust source row starting-point */
1760       pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 3);
1761     else
1762       pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
1763 
1764     if (pData->bIsOpaque)              /* forget about transparency ? */
1765     {
1766       if (pData->bIsRGBA16)            /* 16-bit input row ? */
1767       {
1768         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
1769              iX += pData->iColinc)
1770         {                              /* scale down by dropping the LSB */
1771           *pScanline     = *(pDataline+6);
1772           *(pScanline+1) = *pDataline;
1773           *(pScanline+2) = *(pDataline+2);
1774           *(pScanline+3) = *(pDataline+4);
1775 
1776           pScanline += (pData->iColinc << 2);
1777           pDataline += 8;
1778         }
1779       }
1780       else
1781       {
1782         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
1783              iX += pData->iColinc)
1784         {                              /* copy the values */
1785           *pScanline     = *(pDataline+3);
1786           *(pScanline+1) = *pDataline;
1787           *(pScanline+2) = *(pDataline+1);
1788           *(pScanline+3) = *(pDataline+2);
1789 
1790           pScanline += (pData->iColinc << 2);
1791           pDataline += 4;
1792         }
1793       }
1794     }
1795     else
1796     {
1797       if (pData->bIsRGBA16)            /* 16-bit input row ? */
1798       {
1799         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
1800              iX += pData->iColinc)
1801         {                              /* get alpha values */
1802           iFGa16 = mng_get_uint16 (pDataline+6);
1803           iBGa16 = (mng_uint16)(*pScanline);
1804           iBGa16 = (mng_uint16)(iBGa16 << 8) | iBGa16;
1805 
1806           if (iFGa16)                  /* any opacity at all ? */
1807           {                            /* fully opaque or background fully transparent ? */
1808             if ((iFGa16 == 0xFFFF) || (iBGa16 == 0))
1809             {                          /* plain copy it */
1810               *pScanline     = *(pDataline+6);
1811               *(pScanline+1) = *pDataline;
1812               *(pScanline+2) = *(pDataline+2);
1813               *(pScanline+3) = *(pDataline+4);
1814             }
1815             else
1816             {
1817               if (iBGa16 == 0xFFFF)    /* background fully opaque ? */
1818               {                        /* get the proper values */
1819                 iFGr16 = mng_get_uint16 (pDataline  );
1820                 iFGg16 = mng_get_uint16 (pDataline+2);
1821                 iFGb16 = mng_get_uint16 (pDataline+4);
1822                                        /* scale background up */
1823                 iBGr16 = (mng_uint16)(*(pScanline+1));
1824                 iBGg16 = (mng_uint16)(*(pScanline+2));
1825                 iBGb16 = (mng_uint16)(*(pScanline+3));
1826                 iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
1827                 iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
1828                 iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
1829                                        /* now compose */
1830                 MNG_COMPOSE16(iFGr16, iFGr16, iFGa16, iBGr16);
1831                 MNG_COMPOSE16(iFGg16, iFGg16, iFGa16, iBGg16);
1832                 MNG_COMPOSE16(iFGb16, iFGb16, iFGa16, iBGb16);
1833                                        /* and return the composed values */
1834                                        /* alpha remains fully opaque !!! */
1835                 *(pScanline+1) = (mng_uint8)(iFGr16 >> 8);
1836                 *(pScanline+2) = (mng_uint8)(iFGg16 >> 8);
1837                 *(pScanline+3) = (mng_uint8)(iFGb16 >> 8);
1838               }
1839               else
1840               {                        /* scale background up */
1841                 iBGr16 = (mng_uint16)(*(pScanline+1));
1842                 iBGg16 = (mng_uint16)(*(pScanline+2));
1843                 iBGb16 = (mng_uint16)(*(pScanline+3));
1844                 iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
1845                 iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
1846                 iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
1847                                        /* let's blend */
1848                 MNG_BLEND16 (mng_get_uint16 (pDataline  ),
1849                              mng_get_uint16 (pDataline+2),
1850                              mng_get_uint16 (pDataline+4), iFGa16,
1851                              iBGr16, iBGg16, iBGb16, iBGa16,
1852                              iCr16,  iCg16,  iCb16,  iCa16);
1853                                        /* and return the composed values */
1854                 *pScanline     = (mng_uint8)(iCa16 >> 8);
1855                 *(pScanline+1) = (mng_uint8)(iCr16 >> 8);
1856                 *(pScanline+2) = (mng_uint8)(iCg16 >> 8);
1857                 *(pScanline+3) = (mng_uint8)(iCb16 >> 8);
1858               }
1859             }
1860           }
1861 
1862           pScanline += (pData->iColinc << 2);
1863           pDataline += 8;
1864         }
1865       }
1866       else
1867       {
1868         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
1869              iX += pData->iColinc)
1870         {
1871           iFGa8 = *(pDataline+3);      /* get alpha values */
1872           iBGa8 = *pScanline;
1873 
1874           if (iFGa8)                   /* any opacity at all ? */
1875           {                            /* fully opaque or background fully transparent ? */
1876             if ((iFGa8 == 0xFF) || (iBGa8 == 0))
1877             {                          /* then simply copy the values */
1878               *pScanline     = *(pDataline+3);
1879               *(pScanline+1) = *pDataline;
1880               *(pScanline+2) = *(pDataline+1);
1881               *(pScanline+3) = *(pDataline+2);
1882             }
1883             else
1884             {
1885               if (iBGa8 == 0xFF)       /* background fully opaque ? */
1886               {                        /* do simple alpha composing */
1887                                        /* alpha itself remains fully opaque !!! */
1888               }
1889               else
1890               {                        /* now blend */
1891                 MNG_BLEND8 (*pDataline,     *(pDataline+1), *(pDataline+2), iFGa8,
1892                             *(pScanline+1), *(pScanline+2), *(pScanline+3), iBGa8,
1893                             iCr8, iCg8, iCb8, iCa8);
1894                                        /* and return the composed values */
1895                 *pScanline     = iCa8;
1896                 *(pScanline+1) = iCr8;
1897                 *(pScanline+2) = iCg8;
1898                 *(pScanline+3) = iCb8;
1899               }
1900             }
1901           }
1902 
1903           pScanline += (pData->iColinc << 2);
1904           pDataline += 4;
1905         }
1906       }
1907     }
1908   }
1909 
1910   check_update_region (pData);
1911 
1912 #ifdef MNG_SUPPORT_TRACE
1913   MNG_TRACE (pData, MNG_FN_DISPLAY_ARGB8, MNG_LC_END);
1914 #endif
1915 
1916   return MNG_NOERROR;
1917 }
1918 #else /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
mng_display_argb8(mng_datap pData)1919 mng_retcode mng_display_argb8 (mng_datap pData)
1920 {
1921   mng_uint8p pScanline;
1922   mng_uint8p pDataline;
1923   mng_int32  iX;
1924   mng_uint8  iFGa8, iBGa8, iCa8;
1925   mng_uint16 iFGa16, iBGa16, iCa16;
1926   mng_uint16 iFGg16;
1927   mng_uint16 iBGr16, iBGg16, iBGb16;
1928   mng_uint16 iCr16, iCg16, iCb16;
1929   mng_uint8  iCr8, iCg8, iCb8;
1930   mng_uint8  iBps;
1931 
1932 #ifdef MNG_SUPPORT_TRACE
1933   MNG_TRACE (pData, MNG_FN_DISPLAY_ARGB8, MNG_LC_START);
1934 #endif
1935 
1936   iBps=(mng_uint8)(pData->bIsRGBA16 ? 2:1);
1937                                        /* viewable row ? */
1938   if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
1939   {                                    /* address destination row */
1940     pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
1941                                                    pData->iRow + pData->iDestt -
1942                                                    pData->iSourcet);
1943                                        /* adjust destination row starting-point */
1944     pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
1945     pDataline = pData->pRGBArow;       /* address source row */
1946 
1947     /* adjust source row starting-point */
1948     pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << (iBps+1));
1949 
1950     if (pData->bIsOpaque)              /* forget about transparency ? */
1951     {
1952         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
1953              iX += pData->iColinc)
1954         {                              /* scale down by dropping the LSB */
1955           *pScanline     = *(pDataline+3*iBps);
1956           *(pScanline+1) = *pDataline;
1957           *(pScanline+2) = *(pDataline+iBps);
1958           *(pScanline+3) = *(pDataline+2*iBps);
1959 
1960           pScanline += (pData->iColinc << 2);
1961           pDataline += 4*iBps;
1962         }
1963     }
1964     else
1965     {
1966       if (pData->bIsRGBA16)            /* 16-bit input row ? */
1967       {
1968         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
1969              iX += pData->iColinc)
1970         {                              /* get alpha values */
1971           iFGa16 = mng_get_uint16 (pDataline+6);
1972           iBGa16 = (mng_uint16)(*pScanline);
1973           iBGa16 = (mng_uint16)(iBGa16 << 8) | iBGa16;
1974 
1975           if (iFGa16)                  /* any opacity at all ? */
1976           {                            /* fully opaque or background fully transparent ? */
1977             if ((iFGa16 == 0xFFFF) || (iBGa16 == 0))
1978             {                          /* plain copy it */
1979               *pScanline     = *(pDataline+6);
1980               *(pScanline+1) = *pDataline;
1981               *(pScanline+2) = *(pDataline+2);
1982               *(pScanline+3) = *(pDataline+4);
1983             }
1984             else
1985             {
1986               if (iBGa16 == 0xFFFF)    /* background fully opaque ? */
1987               {                        /* get the proper values */
1988               int i;
1989               for (i=2; i >= 0; i--)
1990               {
1991                 iFGg16 = mng_get_uint16 (pDataline+i+i);
1992                                        /* scale background up */
1993                 iBGg16 = (mng_uint16)(*(pScanline+i+1));
1994                 iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
1995                                        /* now compose */
1996                 MNG_COMPOSE16(iFGg16, iFGg16, iFGa16, iBGg16);
1997                                        /* and return the composed values */
1998                                        /* alpha remains fully opaque !!! */
1999                 *(pScanline+i+1) = (mng_uint8)(iFGg16 >> 8);
2000               }
2001               }
2002               else
2003               {                        /* scale background up */
2004                 iBGr16 = (mng_uint16)(*(pScanline+1));
2005                 iBGg16 = (mng_uint16)(*(pScanline+2));
2006                 iBGb16 = (mng_uint16)(*(pScanline+3));
2007                 iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
2008                 iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
2009                 iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
2010                                        /* let's blend */
2011                 MNG_BLEND16 (mng_get_uint16 (pDataline  ),
2012                              mng_get_uint16 (pDataline+2),
2013                              mng_get_uint16 (pDataline+4), iFGa16,
2014                              iBGr16, iBGg16, iBGb16, iBGa16,
2015                              iCr16,  iCg16,  iCb16,  iCa16);
2016                                        /* and return the composed values */
2017                 *pScanline     = (mng_uint8)(iCa16 >> 8);
2018                 *(pScanline+1) = (mng_uint8)(iCr16 >> 8);
2019                 *(pScanline+2) = (mng_uint8)(iCg16 >> 8);
2020                 *(pScanline+3) = (mng_uint8)(iCb16 >> 8);
2021               }
2022             }
2023           }
2024 
2025           pScanline += (pData->iColinc << 2);
2026           pDataline += 8;
2027         }
2028       }
2029       else
2030       {
2031         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
2032              iX += pData->iColinc)
2033         {
2034           iFGa8 = *(pDataline+3);      /* get alpha values */
2035           iBGa8 = *pScanline;
2036 
2037           if (iFGa8)                   /* any opacity at all ? */
2038           {                            /* fully opaque or background fully transparent ? */
2039             if ((iFGa8 == 0xFF) || (iBGa8 == 0))
2040             {                          /* then simply copy the values */
2041               *pScanline     = *(pDataline+3);
2042               *(pScanline+1) = *pDataline;
2043               *(pScanline+2) = *(pDataline+1);
2044               *(pScanline+3) = *(pDataline+2);
2045             }
2046             else
2047             {
2048               if (iBGa8 == 0xFF)       /* background fully opaque ? */
2049               {                        /* do simple alpha composing */
2050                                        /* alpha itself remains fully opaque !!! */
2051               int i;
2052               for (i=2; i >= 0; i--)
2053               {
2054               MNG_COMPOSE8 (*(pScanline+i+1), *(pDataline+i), iFGa8, *(pScanline+i+1));
2055               }
2056               }
2057               else
2058               {                        /* now blend */
2059                 MNG_BLEND8 (*pDataline,     *(pDataline+1), *(pDataline+2), iFGa8,
2060                             *(pScanline+1), *(pScanline+2), *(pScanline+3), iBGa8,
2061                             iCr8, iCg8, iCb8, iCa8);
2062                                        /* and return the composed values */
2063                 *pScanline     = iCa8;
2064                 *(pScanline+1) = iCr8;
2065                 *(pScanline+2) = iCg8;
2066                 *(pScanline+3) = iCb8;
2067               }
2068             }
2069           }
2070 
2071           pScanline += (pData->iColinc << 2);
2072           pDataline += 4;
2073         }
2074       }
2075     }
2076   }
2077 
2078   check_update_region (pData);
2079 
2080 #ifdef MNG_SUPPORT_TRACE
2081   MNG_TRACE (pData, MNG_FN_DISPLAY_ARGB8, MNG_LC_END);
2082 #endif
2083 
2084   return MNG_NOERROR;
2085 }
2086 #endif /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
2087 #else /* MNG_NO_16BIT_SUPPORT */
mng_display_argb8(mng_datap pData)2088 mng_retcode mng_display_argb8 (mng_datap pData)
2089 {
2090   mng_uint8p pScanline;
2091   mng_uint8p pDataline;
2092   mng_int32  iX;
2093   mng_uint8  iFGa8, iBGa8, iCa8;
2094   mng_uint8  iCr8, iCg8, iCb8;
2095 
2096 #ifdef MNG_SUPPORT_TRACE
2097   MNG_TRACE (pData, MNG_FN_DISPLAY_ARGB8, MNG_LC_START);
2098 #endif
2099 
2100                                        /* viewable row ? */
2101   if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
2102   {                                    /* address destination row */
2103     pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
2104                                                    pData->iRow + pData->iDestt -
2105                                                    pData->iSourcet);
2106                                        /* adjust destination row starting-point */
2107     pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
2108     pDataline = pData->pRGBArow;       /* address source row */
2109 
2110       pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
2111 
2112     if (pData->bIsOpaque)              /* forget about transparency ? */
2113     {
2114       {
2115         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
2116              iX += pData->iColinc)
2117         {                              /* copy the values */
2118           *pScanline     = *(pDataline+3);
2119           *(pScanline+1) = *pDataline;
2120           *(pScanline+2) = *(pDataline+1);
2121           *(pScanline+3) = *(pDataline+2);
2122 
2123           pScanline += (pData->iColinc << 2);
2124           pDataline += 4;
2125         }
2126       }
2127     }
2128     else
2129     {
2130       {
2131         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
2132              iX += pData->iColinc)
2133         {
2134           iFGa8 = *(pDataline+3);      /* get alpha values */
2135           iBGa8 = *pScanline;
2136 
2137           if (iFGa8)                   /* any opacity at all ? */
2138           {                            /* fully opaque or background fully transparent ? */
2139             if ((iFGa8 == 0xFF) || (iBGa8 == 0))
2140             {                          /* then simply copy the values */
2141               *pScanline     = *(pDataline+3);
2142               *(pScanline+1) = *pDataline;
2143               *(pScanline+2) = *(pDataline+1);
2144               *(pScanline+3) = *(pDataline+2);
2145             }
2146             else
2147             {
2148               if (iBGa8 == 0xFF)       /* background fully opaque ? */
2149               {                        /* do simple alpha composing */
2150                                        /* alpha itself remains fully opaque !!! */
2151 #ifdef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
2152               int i;
2153               for (i=2; i >= 0; i--)
2154               {
2155               MNG_COMPOSE8 (*(pScanline+i+1), *(pDataline+i), iFGa8, *(pScanline+i+1));
2156               }
2157 #else
2158                 MNG_COMPOSE8 (*(pScanline+1), *pDataline,     iFGa8, *(pScanline+1));
2159                 MNG_COMPOSE8 (*(pScanline+2), *(pDataline+1), iFGa8, *(pScanline+2));
2160                 MNG_COMPOSE8 (*(pScanline+3), *(pDataline+2), iFGa8, *(pScanline+3));
2161 #endif
2162               }
2163               else
2164               {                        /* now blend */
2165                 MNG_BLEND8 (*pDataline,     *(pDataline+1), *(pDataline+2), iFGa8,
2166                             *(pScanline+1), *(pScanline+2), *(pScanline+3), iBGa8,
2167                             iCr8, iCg8, iCb8, iCa8);
2168                                        /* and return the composed values */
2169                 *pScanline     = iCa8;
2170                 *(pScanline+1) = iCr8;
2171                 *(pScanline+2) = iCg8;
2172                 *(pScanline+3) = iCb8;
2173               }
2174             }
2175           }
2176 
2177           pScanline += (pData->iColinc << 2);
2178           pDataline += 4;
2179         }
2180       }
2181     }
2182   }
2183 
2184   check_update_region (pData);
2185 
2186 #ifdef MNG_SUPPORT_TRACE
2187   MNG_TRACE (pData, MNG_FN_DISPLAY_ARGB8, MNG_LC_END);
2188 #endif
2189 
2190   return MNG_NOERROR;
2191 }
2192 #endif /* MNG_NO_16BIT_SUPPORT */
2193 #endif /* MNG_SKIPCANVAS_ARGB8 */
2194 
2195 /* ************************************************************************** */
2196 
2197 #ifndef MNG_SKIPCANVAS_ARGB8_PM
2198 #ifndef MNG_NO_16BIT_SUPPORT
2199 #ifndef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
mng_display_argb8_pm(mng_datap pData)2200 mng_retcode mng_display_argb8_pm (mng_datap pData)
2201 {
2202   mng_uint8p pScanline;
2203   mng_uint8p pDataline;
2204   mng_int32  iX;
2205   mng_uint32 s, t;
2206 
2207 #ifdef MNG_SUPPORT_TRACE
2208   MNG_TRACE (pData, MNG_FN_DISPLAY_ARGB8_PM, MNG_LC_START);
2209 #endif
2210                                        /* viewable row ? */
2211   if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
2212   {                                    /* address destination row */
2213     pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
2214                                                    pData->iRow + pData->iDestt -
2215                                                    pData->iSourcet);
2216                                        /* adjust destination row starting-point */
2217     pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
2218     pDataline = pData->pRGBArow;       /* address source row */
2219 
2220     if (pData->bIsRGBA16)              /* adjust source row starting-point */
2221       pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 3);
2222     else
2223       pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
2224 
2225     if (pData->bIsOpaque)              /* forget about transparency ? */
2226     {
2227       if (pData->bIsRGBA16)            /* 16-bit input row ? */
2228       {
2229         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
2230              iX += pData->iColinc)
2231         {                              /* scale down by dropping the LSB */
2232 		  if ((s = pDataline[6]) == 0)
2233 			*(mng_uint32*) pScanline = 0; /* set all components = 0 */
2234 		  else
2235 		  {
2236 			if (s == 255)
2237 			{
2238               pScanline[0] = 255;
2239               pScanline[1] = pDataline[0];
2240               pScanline[2] = pDataline[2];
2241 		      pScanline[3] = pDataline[4];
2242 			}
2243 			else
2244 			{
2245               pScanline[0] = (mng_uint8)s;
2246 #ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
2247               {
2248                 int i;
2249                 for (i=2; i >= 0; i--)
2250                 {
2251                   pScanline[3-i] = DIV255B8(s * pDataline[4-i-i]);
2252                 }
2253               }
2254 #else
2255               pScanline[1] = DIV255B8(s * pDataline[0]);
2256               pScanline[2] = DIV255B8(s * pDataline[2]);
2257               pScanline[3] = DIV255B8(s * pDataline[4]);
2258 #endif
2259 			}
2260 		  }
2261           pScanline += (pData->iColinc << 2);
2262           pDataline += 8;
2263         }
2264       }
2265       else
2266       {
2267         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
2268              iX += pData->iColinc)
2269         {                              /* copy the values and premultiply */
2270 		  if ((s = pDataline[3]) == 0)
2271 			*(mng_uint32*) pScanline = 0; /* set all components = 0 */
2272 		  else
2273 		  {
2274 			if (s == 255)
2275 			{
2276               pScanline[0] = 255;
2277               pScanline[1] = pDataline[0];
2278               pScanline[2] = pDataline[1];
2279 		      pScanline[3] = pDataline[2];
2280 			}
2281 			else
2282 			{
2283               pScanline[0] = (mng_uint8)s;
2284 #ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
2285               {
2286                 int i;
2287                 for (i=2; i >= 0; i--)
2288                 {
2289                   pScanline[3-i] = DIV255B8(s * pDataline[2-i]);
2290                 }
2291               }
2292 #else
2293               pScanline[1] = DIV255B8(s * pDataline[0]);
2294               pScanline[2] = DIV255B8(s * pDataline[1]);
2295 		      pScanline[3] = DIV255B8(s * pDataline[2]);
2296 #endif
2297 			}
2298 		  }
2299 
2300           pScanline += (pData->iColinc << 2);
2301           pDataline += 4;
2302         }
2303       }
2304     }
2305     else
2306     {
2307       if (pData->bIsRGBA16)            /* 16-bit input row ? */
2308       {
2309         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
2310              iX += pData->iColinc)
2311         {                              /* get alpha values */
2312           if ((s = pDataline[6]) != 0)       /* any opacity at all ? */
2313           {                            /* fully opaque or background fully transparent ? */
2314             if (s == 255)
2315             {                          /* plain copy it */
2316               pScanline[0] = 255;
2317               pScanline[1] = pDataline[0];
2318               pScanline[2] = pDataline[2];
2319               pScanline[3] = pDataline[4];
2320             }
2321             else
2322             {                          /* now blend (premultiplied) */
2323 			  t = 255 - s;
2324               pScanline[0] = (mng_uint8)(255 - DIV255B8(t * (255 - pScanline[0])));
2325 #ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
2326               {
2327                 int i;
2328                 for (i=2; i >= 0; i--)
2329                 {
2330                   pScanline[3-i] = DIV255B8(s * pDataline[4-i-i] + t *
2331                      pScanline[3-i]);
2332                 }
2333               }
2334 #else
2335               pScanline[1] = DIV255B8(s * pDataline[0] + t * pScanline[1]);
2336               pScanline[2] = DIV255B8(s * pDataline[2] + t * pScanline[2]);
2337 			  pScanline[3] = DIV255B8(s * pDataline[4] + t * pScanline[3]);
2338 #endif
2339             }
2340           }
2341 
2342           pScanline += (pData->iColinc << 2);
2343           pDataline += 8;
2344         }
2345       }
2346       else
2347       {
2348         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
2349              iX += pData->iColinc)
2350         {
2351           if ((s = pDataline[3]) != 0)       /* any opacity at all ? */
2352           {                            /* fully opaque ? */
2353             if (s == 255)
2354             {                          /* then simply copy the values */
2355               pScanline[0] = 255;
2356               pScanline[1] = pDataline[0];
2357               pScanline[2] = pDataline[1];
2358               pScanline[3] = pDataline[2];
2359             }
2360             else
2361             {                          /* now blend (premultiplied) */
2362 			  t = 255 - s;
2363               pScanline[0] = (mng_uint8)(255 - DIV255B8(t * (255 - pScanline[0])));
2364 #ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
2365               {
2366                 int i;
2367                 for (i=2; i >= 0; i--)
2368                 {
2369                   pScanline[3-i] = DIV255B8(s * pDataline[2-i] + t *
2370                      pScanline[3-i]);
2371                 }
2372               }
2373 #else
2374               pScanline[1] = DIV255B8(s * pDataline[0] + t * pScanline[1]);
2375               pScanline[2] = DIV255B8(s * pDataline[1] + t * pScanline[2]);
2376 			  pScanline[3] = DIV255B8(s * pDataline[2] + t * pScanline[3]);
2377 #endif
2378             }
2379           }
2380 
2381           pScanline += (pData->iColinc << 2);
2382           pDataline += 4;
2383         }
2384       }
2385     }
2386   }
2387 
2388   check_update_region (pData);
2389 
2390 #ifdef MNG_SUPPORT_TRACE
2391   MNG_TRACE (pData, MNG_FN_DISPLAY_ARGB8_PM, MNG_LC_END);
2392 #endif
2393 
2394   return MNG_NOERROR;
2395 }
2396 #else /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
mng_display_argb8_pm(mng_datap pData)2397 mng_retcode mng_display_argb8_pm (mng_datap pData)
2398 {
2399   mng_uint8p pScanline;
2400   mng_uint8p pDataline;
2401   mng_int32  iX;
2402   mng_uint32 s, t;
2403   mng_uint8  iBps;
2404 
2405 #ifdef MNG_SUPPORT_TRACE
2406   MNG_TRACE (pData, MNG_FN_DISPLAY_ARGB8_PM, MNG_LC_START);
2407 #endif
2408 
2409   iBps=(mng_uint8)(pData->bIsRGBA16 ? 2:1);
2410                                        /* viewable row ? */
2411   if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
2412   {                                    /* address destination row */
2413     pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
2414                                                    pData->iRow + pData->iDestt -
2415                                                    pData->iSourcet);
2416                                        /* adjust destination row starting-point */
2417     pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
2418     pDataline = pData->pRGBArow;       /* address source row */
2419 
2420     /* adjust source row starting-point */
2421     pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << (iBps+1));
2422 
2423     if (pData->bIsOpaque)              /* forget about transparency ? */
2424     {
2425       if (pData->bIsRGBA16)            /* 16-bit input row ? */
2426       {
2427         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
2428              iX += pData->iColinc)
2429         {                              /* scale down by dropping the LSB */
2430 		  if ((s = pDataline[6]) == 0)
2431 			*(mng_uint32*) pScanline = 0; /* set all components = 0 */
2432 		  else
2433 		  {
2434 			if (s == 255)
2435 			{
2436               pScanline[0] = 255;
2437               pScanline[1] = pDataline[0];
2438               pScanline[2] = pDataline[2];
2439 		      pScanline[3] = pDataline[4];
2440 			}
2441 			else
2442 			{
2443               pScanline[0] = (mng_uint8)s;
2444 #ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
2445               {
2446                 int i;
2447                 for (i=2; i >= 0; i--)
2448                 {
2449                   pScanline[3-i] = DIV255B8(s * pDataline[4-i-i]);
2450                 }
2451               }
2452 #else
2453               pScanline[1] = DIV255B8(s * pDataline[0]);
2454               pScanline[2] = DIV255B8(s * pDataline[2]);
2455               pScanline[3] = DIV255B8(s * pDataline[4]);
2456 #endif
2457 			}
2458 		  }
2459           pScanline += (pData->iColinc << 2);
2460           pDataline += 8;
2461         }
2462       }
2463       else
2464       {
2465         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
2466              iX += pData->iColinc)
2467         {                              /* copy the values and premultiply */
2468 		  if ((s = pDataline[3]) == 0)
2469 			*(mng_uint32*) pScanline = 0; /* set all components = 0 */
2470 		  else
2471 		  {
2472 			if (s == 255)
2473 			{
2474               pScanline[0] = 255;
2475               pScanline[1] = pDataline[0];
2476               pScanline[2] = pDataline[1];
2477 		      pScanline[3] = pDataline[2];
2478 			}
2479 			else
2480 			{
2481               pScanline[0] = (mng_uint8)s;
2482 #ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
2483               {
2484                 int i;
2485                 for (i=2; i >= 0; i--)
2486                 {
2487                   pScanline[3-i] = DIV255B8(s * pDataline[2-i]);
2488                 }
2489               }
2490 #else
2491               pScanline[1] = DIV255B8(s * pDataline[0]);
2492               pScanline[2] = DIV255B8(s * pDataline[1]);
2493 		      pScanline[3] = DIV255B8(s * pDataline[2]);
2494 #endif
2495 			}
2496 		  }
2497 
2498           pScanline += (pData->iColinc << 2);
2499           pDataline += 4;
2500         }
2501       }
2502     }
2503     else
2504     {
2505       if (pData->bIsRGBA16)            /* 16-bit input row ? */
2506       {
2507         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
2508              iX += pData->iColinc)
2509         {                              /* get alpha values */
2510           if ((s = pDataline[6]) != 0)       /* any opacity at all ? */
2511           {                            /* fully opaque or background fully transparent ? */
2512             if (s == 255)
2513             {                          /* plain copy it */
2514               pScanline[0] = 255;
2515               pScanline[1] = pDataline[0];
2516               pScanline[2] = pDataline[2];
2517               pScanline[3] = pDataline[4];
2518             }
2519             else
2520             {                          /* now blend (premultiplied) */
2521 			  t = 255 - s;
2522               pScanline[0] = (mng_uint8)(255 - DIV255B8(t * (255 - pScanline[0])));
2523 #ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
2524               {
2525                 int i;
2526                 for (i=2; i >= 0; i--)
2527                 {
2528                   pScanline[3-i] = DIV255B8(s * pDataline[4-i-i] + t *
2529                      pScanline[3-i]);
2530                 }
2531               }
2532 #else
2533               pScanline[1] = DIV255B8(s * pDataline[0] + t * pScanline[1]);
2534               pScanline[2] = DIV255B8(s * pDataline[2] + t * pScanline[2]);
2535 			  pScanline[3] = DIV255B8(s * pDataline[4] + t * pScanline[3]);
2536 #endif
2537             }
2538           }
2539 
2540           pScanline += (pData->iColinc << 2);
2541           pDataline += 8;
2542         }
2543       }
2544       else
2545       {
2546         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
2547              iX += pData->iColinc)
2548         {
2549           if ((s = pDataline[3]) != 0)       /* any opacity at all ? */
2550           {                            /* fully opaque ? */
2551             if (s == 255)
2552             {                          /* then simply copy the values */
2553               pScanline[0] = 255;
2554               pScanline[1] = pDataline[0];
2555               pScanline[2] = pDataline[1];
2556               pScanline[3] = pDataline[2];
2557             }
2558             else
2559             {                          /* now blend (premultiplied) */
2560 			  t = 255 - s;
2561               pScanline[0] = (mng_uint8)(255 - DIV255B8(t * (255 - pScanline[0])));
2562 #ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
2563               {
2564                 int i;
2565                 for (i=2; i >= 0; i--)
2566                 {
2567                   pScanline[3-i] = DIV255B8(s * pDataline[2-i] + t *
2568                      pScanline[3-i]);
2569                 }
2570               }
2571 #else
2572               pScanline[1] = DIV255B8(s * pDataline[0] + t * pScanline[1]);
2573               pScanline[2] = DIV255B8(s * pDataline[1] + t * pScanline[2]);
2574 			  pScanline[3] = DIV255B8(s * pDataline[2] + t * pScanline[3]);
2575 #endif
2576             }
2577           }
2578 
2579           pScanline += (pData->iColinc << 2);
2580           pDataline += 4;
2581         }
2582       }
2583     }
2584   }
2585 
2586   check_update_region (pData);
2587 
2588 #ifdef MNG_SUPPORT_TRACE
2589   MNG_TRACE (pData, MNG_FN_DISPLAY_ARGB8_PM, MNG_LC_END);
2590 #endif
2591 
2592   return MNG_NOERROR;
2593 }
2594 #endif /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
2595 #else /* MNG_NO_16BIT_SUPPORT */
mng_display_argb8_pm(mng_datap pData)2596 mng_retcode mng_display_argb8_pm (mng_datap pData)
2597 {
2598   mng_uint8p pScanline;
2599   mng_uint8p pDataline;
2600   mng_int32  iX;
2601   mng_uint32 s, t;
2602 
2603 #ifdef MNG_SUPPORT_TRACE
2604   MNG_TRACE (pData, MNG_FN_DISPLAY_ARGB8_PM, MNG_LC_START);
2605 #endif
2606                                        /* viewable row ? */
2607   if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
2608   {                                    /* address destination row */
2609     pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
2610                                                    pData->iRow + pData->iDestt -
2611                                                    pData->iSourcet);
2612                                        /* adjust destination row starting-point */
2613     pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
2614     pDataline = pData->pRGBArow;       /* address source row */
2615 
2616       pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
2617 
2618     if (pData->bIsOpaque)              /* forget about transparency ? */
2619     {
2620       {
2621         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
2622              iX += pData->iColinc)
2623         {                              /* copy the values and premultiply */
2624 		  if ((s = pDataline[3]) == 0)
2625 			*(mng_uint32*) pScanline = 0; /* set all components = 0 */
2626 		  else
2627 		  {
2628 			if (s == 255)
2629 			{
2630               pScanline[0] = 255;
2631               pScanline[1] = pDataline[0];
2632               pScanline[2] = pDataline[1];
2633 		      pScanline[3] = pDataline[2];
2634 			}
2635 			else
2636 			{
2637               pScanline[0] = (mng_uint8)s;
2638 #ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
2639               {
2640                 int i;
2641                 for (i=2; i >= 0; i--)
2642                 {
2643                   pScanline[3-i] = DIV255B8(s * pDataline[2-i]);
2644                 }
2645               }
2646 #else
2647               pScanline[1] = DIV255B8(s * pDataline[0]);
2648               pScanline[2] = DIV255B8(s * pDataline[1]);
2649 		      pScanline[3] = DIV255B8(s * pDataline[2]);
2650 #endif
2651 			}
2652 		  }
2653 
2654           pScanline += (pData->iColinc << 2);
2655           pDataline += 4;
2656         }
2657       }
2658     }
2659     else
2660     {
2661       {
2662         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
2663              iX += pData->iColinc)
2664         {
2665           if ((s = pDataline[3]) != 0)       /* any opacity at all ? */
2666           {                            /* fully opaque ? */
2667             if (s == 255)
2668             {                          /* then simply copy the values */
2669               pScanline[0] = 255;
2670               pScanline[1] = pDataline[0];
2671               pScanline[2] = pDataline[1];
2672               pScanline[3] = pDataline[2];
2673             }
2674             else
2675             {                          /* now blend (premultiplied) */
2676 			  t = 255 - s;
2677               pScanline[0] = (mng_uint8)(255 - DIV255B8(t * (255 - pScanline[0])));
2678 #ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
2679               {
2680                 int i;
2681                 for (i=2; i >= 0; i--)
2682                 {
2683                   pScanline[3-i] = DIV255B8(s * pDataline[2-i] + t *
2684                      pScanline[3-i]);
2685                 }
2686               }
2687 #else
2688               pScanline[1] = DIV255B8(s * pDataline[0] + t * pScanline[1]);
2689               pScanline[2] = DIV255B8(s * pDataline[1] + t * pScanline[2]);
2690 			  pScanline[3] = DIV255B8(s * pDataline[2] + t * pScanline[3]);
2691 #endif
2692             }
2693           }
2694 
2695           pScanline += (pData->iColinc << 2);
2696           pDataline += 4;
2697         }
2698       }
2699     }
2700   }
2701 
2702   check_update_region (pData);
2703 
2704 #ifdef MNG_SUPPORT_TRACE
2705   MNG_TRACE (pData, MNG_FN_DISPLAY_ARGB8_PM, MNG_LC_END);
2706 #endif
2707 
2708   return MNG_NOERROR;
2709 }
2710 #endif /* MNG_NO_16BIT_SUPPORT */
2711 #endif /* MNG_SKIPCANVAS_ARGB8_PM */
2712 
2713 /* ************************************************************************** */
2714 
2715 #ifndef MNG_SKIPCANVAS_RGB8_A8
2716 #ifndef MNG_NO_16BIT_SUPPORT
2717 #ifndef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
mng_display_rgb8_a8(mng_datap pData)2718 mng_retcode mng_display_rgb8_a8 (mng_datap pData)
2719 {
2720   mng_uint8p pScanline;
2721   mng_uint8p pAlphaline;
2722   mng_uint8p pDataline;
2723   mng_int32  iX;
2724   mng_uint8  iFGa8, iBGa8, iCa8;
2725   mng_uint16 iFGa16, iBGa16, iCa16;
2726   mng_uint16 iFGr16, iFGg16, iFGb16;
2727   mng_uint16 iBGr16, iBGg16, iBGb16;
2728   mng_uint16 iCr16, iCg16, iCb16;
2729   mng_uint8  iCr8, iCg8, iCb8;
2730 
2731 #ifdef MNG_SUPPORT_TRACE
2732   MNG_TRACE (pData, MNG_FN_DISPLAY_RGB8_A8, MNG_LC_START);
2733 #endif
2734                                        /* viewable row ? */
2735   if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
2736   {                                    /* address destination rows */
2737     pScanline  = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
2738                                                     pData->iRow + pData->iDestt -
2739                                                     pData->iSourcet);
2740     pAlphaline = (mng_uint8p)pData->fGetalphaline  (((mng_handle)pData),
2741                                                     pData->iRow + pData->iDestt -
2742                                                     pData->iSourcet);
2743                                        /* adjust destination rows starting-point */
2744     pScanline  = pScanline  + (pData->iCol * 3) + (pData->iDestl * 3);
2745     pAlphaline = pAlphaline + pData->iCol + pData->iDestl;
2746 
2747     pDataline  = pData->pRGBArow;      /* address source row */
2748 
2749     if (pData->bIsRGBA16)              /* adjust source row starting-point */
2750       pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 3);
2751     else
2752       pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
2753 
2754     if (pData->bIsOpaque)              /* forget about transparency ? */
2755     {
2756       if (pData->bIsRGBA16)            /* 16-bit input row ? */
2757       {
2758         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
2759              iX += pData->iColinc)
2760         {                              /* scale down by dropping the LSB */
2761           *pScanline     = *pDataline;
2762           *(pScanline+1) = *(pDataline+2);
2763           *(pScanline+2) = *(pDataline+4);
2764           *pAlphaline    = *(pDataline+6);
2765 
2766           pScanline  += (pData->iColinc * 3);
2767           pAlphaline += pData->iColinc;
2768           pDataline  += 8;
2769         }
2770       }
2771       else
2772       {
2773         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
2774              iX += pData->iColinc)
2775         {                              /* copy the values */
2776           *pScanline     = *pDataline;
2777           *(pScanline+1) = *(pDataline+1);
2778           *(pScanline+2) = *(pDataline+2);
2779           *pAlphaline    = *(pDataline+3);
2780 
2781           pScanline  += (pData->iColinc * 3);
2782           pAlphaline += pData->iColinc;
2783           pDataline  += 4;
2784         }
2785       }
2786     }
2787     else
2788     {
2789       if (pData->bIsRGBA16)            /* 16-bit input row ? */
2790       {
2791         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
2792              iX += pData->iColinc)
2793         {                              /* get alpha values */
2794           iFGa16 = mng_get_uint16 (pDataline+6);
2795           iBGa16 = (mng_uint16)(*pAlphaline);
2796           iBGa16 = (mng_uint16)(iBGa16 << 8) | iBGa16;
2797 
2798           if (iFGa16)                  /* any opacity at all ? */
2799           {                            /* fully opaque or background fully transparent ? */
2800             if ((iFGa16 == 0xFFFF) || (iBGa16 == 0))
2801             {                          /* plain copy it */
2802               *pScanline     = *pDataline;
2803               *(pScanline+1) = *(pDataline+2);
2804               *(pScanline+2) = *(pDataline+4);
2805               *pAlphaline    = *(pDataline+6);
2806             }
2807             else
2808             {
2809               if (iBGa16 == 0xFFFF)    /* background fully opaque ? */
2810               {                        /* get the proper values */
2811                 iFGr16 = mng_get_uint16 (pDataline  );
2812                 iFGg16 = mng_get_uint16 (pDataline+2);
2813                 iFGb16 = mng_get_uint16 (pDataline+4);
2814                                        /* scale background up */
2815                 iBGr16 = (mng_uint16)(*pScanline    );
2816                 iBGg16 = (mng_uint16)(*(pScanline+1));
2817                 iBGb16 = (mng_uint16)(*(pScanline+2));
2818                 iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
2819                 iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
2820                 iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
2821                                        /* now compose */
2822                 MNG_COMPOSE16(iFGr16, iFGr16, iFGa16, iBGr16);
2823                 MNG_COMPOSE16(iFGg16, iFGg16, iFGa16, iBGg16);
2824                 MNG_COMPOSE16(iFGb16, iFGb16, iFGa16, iBGb16);
2825                                        /* and return the composed values */
2826                 *pScanline     = (mng_uint8)(iFGr16 >> 8);
2827                 *(pScanline+1) = (mng_uint8)(iFGg16 >> 8);
2828                 *(pScanline+2) = (mng_uint8)(iFGb16 >> 8);
2829                                        /* alpha remains fully opaque !!! */
2830               }
2831               else
2832               {                        /* scale background up */
2833                 iBGr16 = (mng_uint16)(*pScanline    );
2834                 iBGg16 = (mng_uint16)(*(pScanline+1));
2835                 iBGb16 = (mng_uint16)(*(pScanline+2));
2836                 iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
2837                 iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
2838                 iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
2839                                        /* let's blend */
2840                 MNG_BLEND16 (mng_get_uint16 (pDataline  ),
2841                              mng_get_uint16 (pDataline+2),
2842                              mng_get_uint16 (pDataline+4), iFGa16,
2843                              iBGr16, iBGg16, iBGb16, iBGa16,
2844                              iCr16,  iCg16,  iCb16,  iCa16);
2845                                        /* and return the composed values */
2846                 *pScanline     = (mng_uint8)(iCr16 >> 8);
2847                 *(pScanline+1) = (mng_uint8)(iCg16 >> 8);
2848                 *(pScanline+2) = (mng_uint8)(iCb16 >> 8);
2849                 *pAlphaline    = (mng_uint8)(iCa16 >> 8);
2850               }
2851             }
2852           }
2853 
2854           pScanline  += (pData->iColinc * 3);
2855           pAlphaline += pData->iColinc;
2856           pDataline  += 8;
2857         }
2858       }
2859       else
2860       {
2861         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
2862              iX += pData->iColinc)
2863         {
2864           iFGa8 = *(pDataline+3);      /* get alpha values */
2865           iBGa8 = *pAlphaline;
2866 
2867           if (iFGa8)                   /* any opacity at all ? */
2868           {                            /* fully opaque or background fully transparent ? */
2869             if ((iFGa8 == 0xFF) || (iBGa8 == 0))
2870             {                          /* then simply copy the values */
2871               *pScanline     = *pDataline;
2872               *(pScanline+1) = *(pDataline+1);
2873               *(pScanline+2) = *(pDataline+2);
2874               *pAlphaline    = *(pDataline+3);
2875             }
2876             else
2877             {
2878               if (iBGa8 == 0xFF)       /* background fully opaque ? */
2879               {                        /* do alpha composing */
2880                 MNG_COMPOSE8 (*pScanline,     *pDataline,     iFGa8, *pScanline    );
2881                 MNG_COMPOSE8 (*(pScanline+1), *(pDataline+1), iFGa8, *(pScanline+1));
2882                 MNG_COMPOSE8 (*(pScanline+2), *(pDataline+2), iFGa8, *(pScanline+2));
2883                                        /* alpha remains fully opaque !!! */
2884               }
2885               else
2886               {                        /* now blend */
2887                 MNG_BLEND8 (*pDataline, *(pDataline+1), *(pDataline+2), iFGa8,
2888                             *pScanline, *(pScanline+1), *(pScanline+2), iBGa8,
2889                             iCr8, iCg8, iCb8, iCa8);
2890                                        /* and return the composed values */
2891                 *pScanline     = iCr8;
2892                 *(pScanline+1) = iCg8;
2893                 *(pScanline+2) = iCb8;
2894                 *pAlphaline    = iCa8;
2895               }
2896             }
2897           }
2898 
2899           pScanline  += (pData->iColinc * 3);
2900           pAlphaline += pData->iColinc;
2901           pDataline  += 4;
2902         }
2903       }
2904     }
2905   }
2906 
2907   check_update_region (pData);
2908 
2909 #ifdef MNG_SUPPORT_TRACE
2910   MNG_TRACE (pData, MNG_FN_DISPLAY_RGB8_A8, MNG_LC_END);
2911 #endif
2912 
2913   return MNG_NOERROR;
2914 }
2915 #else /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
mng_display_rgb8_a8(mng_datap pData)2916 mng_retcode mng_display_rgb8_a8 (mng_datap pData)
2917 {
2918   mng_uint8p pScanline;
2919   mng_uint8p pAlphaline;
2920   mng_uint8p pDataline;
2921   mng_int32  iX;
2922   mng_uint8  iFGa8, iBGa8, iCa8;
2923   mng_uint16 iFGa16, iBGa16, iCa16;
2924   mng_uint16 iFGg16;
2925   mng_uint16 iBGr16, iBGg16, iBGb16;
2926   mng_uint16 iCr16, iCg16, iCb16;
2927   mng_uint8  iCr8, iCg8, iCb8;
2928   mng_uint8  iBps;
2929 
2930 #ifdef MNG_SUPPORT_TRACE
2931   MNG_TRACE (pData, MNG_FN_DISPLAY_RGB8_A8, MNG_LC_START);
2932 #endif
2933 
2934   iBps=(mng_uint8)(pData->bIsRGBA16 ? 2:1);
2935                                        /* viewable row ? */
2936   if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
2937   {                                    /* address destination rows */
2938     pScanline  = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
2939                                                     pData->iRow + pData->iDestt -
2940                                                     pData->iSourcet);
2941     pAlphaline = (mng_uint8p)pData->fGetalphaline  (((mng_handle)pData),
2942                                                     pData->iRow + pData->iDestt -
2943                                                     pData->iSourcet);
2944                                        /* adjust destination rows starting-point */
2945     pScanline  = pScanline  + (pData->iCol * 3) + (pData->iDestl * 3);
2946     pAlphaline = pAlphaline + pData->iCol + pData->iDestl;
2947 
2948     pDataline  = pData->pRGBArow;      /* address source row */
2949 
2950     /* adjust source row starting-point */
2951     pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << (iBps+1));
2952 
2953     if (pData->bIsOpaque)              /* forget about transparency ? */
2954     {
2955         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
2956              iX += pData->iColinc)
2957         {                              /* scale down by dropping the LSB */
2958           *pScanline     = *pDataline;
2959           *(pScanline+1) = *(pDataline+iBps);
2960           *(pScanline+2) = *(pDataline+2*iBps);
2961           *pAlphaline    = *(pDataline+3*iBps);
2962 
2963           pScanline  += (pData->iColinc * 3);
2964           pAlphaline += pData->iColinc;
2965           pDataline  += 4*iBps;
2966         }
2967     }
2968     else
2969     {
2970       if (pData->bIsRGBA16)            /* 16-bit input row ? */
2971       {
2972         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
2973              iX += pData->iColinc)
2974         {                              /* get alpha values */
2975           iFGa16 = mng_get_uint16 (pDataline+6);
2976           iBGa16 = (mng_uint16)(*pAlphaline);
2977           iBGa16 = (mng_uint16)(iBGa16 << 8) | iBGa16;
2978 
2979           if (iFGa16)                  /* any opacity at all ? */
2980           {                            /* fully opaque or background fully transparent ? */
2981             if ((iFGa16 == 0xFFFF) || (iBGa16 == 0))
2982             {                          /* plain copy it */
2983               *pScanline     = *pDataline;
2984               *(pScanline+1) = *(pDataline+2);
2985               *(pScanline+2) = *(pDataline+4);
2986               *pAlphaline    = *(pDataline+6);
2987             }
2988             else
2989             {
2990               if (iBGa16 == 0xFFFF)    /* background fully opaque ? */
2991               {                        /* get the proper values */
2992               int i;
2993               for (i=2; i >= 0; i--)
2994               {
2995                 iFGg16 = mng_get_uint16 (pDataline+i+i);
2996                                        /* scale background up */
2997                 iBGg16 = (mng_uint16)(*(pScanline+i));
2998                 iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
2999                                        /* now compose */
3000                 MNG_COMPOSE16(iFGg16, iFGg16, iFGa16, iBGg16);
3001                                        /* and return the composed values */
3002                 *(pScanline+i) = (mng_uint8)(iFGg16 >> 8);
3003                                        /* alpha remains fully opaque !!! */
3004               }
3005               }
3006               else
3007               {                        /* scale background up */
3008                 iBGr16 = (mng_uint16)(*pScanline    );
3009                 iBGg16 = (mng_uint16)(*(pScanline+1));
3010                 iBGb16 = (mng_uint16)(*(pScanline+2));
3011                 iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
3012                 iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
3013                 iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
3014                                        /* let's blend */
3015                 MNG_BLEND16 (mng_get_uint16 (pDataline  ),
3016                              mng_get_uint16 (pDataline+2),
3017                              mng_get_uint16 (pDataline+4), iFGa16,
3018                              iBGr16, iBGg16, iBGb16, iBGa16,
3019                              iCr16,  iCg16,  iCb16,  iCa16);
3020                                        /* and return the composed values */
3021                 *pScanline     = (mng_uint8)(iCr16 >> 8);
3022                 *(pScanline+1) = (mng_uint8)(iCg16 >> 8);
3023                 *(pScanline+2) = (mng_uint8)(iCb16 >> 8);
3024                 *pAlphaline    = (mng_uint8)(iCa16 >> 8);
3025               }
3026             }
3027           }
3028 
3029           pScanline  += (pData->iColinc * 3);
3030           pAlphaline += pData->iColinc;
3031           pDataline  += 8;
3032         }
3033       }
3034       else
3035       {
3036         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
3037              iX += pData->iColinc)
3038         {
3039           iFGa8 = *(pDataline+3);      /* get alpha values */
3040           iBGa8 = *pAlphaline;
3041 
3042           if (iFGa8)                   /* any opacity at all ? */
3043           {                            /* fully opaque or background fully transparent ? */
3044             if ((iFGa8 == 0xFF) || (iBGa8 == 0))
3045             {                          /* then simply copy the values */
3046               *pScanline     = *pDataline;
3047               *(pScanline+1) = *(pDataline+1);
3048               *(pScanline+2) = *(pDataline+2);
3049               *pAlphaline    = *(pDataline+3);
3050             }
3051             else
3052             {
3053               if (iBGa8 == 0xFF)       /* background fully opaque ? */
3054               {                        /* do alpha composing */
3055               int i;
3056               for (i=2; i >= 0; i--)
3057               {
3058               MNG_COMPOSE8 (*(pScanline+i), *(pDataline+i), iFGa8, *(pScanline+i));
3059               }
3060                                        /* alpha remains fully opaque !!! */
3061               }
3062               else
3063               {                        /* now blend */
3064                 MNG_BLEND8 (*pDataline, *(pDataline+1), *(pDataline+2), iFGa8,
3065                             *pScanline, *(pScanline+1), *(pScanline+2), iBGa8,
3066                             iCr8, iCg8, iCb8, iCa8);
3067                                        /* and return the composed values */
3068                 *pScanline     = iCr8;
3069                 *(pScanline+1) = iCg8;
3070                 *(pScanline+2) = iCb8;
3071                 *pAlphaline    = iCa8;
3072               }
3073             }
3074           }
3075 
3076           pScanline  += (pData->iColinc * 3);
3077           pAlphaline += pData->iColinc;
3078           pDataline  += 4;
3079         }
3080       }
3081     }
3082   }
3083 
3084   check_update_region (pData);
3085 
3086 #ifdef MNG_SUPPORT_TRACE
3087   MNG_TRACE (pData, MNG_FN_DISPLAY_RGB8_A8, MNG_LC_END);
3088 #endif
3089 
3090   return MNG_NOERROR;
3091 }
3092 #endif /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
3093 #else /* MNG_NO_16BIT_SUPPORT */
mng_display_rgb8_a8(mng_datap pData)3094 mng_retcode mng_display_rgb8_a8 (mng_datap pData)
3095 {
3096   mng_uint8p pScanline;
3097   mng_uint8p pAlphaline;
3098   mng_uint8p pDataline;
3099   mng_int32  iX;
3100   mng_uint8  iFGa8, iBGa8, iCa8;
3101   mng_uint8  iCr8, iCg8, iCb8;
3102 
3103 #ifdef MNG_SUPPORT_TRACE
3104   MNG_TRACE (pData, MNG_FN_DISPLAY_RGB8_A8, MNG_LC_START);
3105 #endif
3106                                        /* viewable row ? */
3107   if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
3108   {                                    /* address destination rows */
3109     pScanline  = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
3110                                                     pData->iRow + pData->iDestt -
3111                                                     pData->iSourcet);
3112     pAlphaline = (mng_uint8p)pData->fGetalphaline  (((mng_handle)pData),
3113                                                     pData->iRow + pData->iDestt -
3114                                                     pData->iSourcet);
3115                                        /* adjust destination rows starting-point */
3116     pScanline  = pScanline  + (pData->iCol * 3) + (pData->iDestl * 3);
3117     pAlphaline = pAlphaline + pData->iCol + pData->iDestl;
3118 
3119     pDataline  = pData->pRGBArow;      /* address source row */
3120 
3121       pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
3122 
3123     if (pData->bIsOpaque)              /* forget about transparency ? */
3124     {
3125       {
3126         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
3127              iX += pData->iColinc)
3128         {                              /* copy the values */
3129           *pScanline     = *pDataline;
3130           *(pScanline+1) = *(pDataline+1);
3131           *(pScanline+2) = *(pDataline+2);
3132           *pAlphaline    = *(pDataline+3);
3133 
3134           pScanline  += (pData->iColinc * 3);
3135           pAlphaline += pData->iColinc;
3136           pDataline  += 4;
3137         }
3138       }
3139     }
3140     else
3141     {
3142       {
3143         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
3144              iX += pData->iColinc)
3145         {
3146           iFGa8 = *(pDataline+3);      /* get alpha values */
3147           iBGa8 = *pAlphaline;
3148 
3149           if (iFGa8)                   /* any opacity at all ? */
3150           {                            /* fully opaque or background fully transparent ? */
3151             if ((iFGa8 == 0xFF) || (iBGa8 == 0))
3152             {                          /* then simply copy the values */
3153               *pScanline     = *pDataline;
3154               *(pScanline+1) = *(pDataline+1);
3155               *(pScanline+2) = *(pDataline+2);
3156               *pAlphaline    = *(pDataline+3);
3157             }
3158             else
3159             {
3160               if (iBGa8 == 0xFF)       /* background fully opaque ? */
3161               {                        /* do alpha composing */
3162 #ifdef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
3163               int i;
3164               for (i=2; i >= 0; i--)
3165               {
3166               MNG_COMPOSE8 (*(pScanline+i), *(pDataline+i), iFGa8, *(pScanline+i));
3167               }
3168 #else
3169                 MNG_COMPOSE8 (*pScanline,     *pDataline,     iFGa8, *pScanline    );
3170                 MNG_COMPOSE8 (*(pScanline+1), *(pDataline+1), iFGa8, *(pScanline+1));
3171                 MNG_COMPOSE8 (*(pScanline+2), *(pDataline+2), iFGa8, *(pScanline+2));
3172 #endif
3173                                        /* alpha remains fully opaque !!! */
3174               }
3175               else
3176               {                        /* now blend */
3177                 MNG_BLEND8 (*pDataline, *(pDataline+1), *(pDataline+2), iFGa8,
3178                             *pScanline, *(pScanline+1), *(pScanline+2), iBGa8,
3179                             iCr8, iCg8, iCb8, iCa8);
3180                                        /* and return the composed values */
3181                 *pScanline     = iCr8;
3182                 *(pScanline+1) = iCg8;
3183                 *(pScanline+2) = iCb8;
3184                 *pAlphaline    = iCa8;
3185               }
3186             }
3187           }
3188 
3189           pScanline  += (pData->iColinc * 3);
3190           pAlphaline += pData->iColinc;
3191           pDataline  += 4;
3192         }
3193       }
3194     }
3195   }
3196 
3197   check_update_region (pData);
3198 
3199 #ifdef MNG_SUPPORT_TRACE
3200   MNG_TRACE (pData, MNG_FN_DISPLAY_RGB8_A8, MNG_LC_END);
3201 #endif
3202 
3203   return MNG_NOERROR;
3204 }
3205 #endif /* MNG_NO_16BIT_SUPPORT */
3206 #endif /* MNG_SKIPCANVAS_RGB8_A8 */
3207 
3208 /* ************************************************************************** */
3209 
3210 #ifndef MNG_SKIPCANVAS_BGR8
3211 #ifndef MNG_NO_16BIT_SUPPORT
3212 #ifndef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
mng_display_bgr8(mng_datap pData)3213 mng_retcode mng_display_bgr8 (mng_datap pData)
3214 {
3215   mng_uint8p pScanline;
3216   mng_uint8p pDataline;
3217   mng_int32  iX;
3218   mng_uint16 iA16;
3219   mng_uint16 iFGr16, iFGg16, iFGb16;
3220   mng_uint16 iBGr16, iBGg16, iBGb16;
3221   mng_uint8  iA8;
3222 
3223 #ifdef MNG_SUPPORT_TRACE
3224   MNG_TRACE (pData, MNG_FN_DISPLAY_BGR8, MNG_LC_START);
3225 #endif
3226                                        /* viewable row ? */
3227   if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
3228   {                                    /* address destination row */
3229     pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
3230                                                    pData->iRow + pData->iDestt -
3231                                                    pData->iSourcet);
3232                                        /* adjust destination row starting-point */
3233     pScanline = pScanline + (pData->iCol * 3) + (pData->iDestl * 3);
3234     pDataline = pData->pRGBArow;       /* address source row */
3235 
3236     if (pData->bIsRGBA16)              /* adjust source row starting-point */
3237       pDataline = pDataline + (pData->iSourcel / pData->iColinc) * 8;
3238     else
3239       pDataline = pDataline + (pData->iSourcel / pData->iColinc) * 4;
3240 
3241     if (pData->bIsOpaque)              /* forget about transparency ? */
3242     {
3243       if (pData->bIsRGBA16)            /* 16-bit input row ? */
3244       {
3245         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
3246              iX += pData->iColinc)
3247         {                              /* scale down by dropping the LSB */
3248           *pScanline     = *(pDataline+4);
3249           *(pScanline+1) = *(pDataline+2);
3250           *(pScanline+2) = *pDataline;
3251 
3252           pScanline += (pData->iColinc * 3);
3253           pDataline += 8;
3254         }
3255       }
3256       else
3257       {
3258         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
3259              iX += pData->iColinc)
3260         {                              /* copy the values */
3261           *pScanline     = *(pDataline+2);
3262           *(pScanline+1) = *(pDataline+1);
3263           *(pScanline+2) = *pDataline;
3264 
3265           pScanline += (pData->iColinc * 3);
3266           pDataline += 4;
3267         }
3268       }
3269     }
3270     else
3271     {
3272       if (pData->bIsRGBA16)            /* 16-bit input row ? */
3273       {
3274         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
3275              iX += pData->iColinc)
3276         {                              /* get alpha value */
3277           iA16 = mng_get_uint16 (pDataline+6);
3278 
3279           if (iA16)                    /* any opacity at all ? */
3280           {
3281             if (iA16 == 0xFFFF)        /* fully opaque ? */
3282             {                          /* scale down by dropping the LSB */
3283               *pScanline     = *(pDataline+4);
3284               *(pScanline+1) = *(pDataline+2);
3285               *(pScanline+2) = *pDataline;
3286             }
3287             else
3288             {                          /* get the proper values */
3289               iFGr16 = mng_get_uint16 (pDataline  );
3290               iFGg16 = mng_get_uint16 (pDataline+2);
3291               iFGb16 = mng_get_uint16 (pDataline+4);
3292                                        /* scale background up */
3293               iBGr16 = (mng_uint16)(*(pScanline+2));
3294               iBGg16 = (mng_uint16)(*(pScanline+1));
3295               iBGb16 = (mng_uint16)(*pScanline    );
3296               iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
3297               iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
3298               iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
3299                                        /* now compose */
3300               MNG_COMPOSE16(iFGr16, iFGr16, iA16, iBGr16);
3301               MNG_COMPOSE16(iFGg16, iFGg16, iA16, iBGg16);
3302               MNG_COMPOSE16(iFGb16, iFGb16, iA16, iBGb16);
3303                                        /* and return the composed values */
3304               *pScanline     = (mng_uint8)(iFGb16 >> 8);
3305               *(pScanline+1) = (mng_uint8)(iFGg16 >> 8);
3306               *(pScanline+2) = (mng_uint8)(iFGr16 >> 8);
3307             }
3308           }
3309 
3310           pScanline += (pData->iColinc * 3);
3311           pDataline += 8;
3312         }
3313       }
3314       else
3315       {
3316         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
3317              iX += pData->iColinc)
3318         {
3319           iA8 = *(pDataline+3);        /* get alpha value */
3320 
3321           if (iA8)                     /* any opacity at all ? */
3322           {
3323             if (iA8 == 0xFF)           /* fully opaque ? */
3324             {                          /* then simply copy the values */
3325               *pScanline     = *(pDataline+2);
3326               *(pScanline+1) = *(pDataline+1);
3327               *(pScanline+2) = *pDataline;
3328             }
3329             else
3330             {                          /* do alpha composing */
3331               MNG_COMPOSE8 (*pScanline,     *(pDataline+2), iA8, *pScanline    );
3332               MNG_COMPOSE8 (*(pScanline+1), *(pDataline+1), iA8, *(pScanline+1));
3333               MNG_COMPOSE8 (*(pScanline+2), *pDataline,     iA8, *(pScanline+2));
3334             }
3335           }
3336 
3337           pScanline += (pData->iColinc * 3);
3338           pDataline += 4;
3339         }
3340       }
3341     }
3342   }
3343 
3344   check_update_region (pData);
3345 
3346 #ifdef MNG_SUPPORT_TRACE
3347   MNG_TRACE (pData, MNG_FN_DISPLAY_BGR8, MNG_LC_END);
3348 #endif
3349 
3350   return MNG_NOERROR;
3351 }
3352 #else /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
mng_display_bgr8(mng_datap pData)3353 mng_retcode mng_display_bgr8 (mng_datap pData)
3354 {
3355   mng_uint8p pScanline;
3356   mng_uint8p pDataline;
3357   mng_int32  iX;
3358   mng_uint16 iA16;
3359   mng_uint16 iFGg16;
3360   mng_uint16 iBGg16;
3361   mng_uint8  iA8;
3362   mng_uint8  iBps;
3363 
3364 #ifdef MNG_SUPPORT_TRACE
3365   MNG_TRACE (pData, MNG_FN_DISPLAY_BGR8, MNG_LC_START);
3366 #endif
3367 
3368   iBps=(mng_uint8)(pData->bIsRGBA16 ? 2:1);
3369                                        /* viewable row ? */
3370   if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
3371   {                                    /* address destination row */
3372     pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
3373                                                    pData->iRow + pData->iDestt -
3374                                                    pData->iSourcet);
3375                                        /* adjust destination row starting-point */
3376     pScanline = pScanline + (pData->iCol * 3) + (pData->iDestl * 3);
3377     pDataline = pData->pRGBArow;       /* address source row */
3378 
3379     /* adjust source row starting-point */
3380     pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << (iBps+1));
3381 
3382     if (pData->bIsOpaque)              /* forget about transparency ? */
3383     {
3384         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
3385              iX += pData->iColinc)
3386         {                              /* scale down by dropping the LSB */
3387           *pScanline     = *(pDataline+2*iBps);
3388           *(pScanline+1) = *(pDataline+iBps);
3389           *(pScanline+2) = *pDataline;
3390 
3391           pScanline += (pData->iColinc * 3);
3392           pDataline += 4*iBps;
3393         }
3394     }
3395     else
3396     {
3397       if (pData->bIsRGBA16)            /* 16-bit input row ? */
3398       {
3399         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
3400              iX += pData->iColinc)
3401         {                              /* get alpha value */
3402           iA16 = mng_get_uint16 (pDataline+6);
3403 
3404           if (iA16)                    /* any opacity at all ? */
3405           {
3406             if (iA16 == 0xFFFF)        /* fully opaque ? */
3407             {                          /* scale down by dropping the LSB */
3408               *pScanline     = *(pDataline+4);
3409               *(pScanline+1) = *(pDataline+2);
3410               *(pScanline+2) = *pDataline;
3411             }
3412             else
3413             {                          /* get the proper values */
3414               int i;
3415               for (i=2; i >= 0; i--)
3416               {
3417               iFGg16 = mng_get_uint16 (pDataline+i+i);
3418                                        /* scale background up */
3419               iBGg16 = (mng_uint16)(*(pScanline+2-i));
3420               iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
3421                                        /* now compose */
3422               MNG_COMPOSE16(iFGg16, iFGg16, iA16, iBGg16);
3423                                        /* and return the composed values */
3424               *(pScanline+2-i) = (mng_uint8)(iFGg16 >> 8);
3425               }
3426             }
3427           }
3428 
3429           pScanline += (pData->iColinc * 3);
3430           pDataline += 8;
3431         }
3432       }
3433       else
3434       {
3435         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
3436              iX += pData->iColinc)
3437         {
3438           iA8 = *(pDataline+3);        /* get alpha value */
3439 
3440           if (iA8)                     /* any opacity at all ? */
3441           {
3442             if (iA8 == 0xFF)           /* fully opaque ? */
3443             {                          /* then simply copy the values */
3444               *pScanline     = *(pDataline+2);
3445               *(pScanline+1) = *(pDataline+1);
3446               *(pScanline+2) = *pDataline;
3447             }
3448             else
3449             {                          /* do alpha composing */
3450               int i;
3451               for (i=2; i >= 0; i--)
3452               {
3453               MNG_COMPOSE8 (*(pScanline+i), *(pDataline+2-i), iA8, *(pScanline+i));
3454               }
3455             }
3456           }
3457 
3458           pScanline += (pData->iColinc * 3);
3459           pDataline += 4;
3460         }
3461       }
3462     }
3463   }
3464 
3465   check_update_region (pData);
3466 
3467 #ifdef MNG_SUPPORT_TRACE
3468   MNG_TRACE (pData, MNG_FN_DISPLAY_BGR8, MNG_LC_END);
3469 #endif
3470 
3471   return MNG_NOERROR;
3472 }
3473 #endif /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
3474 #else /* MNG_NO_16BIT_SUPPORT */
mng_display_bgr8(mng_datap pData)3475 mng_retcode mng_display_bgr8 (mng_datap pData)
3476 {
3477   mng_uint8p pScanline;
3478   mng_uint8p pDataline;
3479   mng_int32  iX;
3480   mng_uint8  iA8;
3481 
3482 #ifdef MNG_SUPPORT_TRACE
3483   MNG_TRACE (pData, MNG_FN_DISPLAY_BGR8, MNG_LC_START);
3484 #endif
3485                                        /* viewable row ? */
3486   if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
3487   {                                    /* address destination row */
3488     pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
3489                                                    pData->iRow + pData->iDestt -
3490                                                    pData->iSourcet);
3491                                        /* adjust destination row starting-point */
3492     pScanline = pScanline + (pData->iCol * 3) + (pData->iDestl * 3);
3493     pDataline = pData->pRGBArow;       /* address source row */
3494 
3495       pDataline = pDataline + (pData->iSourcel / pData->iColinc) * 4;
3496 
3497     if (pData->bIsOpaque)              /* forget about transparency ? */
3498     {
3499       {
3500         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
3501              iX += pData->iColinc)
3502         {                              /* copy the values */
3503           *pScanline     = *(pDataline+2);
3504           *(pScanline+1) = *(pDataline+1);
3505           *(pScanline+2) = *pDataline;
3506 
3507           pScanline += (pData->iColinc * 3);
3508           pDataline += 4;
3509         }
3510       }
3511     }
3512     else
3513     {
3514       {
3515         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
3516              iX += pData->iColinc)
3517         {
3518           iA8 = *(pDataline+3);        /* get alpha value */
3519 
3520           if (iA8)                     /* any opacity at all ? */
3521           {
3522             if (iA8 == 0xFF)           /* fully opaque ? */
3523             {                          /* then simply copy the values */
3524               *pScanline     = *(pDataline+2);
3525               *(pScanline+1) = *(pDataline+1);
3526               *(pScanline+2) = *pDataline;
3527             }
3528             else
3529             {                          /* do alpha composing */
3530 #ifdef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
3531               int i;
3532               for (i=2; i >= 0; i--)
3533               {
3534               MNG_COMPOSE8 (*(pScanline+i), *(pDataline+2-i), iA8, *(pScanline+i));
3535               }
3536 #else
3537               MNG_COMPOSE8 (*pScanline,     *(pDataline+2), iA8, *pScanline    );
3538               MNG_COMPOSE8 (*(pScanline+1), *(pDataline+1), iA8, *(pScanline+1));
3539               MNG_COMPOSE8 (*(pScanline+2), *pDataline,     iA8, *(pScanline+2));
3540 #endif
3541             }
3542           }
3543 
3544           pScanline += (pData->iColinc * 3);
3545           pDataline += 4;
3546         }
3547       }
3548     }
3549   }
3550 
3551   check_update_region (pData);
3552 
3553 #ifdef MNG_SUPPORT_TRACE
3554   MNG_TRACE (pData, MNG_FN_DISPLAY_BGR8, MNG_LC_END);
3555 #endif
3556 
3557   return MNG_NOERROR;
3558 }
3559 #endif /* MNG_NO_16BIT_SUPPORT */
3560 #endif /* MNG_SKIPCANVAS_BGR8 */
3561 
3562 /* ************************************************************************** */
3563 
3564 #ifndef MNG_SKIPCANVAS_BGRX8
3565 #ifndef MNG_NO_16BIT_SUPPORT
3566 #ifndef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
mng_display_bgrx8(mng_datap pData)3567 mng_retcode mng_display_bgrx8 (mng_datap pData)
3568 {
3569   mng_uint8p pScanline;
3570   mng_uint8p pDataline;
3571   mng_int32  iX;
3572   mng_uint16 iA16;
3573   mng_uint16 iFGr16, iFGg16, iFGb16;
3574   mng_uint16 iBGr16, iBGg16, iBGb16;
3575   mng_uint8  iA8;
3576 
3577 #ifdef MNG_SUPPORT_TRACE
3578   MNG_TRACE (pData, MNG_FN_DISPLAY_BGRX8, MNG_LC_START);
3579 #endif
3580                                        /* viewable row ? */
3581   if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
3582   {                                    /* address destination row */
3583     pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
3584                                                    pData->iRow + pData->iDestt -
3585                                                    pData->iSourcet);
3586                                        /* adjust destination row starting-point */
3587     pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
3588     pDataline = pData->pRGBArow;       /* address source row */
3589 
3590     if (pData->bIsRGBA16)              /* adjust source row starting-point */
3591       pDataline = pDataline + (pData->iSourcel / pData->iColinc) * 8;
3592     else
3593       pDataline = pDataline + (pData->iSourcel / pData->iColinc) * 4;
3594 
3595     if (pData->bIsOpaque)              /* forget about transparency ? */
3596     {
3597       if (pData->bIsRGBA16)            /* 16-bit input row ? */
3598       {
3599         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
3600              iX += pData->iColinc)
3601         {                              /* scale down by dropping the LSB */
3602           *pScanline     = *(pDataline+4);
3603           *(pScanline+1) = *(pDataline+2);
3604           *(pScanline+2) = *pDataline;
3605           *(pScanline+3) = 0xFF;       /* filler byte */
3606 
3607           pScanline += (pData->iColinc << 2);
3608           pDataline += 8;
3609         }
3610       }
3611       else
3612       {
3613         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
3614              iX += pData->iColinc)
3615         {                              /* copy the values */
3616           *pScanline     = *(pDataline+2);
3617           *(pScanline+1) = *(pDataline+1);
3618           *(pScanline+2) = *pDataline;
3619           *(pScanline+3) = 0xFF;       /* filler byte */
3620 
3621           pScanline += (pData->iColinc << 2);
3622           pDataline += 4;
3623         }
3624       }
3625     }
3626     else
3627     {
3628       if (pData->bIsRGBA16)            /* 16-bit input row ? */
3629       {
3630         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
3631              iX += pData->iColinc)
3632         {                              /* get alpha value */
3633           iA16 = mng_get_uint16 (pDataline+6);
3634 
3635           if (iA16)                    /* any opacity at all ? */
3636           {
3637             if (iA16 == 0xFFFF)        /* fully opaque ? */
3638             {                          /* scale down by dropping the LSB */
3639               *pScanline     = *(pDataline+4);
3640               *(pScanline+1) = *(pDataline+2);
3641               *(pScanline+2) = *pDataline;
3642               *(pScanline+3) = 0xFF;   /* filler byte */
3643             }
3644             else
3645             {                          /* get the proper values */
3646               iFGr16 = mng_get_uint16 (pDataline  );
3647               iFGg16 = mng_get_uint16 (pDataline+2);
3648               iFGb16 = mng_get_uint16 (pDataline+4);
3649                                        /* scale background up */
3650               iBGr16 = (mng_uint16)(*(pScanline+2));
3651               iBGg16 = (mng_uint16)(*(pScanline+1));
3652               iBGb16 = (mng_uint16)(*pScanline    );
3653               iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
3654               iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
3655               iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
3656                                        /* now compose */
3657               MNG_COMPOSE16(iFGr16, iFGr16, iA16, iBGr16);
3658               MNG_COMPOSE16(iFGg16, iFGg16, iA16, iBGg16);
3659               MNG_COMPOSE16(iFGb16, iFGb16, iA16, iBGb16);
3660                                        /* and return the composed values */
3661               *pScanline     = (mng_uint8)(iFGb16 >> 8);
3662               *(pScanline+1) = (mng_uint8)(iFGg16 >> 8);
3663               *(pScanline+2) = (mng_uint8)(iFGr16 >> 8);
3664               *(pScanline+3) = 0xFF;   /* filler byte */
3665             }
3666           }
3667 
3668           pScanline += (pData->iColinc << 2);
3669           pDataline += 8;
3670         }
3671       }
3672       else
3673       {
3674         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
3675              iX += pData->iColinc)
3676         {
3677           iA8 = *(pDataline+3);        /* get alpha value */
3678 
3679           if (iA8)                     /* any opacity at all ? */
3680           {
3681             if (iA8 == 0xFF)           /* fully opaque ? */
3682             {                          /* then simply copy the values */
3683               *pScanline     = *(pDataline+2);
3684               *(pScanline+1) = *(pDataline+1);
3685               *(pScanline+2) = *pDataline;
3686               *(pScanline+3) = 0xFF;   /* filler byte */
3687             }
3688             else
3689             {                          /* do alpha composing */
3690               MNG_COMPOSE8 (*pScanline,     *(pDataline+2), iA8, *pScanline    );
3691               MNG_COMPOSE8 (*(pScanline+1), *(pDataline+1), iA8, *(pScanline+1));
3692               MNG_COMPOSE8 (*(pScanline+2), *pDataline,     iA8, *(pScanline+2));
3693               *(pScanline+3) = 0xFF;   /* filler byte */
3694             }
3695           }
3696 
3697           pScanline += (pData->iColinc << 2);
3698           pDataline += 4;
3699         }
3700       }
3701     }
3702   }
3703 
3704   check_update_region (pData);
3705 
3706 #ifdef MNG_SUPPORT_TRACE
3707   MNG_TRACE (pData, MNG_FN_DISPLAY_BGRX8, MNG_LC_END);
3708 #endif
3709 
3710   return MNG_NOERROR;
3711 }
3712 #else /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
mng_display_bgrx8(mng_datap pData)3713 mng_retcode mng_display_bgrx8 (mng_datap pData)
3714 {
3715   mng_uint8p pScanline;
3716   mng_uint8p pDataline;
3717   mng_int32  iX;
3718   mng_uint16 iA16;
3719   mng_uint16 iFGg16;
3720   mng_uint16 iBGg16;
3721   mng_uint8  iA8;
3722   mng_uint8  iBps;
3723 
3724 #ifdef MNG_SUPPORT_TRACE
3725   MNG_TRACE (pData, MNG_FN_DISPLAY_BGRX8, MNG_LC_START);
3726 #endif
3727 
3728   iBps=(mng_uint8)(pData->bIsRGBA16 ? 2:1);
3729                                        /* viewable row ? */
3730   if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
3731   {                                    /* address destination row */
3732     pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
3733                                                    pData->iRow + pData->iDestt -
3734                                                    pData->iSourcet);
3735                                        /* adjust destination row starting-point */
3736     pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
3737     pDataline = pData->pRGBArow;       /* address source row */
3738 
3739     /* adjust source row starting-point */
3740     pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << (iBps+1));
3741 
3742     if (pData->bIsOpaque)              /* forget about transparency ? */
3743     {
3744         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
3745              iX += pData->iColinc)
3746         {                              /* scale down by dropping the LSB */
3747           *pScanline     = *(pDataline+2*iBps);
3748           *(pScanline+1) = *(pDataline+iBps);
3749           *(pScanline+2) = *pDataline;
3750           *(pScanline+3) = 0xFF;       /* filler byte */
3751 
3752           pScanline += (pData->iColinc << 2);
3753           pDataline += 4*iBps;
3754         }
3755     }
3756     else
3757     {
3758       if (pData->bIsRGBA16)            /* 16-bit input row ? */
3759       {
3760         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
3761              iX += pData->iColinc)
3762         {                              /* get alpha value */
3763           iA16 = mng_get_uint16 (pDataline+6);
3764 
3765           if (iA16)                    /* any opacity at all ? */
3766           {
3767             if (iA16 == 0xFFFF)        /* fully opaque ? */
3768             {                          /* scale down by dropping the LSB */
3769               *pScanline     = *(pDataline+4);
3770               *(pScanline+1) = *(pDataline+2);
3771               *(pScanline+2) = *pDataline;
3772               *(pScanline+3) = 0xFF;   /* filler byte */
3773             }
3774             else
3775             {                          /* get the proper values */
3776               int i;
3777               for (i=2; i >= 0; i--)
3778               {
3779               iFGg16 = mng_get_uint16 (pDataline+i+i);
3780                                        /* scale background up */
3781               iBGg16 = (mng_uint16)(*(pScanline+2-i));
3782               iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
3783                                        /* now compose */
3784               MNG_COMPOSE16(iFGg16, iFGg16, iA16, iBGg16);
3785                                        /* and return the composed values */
3786               *(pScanline+2-i) = (mng_uint8)(iFGg16 >> 8);
3787               }
3788               *(pScanline+3) = 0xFF;   /* filler byte */
3789             }
3790           }
3791 
3792           pScanline += (pData->iColinc << 2);
3793           pDataline += 8;
3794         }
3795       }
3796       else
3797       {
3798         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
3799              iX += pData->iColinc)
3800         {
3801           iA8 = *(pDataline+3);        /* get alpha value */
3802 
3803           if (iA8)                     /* any opacity at all ? */
3804           {
3805             if (iA8 == 0xFF)           /* fully opaque ? */
3806             {                          /* then simply copy the values */
3807               *pScanline     = *(pDataline+2);
3808               *(pScanline+1) = *(pDataline+1);
3809               *(pScanline+2) = *pDataline;
3810               *(pScanline+3) = 0xFF;   /* filler byte */
3811             }
3812             else
3813             {                          /* do alpha composing */
3814               int i;
3815               for (i=2; i >= 0; i--)
3816               {
3817               MNG_COMPOSE8 (*(pScanline+i), *(pDataline+2-i), iA8, *(pScanline+i));
3818               }
3819               *(pScanline+3) = 0xFF;   /* filler byte */
3820             }
3821           }
3822 
3823           pScanline += (pData->iColinc << 2);
3824           pDataline += 4;
3825         }
3826       }
3827     }
3828   }
3829 
3830   check_update_region (pData);
3831 
3832 #ifdef MNG_SUPPORT_TRACE
3833   MNG_TRACE (pData, MNG_FN_DISPLAY_BGRX8, MNG_LC_END);
3834 #endif
3835 
3836   return MNG_NOERROR;
3837 }
3838 #endif /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
3839 #else /* MNG_NO_16BIT_SUPPORT */
mng_display_bgrx8(mng_datap pData)3840 mng_retcode mng_display_bgrx8 (mng_datap pData)
3841 {
3842   mng_uint8p pScanline;
3843   mng_uint8p pDataline;
3844   mng_int32  iX;
3845   mng_uint8  iA8;
3846 
3847 #ifdef MNG_SUPPORT_TRACE
3848   MNG_TRACE (pData, MNG_FN_DISPLAY_BGRX8, MNG_LC_START);
3849 #endif
3850                                        /* viewable row ? */
3851   if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
3852   {                                    /* address destination row */
3853     pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
3854                                                    pData->iRow + pData->iDestt -
3855                                                    pData->iSourcet);
3856                                        /* adjust destination row starting-point */
3857     pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
3858     pDataline = pData->pRGBArow;       /* address source row */
3859 
3860       pDataline = pDataline + (pData->iSourcel / pData->iColinc) * 4;
3861 
3862     if (pData->bIsOpaque)              /* forget about transparency ? */
3863     {
3864       {
3865         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
3866              iX += pData->iColinc)
3867         {                              /* copy the values */
3868           *pScanline     = *(pDataline+2);
3869           *(pScanline+1) = *(pDataline+1);
3870           *(pScanline+2) = *pDataline;
3871           *(pScanline+3) = 0xFF;       /* filler byte */
3872 
3873           pScanline += (pData->iColinc << 2);
3874           pDataline += 4;
3875         }
3876       }
3877     }
3878     else
3879     {
3880       {
3881         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
3882              iX += pData->iColinc)
3883         {
3884           iA8 = *(pDataline+3);        /* get alpha value */
3885 
3886           if (iA8)                     /* any opacity at all ? */
3887           {
3888             if (iA8 == 0xFF)           /* fully opaque ? */
3889             {                          /* then simply copy the values */
3890               *pScanline     = *(pDataline+2);
3891               *(pScanline+1) = *(pDataline+1);
3892               *(pScanline+2) = *pDataline;
3893               *(pScanline+3) = 0xFF;   /* filler byte */
3894             }
3895             else
3896             {                          /* do alpha composing */
3897 #ifdef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
3898               int i;
3899               for (i=2; i >= 0; i--)
3900               {
3901               MNG_COMPOSE8 (*(pScanline+i), *(pDataline+2-i), iA8, *(pScanline+i));
3902               }
3903 #else
3904               MNG_COMPOSE8 (*pScanline,     *(pDataline+2), iA8, *pScanline    );
3905               MNG_COMPOSE8 (*(pScanline+1), *(pDataline+1), iA8, *(pScanline+1));
3906               MNG_COMPOSE8 (*(pScanline+2), *pDataline,     iA8, *(pScanline+2));
3907 #endif
3908               *(pScanline+3) = 0xFF;   /* filler byte */
3909             }
3910           }
3911 
3912           pScanline += (pData->iColinc << 2);
3913           pDataline += 4;
3914         }
3915       }
3916     }
3917   }
3918 
3919   check_update_region (pData);
3920 
3921 #ifdef MNG_SUPPORT_TRACE
3922   MNG_TRACE (pData, MNG_FN_DISPLAY_BGRX8, MNG_LC_END);
3923 #endif
3924 
3925   return MNG_NOERROR;
3926 }
3927 #endif /* MNG_NO_16BIT_SUPPORT */
3928 #endif /* MNG_SKIPCANVAS_BGRX8 */
3929 
3930 /* ************************************************************************** */
3931 
3932 #ifndef MNG_SKIPCANVAS_BGRA8
3933 #ifndef MNG_NO_16BIT_SUPPORT
3934 #ifndef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
mng_display_bgra8(mng_datap pData)3935 mng_retcode mng_display_bgra8 (mng_datap pData)
3936 {
3937   mng_uint8p pScanline;
3938   mng_uint8p pDataline;
3939   mng_int32  iX;
3940   mng_uint8  iFGa8, iBGa8, iCa8;
3941   mng_uint16 iFGa16, iBGa16, iCa16;
3942   mng_uint16 iFGr16, iFGg16, iFGb16;
3943   mng_uint16 iBGr16, iBGg16, iBGb16;
3944   mng_uint16 iCr16, iCg16, iCb16;
3945   mng_uint8  iCr8, iCg8, iCb8;
3946 
3947 #ifdef MNG_SUPPORT_TRACE
3948   MNG_TRACE (pData, MNG_FN_DISPLAY_BGRA8, MNG_LC_START);
3949 #endif
3950                                        /* viewable row ? */
3951   if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
3952   {                                    /* address destination row */
3953     pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
3954                                                    pData->iRow + pData->iDestt -
3955                                                    pData->iSourcet);
3956                                        /* adjust destination row starting-point */
3957     pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
3958     pDataline = pData->pRGBArow;       /* address source row */
3959 
3960     if (pData->bIsRGBA16)              /* adjust source row starting-point */
3961       pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 3);
3962     else
3963       pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
3964 
3965     if (pData->bIsOpaque)              /* forget about transparency ? */
3966     {
3967       if (pData->bIsRGBA16)            /* 16-bit input row ? */
3968       {
3969         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
3970              iX += pData->iColinc)
3971         {                              /* scale down by dropping the LSB */
3972           *pScanline     = *(pDataline+4);
3973           *(pScanline+1) = *(pDataline+2);
3974           *(pScanline+2) = *pDataline;
3975           *(pScanline+3) = *(pDataline+6);
3976 
3977           pScanline += (pData->iColinc << 2);
3978           pDataline += 8;
3979         }
3980       }
3981       else
3982       {
3983         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
3984              iX += pData->iColinc)
3985         {                              /* copy the values */
3986           *pScanline     = *(pDataline+2);
3987           *(pScanline+1) = *(pDataline+1);
3988           *(pScanline+2) = *pDataline;
3989           *(pScanline+3) = *(pDataline+3);
3990 
3991           pScanline += (pData->iColinc << 2);
3992           pDataline += 4;
3993         }
3994       }
3995     }
3996     else
3997     {
3998       if (pData->bIsRGBA16)            /* 16-bit input row ? */
3999       {
4000         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
4001              iX += pData->iColinc)
4002         {                              /* get alpha values */
4003           iFGa16 = mng_get_uint16 (pDataline+6);
4004           iBGa16 = (mng_uint16)(*(pScanline+3));
4005           iBGa16 = (mng_uint16)(iBGa16 << 8) | iBGa16;
4006 
4007           if (iFGa16)                  /* any opacity at all ? */
4008           {                            /* fully opaque or background fully transparent ? */
4009             if ((iFGa16 == 0xFFFF) || (iBGa16 == 0))
4010             {                          /* plain copy it */
4011               *pScanline     = *(pDataline+4);
4012               *(pScanline+1) = *(pDataline+2);
4013               *(pScanline+2) = *pDataline;
4014               *(pScanline+3) = *(pDataline+6);
4015             }
4016             else
4017             {
4018               if (iBGa16 == 0xFFFF)    /* background fully opaque ? */
4019               {                        /* get the proper values */
4020                 iFGr16 = mng_get_uint16 (pDataline  );
4021                 iFGg16 = mng_get_uint16 (pDataline+2);
4022                 iFGb16 = mng_get_uint16 (pDataline+4);
4023                                        /* scale background up */
4024                 iBGr16 = (mng_uint16)(*(pScanline+2));
4025                 iBGg16 = (mng_uint16)(*(pScanline+1));
4026                 iBGb16 = (mng_uint16)(*pScanline    );
4027                 iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
4028                 iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
4029                 iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
4030                                        /* now compose */
4031                 MNG_COMPOSE16(iFGr16, iFGr16, iFGa16, iBGr16);
4032                 MNG_COMPOSE16(iFGg16, iFGg16, iFGa16, iBGg16);
4033                 MNG_COMPOSE16(iFGb16, iFGb16, iFGa16, iBGb16);
4034                                        /* and return the composed values */
4035                 *pScanline     = (mng_uint8)(iFGb16 >> 8);
4036                 *(pScanline+1) = (mng_uint8)(iFGg16 >> 8);
4037                 *(pScanline+2) = (mng_uint8)(iFGr16 >> 8);
4038                                        /* alpha remains fully opaque !!! */
4039               }
4040               else
4041               {                        /* scale background up */
4042                 iBGr16 = (mng_uint16)(*(pScanline+2));
4043                 iBGg16 = (mng_uint16)(*(pScanline+1));
4044                 iBGb16 = (mng_uint16)(*pScanline    );
4045                 iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
4046                 iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
4047                 iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
4048                                        /* let's blend */
4049                 MNG_BLEND16 (mng_get_uint16 (pDataline  ),
4050                              mng_get_uint16 (pDataline+2),
4051                              mng_get_uint16 (pDataline+4), iFGa16,
4052                              iBGr16, iBGg16, iBGb16, iBGa16,
4053                              iCr16,  iCg16,  iCb16,  iCa16);
4054                                        /* and return the composed values */
4055                 *pScanline     = (mng_uint8)(iCb16 >> 8);
4056                 *(pScanline+1) = (mng_uint8)(iCg16 >> 8);
4057                 *(pScanline+2) = (mng_uint8)(iCr16 >> 8);
4058                 *(pScanline+3) = (mng_uint8)(iCa16 >> 8);
4059               }
4060             }
4061           }
4062 
4063           pScanline += (pData->iColinc << 2);
4064           pDataline += 8;
4065         }
4066       }
4067       else
4068       {
4069         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
4070              iX += pData->iColinc)
4071         {
4072           iFGa8 = *(pDataline+3);      /* get alpha values */
4073           iBGa8 = *(pScanline+3);
4074 
4075           if (iFGa8)                   /* any opacity at all ? */
4076           {                            /* fully opaque or background fully transparent ? */
4077             if ((iFGa8 == 0xFF) || (iBGa8 == 0))
4078             {                          /* then simply copy the values */
4079               *pScanline     = *(pDataline+2);
4080               *(pScanline+1) = *(pDataline+1);
4081               *(pScanline+2) = *pDataline;
4082               *(pScanline+3) = *(pDataline+3);
4083             }
4084             else
4085             {
4086               if (iBGa8 == 0xFF)       /* background fully opaque ? */
4087               {                        /* do alpha composing */
4088                 MNG_COMPOSE8 (*pScanline,     *(pDataline+2), iFGa8, *pScanline    );
4089                 MNG_COMPOSE8 (*(pScanline+1), *(pDataline+1), iFGa8, *(pScanline+1));
4090                 MNG_COMPOSE8 (*(pScanline+2), *pDataline,     iFGa8, *(pScanline+2));
4091                                        /* alpha remains fully opaque !!! */
4092               }
4093               else
4094               {                        /* now blend */
4095                 MNG_BLEND8 (*pDataline,     *(pDataline+1), *(pDataline+2), iFGa8,
4096                             *(pScanline+2), *(pScanline+1), *pScanline,     iBGa8,
4097                             iCr8, iCg8, iCb8, iCa8);
4098                                        /* and return the composed values */
4099                 *pScanline     = iCb8;
4100                 *(pScanline+1) = iCg8;
4101                 *(pScanline+2) = iCr8;
4102                 *(pScanline+3) = iCa8;
4103               }
4104             }
4105           }
4106 
4107           pScanline += (pData->iColinc << 2);
4108           pDataline += 4;
4109         }
4110       }
4111     }
4112   }
4113 
4114   check_update_region (pData);
4115 
4116 #ifdef MNG_SUPPORT_TRACE
4117   MNG_TRACE (pData, MNG_FN_DISPLAY_BGRA8, MNG_LC_END);
4118 #endif
4119 
4120   return MNG_NOERROR;
4121 }
4122 #else /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
mng_display_bgra8(mng_datap pData)4123 mng_retcode mng_display_bgra8 (mng_datap pData)
4124 {
4125   mng_uint8p pScanline;
4126   mng_uint8p pDataline;
4127   mng_int32  iX;
4128   mng_uint8  iFGa8, iBGa8, iCa8;
4129   mng_uint16 iFGa16, iBGa16, iCa16;
4130   mng_uint16 iFGg16;
4131   mng_uint16 iBGr16, iBGg16, iBGb16;
4132   mng_uint16 iCr16, iCg16, iCb16;
4133   mng_uint8  iCr8, iCg8, iCb8;
4134   mng_uint8  iBps;
4135 
4136 #ifdef MNG_SUPPORT_TRACE
4137   MNG_TRACE (pData, MNG_FN_DISPLAY_BGRA8, MNG_LC_START);
4138 #endif
4139 
4140   iBps=(mng_uint8)(pData->bIsRGBA16 ? 2:1);
4141                                        /* viewable row ? */
4142   if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
4143   {                                    /* address destination row */
4144     pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
4145                                                    pData->iRow + pData->iDestt -
4146                                                    pData->iSourcet);
4147                                        /* adjust destination row starting-point */
4148     pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
4149     pDataline = pData->pRGBArow;       /* address source row */
4150 
4151     /* adjust source row starting-point */
4152     pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << (iBps+1));
4153 
4154     if (pData->bIsOpaque)              /* forget about transparency ? */
4155     {
4156         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
4157              iX += pData->iColinc)
4158         {                              /* scale down by dropping the LSB */
4159           *pScanline     = *(pDataline+2*iBps);
4160           *(pScanline+1) = *(pDataline+iBps);
4161           *(pScanline+2) = *pDataline;
4162           *(pScanline+3) = *(pDataline+3*iBps);
4163 
4164           pScanline += (pData->iColinc << 2);
4165           pDataline += 4*iBps;
4166         }
4167     }
4168     else
4169     {
4170       if (pData->bIsRGBA16)            /* 16-bit input row ? */
4171       {
4172         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
4173              iX += pData->iColinc)
4174         {                              /* get alpha values */
4175           iFGa16 = mng_get_uint16 (pDataline+6);
4176           iBGa16 = (mng_uint16)(*(pScanline+3));
4177           iBGa16 = (mng_uint16)(iBGa16 << 8) | iBGa16;
4178 
4179           if (iFGa16)                  /* any opacity at all ? */
4180           {                            /* fully opaque or background fully transparent ? */
4181             if ((iFGa16 == 0xFFFF) || (iBGa16 == 0))
4182             {                          /* plain copy it */
4183               *pScanline     = *(pDataline+4);
4184               *(pScanline+1) = *(pDataline+2);
4185               *(pScanline+2) = *pDataline;
4186               *(pScanline+3) = *(pDataline+6);
4187             }
4188             else
4189             {
4190               if (iBGa16 == 0xFFFF)    /* background fully opaque ? */
4191               {                        /* get the proper values */
4192               int i;
4193               for (i=2; i >= 0; i--)
4194               {
4195                 iFGg16 = mng_get_uint16 (pDataline+i+i);
4196                                        /* scale background up */
4197                 iBGg16 = (mng_uint16)(*(pScanline+2-i));
4198                 iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
4199                                        /* now compose */
4200                 MNG_COMPOSE16(iFGg16, iFGg16, iFGa16, iBGg16);
4201                                        /* and return the composed values */
4202                 *(pScanline+2-i) = (mng_uint8)(iFGg16 >> 8);
4203                                        /* alpha remains fully opaque !!! */
4204               }
4205               }
4206               else
4207               {                        /* scale background up */
4208                 iBGr16 = (mng_uint16)(*(pScanline+2));
4209                 iBGg16 = (mng_uint16)(*(pScanline+1));
4210                 iBGb16 = (mng_uint16)(*pScanline    );
4211                 iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
4212                 iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
4213                 iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
4214                                        /* let's blend */
4215                 MNG_BLEND16 (mng_get_uint16 (pDataline  ),
4216                              mng_get_uint16 (pDataline+2),
4217                              mng_get_uint16 (pDataline+4), iFGa16,
4218                              iBGr16, iBGg16, iBGb16, iBGa16,
4219                              iCr16,  iCg16,  iCb16,  iCa16);
4220                                        /* and return the composed values */
4221                 *pScanline     = (mng_uint8)(iCb16 >> 8);
4222                 *(pScanline+1) = (mng_uint8)(iCg16 >> 8);
4223                 *(pScanline+2) = (mng_uint8)(iCr16 >> 8);
4224                 *(pScanline+3) = (mng_uint8)(iCa16 >> 8);
4225               }
4226             }
4227           }
4228 
4229           pScanline += (pData->iColinc << 2);
4230           pDataline += 8;
4231         }
4232       }
4233       else
4234       {
4235         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
4236              iX += pData->iColinc)
4237         {
4238           iFGa8 = *(pDataline+3);      /* get alpha values */
4239           iBGa8 = *(pScanline+3);
4240 
4241           if (iFGa8)                   /* any opacity at all ? */
4242           {                            /* fully opaque or background fully transparent ? */
4243             if ((iFGa8 == 0xFF) || (iBGa8 == 0))
4244             {                          /* then simply copy the values */
4245               *pScanline     = *(pDataline+2);
4246               *(pScanline+1) = *(pDataline+1);
4247               *(pScanline+2) = *pDataline;
4248               *(pScanline+3) = *(pDataline+3);
4249             }
4250             else
4251             {
4252               if (iBGa8 == 0xFF)       /* background fully opaque ? */
4253               {                        /* do alpha composing */
4254                 int i;
4255                 for (i=2; i >= 0; i--)
4256                 {
4257                 MNG_COMPOSE8 (*(pScanline+i), *(pDataline+2-i), iFGa8, *(pScanline+i));
4258                 }
4259                                        /* alpha remains fully opaque !!! */
4260               }
4261               else
4262               {                        /* now blend */
4263                 MNG_BLEND8 (*pDataline,     *(pDataline+1), *(pDataline+2), iFGa8,
4264                             *(pScanline+2), *(pScanline+1), *pScanline,     iBGa8,
4265                             iCr8, iCg8, iCb8, iCa8);
4266                                        /* and return the composed values */
4267                 *pScanline     = iCb8;
4268                 *(pScanline+1) = iCg8;
4269                 *(pScanline+2) = iCr8;
4270                 *(pScanline+3) = iCa8;
4271               }
4272             }
4273           }
4274 
4275           pScanline += (pData->iColinc << 2);
4276           pDataline += 4;
4277         }
4278       }
4279     }
4280   }
4281 
4282   check_update_region (pData);
4283 
4284 #ifdef MNG_SUPPORT_TRACE
4285   MNG_TRACE (pData, MNG_FN_DISPLAY_BGRA8, MNG_LC_END);
4286 #endif
4287 
4288   return MNG_NOERROR;
4289 }
4290 #endif /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
4291 #else /* MNG_NO_16BIT_SUPPORT */
mng_display_bgra8(mng_datap pData)4292 mng_retcode mng_display_bgra8 (mng_datap pData)
4293 {
4294   mng_uint8p pScanline;
4295   mng_uint8p pDataline;
4296   mng_int32  iX;
4297   mng_uint8  iFGa8, iBGa8, iCa8;
4298   mng_uint8  iCr8, iCg8, iCb8;
4299 
4300 #ifdef MNG_SUPPORT_TRACE
4301   MNG_TRACE (pData, MNG_FN_DISPLAY_BGRA8, MNG_LC_START);
4302 #endif
4303                                        /* viewable row ? */
4304   if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
4305   {                                    /* address destination row */
4306     pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
4307                                                    pData->iRow + pData->iDestt -
4308                                                    pData->iSourcet);
4309                                        /* adjust destination row starting-point */
4310     pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
4311     pDataline = pData->pRGBArow;       /* address source row */
4312 
4313       pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
4314 
4315     if (pData->bIsOpaque)              /* forget about transparency ? */
4316     {
4317       {
4318         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
4319              iX += pData->iColinc)
4320         {                              /* copy the values */
4321           *pScanline     = *(pDataline+2);
4322           *(pScanline+1) = *(pDataline+1);
4323           *(pScanline+2) = *pDataline;
4324           *(pScanline+3) = *(pDataline+3);
4325 
4326           pScanline += (pData->iColinc << 2);
4327           pDataline += 4;
4328         }
4329       }
4330     }
4331     else
4332     {
4333       {
4334         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
4335              iX += pData->iColinc)
4336         {
4337           iFGa8 = *(pDataline+3);      /* get alpha values */
4338           iBGa8 = *(pScanline+3);
4339 
4340           if (iFGa8)                   /* any opacity at all ? */
4341           {                            /* fully opaque or background fully transparent ? */
4342             if ((iFGa8 == 0xFF) || (iBGa8 == 0))
4343             {                          /* then simply copy the values */
4344               *pScanline     = *(pDataline+2);
4345               *(pScanline+1) = *(pDataline+1);
4346               *(pScanline+2) = *pDataline;
4347               *(pScanline+3) = *(pDataline+3);
4348             }
4349             else
4350             {
4351               if (iBGa8 == 0xFF)       /* background fully opaque ? */
4352               {                        /* do alpha composing */
4353 #ifdef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
4354                 int i;
4355                 for (i=2; i >= 0; i--)
4356                 {
4357                 MNG_COMPOSE8 (*(pScanline+i), *(pDataline+2-i), iFGa8, *(pScanline+i));
4358                 }
4359 #else
4360                 MNG_COMPOSE8 (*pScanline,     *(pDataline+2), iFGa8, *pScanline    );
4361                 MNG_COMPOSE8 (*(pScanline+1), *(pDataline+1), iFGa8, *(pScanline+1));
4362                 MNG_COMPOSE8 (*(pScanline+2), *pDataline,     iFGa8, *(pScanline+2));
4363 #endif
4364                                        /* alpha remains fully opaque !!! */
4365               }
4366               else
4367               {                        /* now blend */
4368                 MNG_BLEND8 (*pDataline,     *(pDataline+1), *(pDataline+2), iFGa8,
4369                             *(pScanline+2), *(pScanline+1), *pScanline,     iBGa8,
4370                             iCr8, iCg8, iCb8, iCa8);
4371                                        /* and return the composed values */
4372                 *pScanline     = iCb8;
4373                 *(pScanline+1) = iCg8;
4374                 *(pScanline+2) = iCr8;
4375                 *(pScanline+3) = iCa8;
4376               }
4377             }
4378           }
4379 
4380           pScanline += (pData->iColinc << 2);
4381           pDataline += 4;
4382         }
4383       }
4384     }
4385   }
4386 
4387   check_update_region (pData);
4388 
4389 #ifdef MNG_SUPPORT_TRACE
4390   MNG_TRACE (pData, MNG_FN_DISPLAY_BGRA8, MNG_LC_END);
4391 #endif
4392 
4393   return MNG_NOERROR;
4394 }
4395 #endif /* MNG_NO_16BIT_SUPPORT */
4396 #endif /* MNG_SKIPCANVAS_BGRA8 */
4397 
4398 /* ************************************************************************** */
4399 
4400 #ifndef MNG_SKIPCANVAS_BGRA8_PM
4401 #ifndef MNG_NO_16BIT_SUPPORT
4402 #ifndef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
mng_display_bgra8_pm(mng_datap pData)4403 mng_retcode mng_display_bgra8_pm (mng_datap pData)
4404 {
4405   mng_uint8p pScanline;
4406   mng_uint8p pDataline;
4407   mng_int32  iX;
4408   mng_uint32 s, t;
4409 
4410 #ifdef MNG_SUPPORT_TRACE
4411   MNG_TRACE (pData, MNG_FN_DISPLAY_BGRA8PM, MNG_LC_START);
4412 #endif
4413                                        /* viewable row ? */
4414   if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
4415   {                                    /* address destination row */
4416     pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
4417                                                    pData->iRow + pData->iDestt -
4418                                                    pData->iSourcet);
4419                                        /* adjust destination row starting-point */
4420     pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
4421     pDataline = pData->pRGBArow;       /* address source row */
4422 
4423     if (pData->bIsRGBA16)              /* adjust source row starting-point */
4424       pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 3);
4425     else
4426       pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
4427 
4428     if (pData->bIsOpaque)              /* forget about transparency ? */
4429     {
4430       if (pData->bIsRGBA16)            /* 16-bit input row ? */
4431       {
4432         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
4433              iX += pData->iColinc)
4434         {                              /* scale down by dropping the LSB */
4435           if ((s = pDataline[6]) == 0)
4436             *(mng_uint32*) pScanline = 0; /* set all components = 0 */
4437           else
4438           {
4439             if (s == 255)
4440             {
4441               pScanline[0] = pDataline[4];
4442               pScanline[1] = pDataline[2];
4443               pScanline[2] = pDataline[0];
4444               pScanline[3] = 255;
4445             }
4446             else
4447             {
4448               pScanline[0] = DIV255B8(s * pDataline[4]);
4449               pScanline[1] = DIV255B8(s * pDataline[2]);
4450               pScanline[2] = DIV255B8(s * pDataline[0]);
4451               pScanline[3] = (mng_uint8)s;
4452             }
4453           }
4454           pScanline += (pData->iColinc << 2);
4455           pDataline += 8;
4456         }
4457       }
4458       else
4459       {
4460         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
4461              iX += pData->iColinc)
4462         {                              /* copy the values and premultiply */
4463           if ((s = pDataline[3]) == 0)
4464             *(mng_uint32*) pScanline = 0; /* set all components = 0 */
4465           else
4466           {
4467             if (s == 255)
4468             {
4469               pScanline[0] = pDataline[2];
4470               pScanline[1] = pDataline[1];
4471               pScanline[2] = pDataline[0];
4472               pScanline[3] = 255;
4473             }
4474             else
4475             {
4476               pScanline[0] = DIV255B8(s * pDataline[2]);
4477               pScanline[1] = DIV255B8(s * pDataline[1]);
4478               pScanline[2] = DIV255B8(s * pDataline[0]);
4479               pScanline[3] = (mng_uint8)s;
4480             }
4481           }
4482 
4483           pScanline += (pData->iColinc << 2);
4484           pDataline += 4;
4485         }
4486       }
4487     }
4488     else
4489     {
4490       if (pData->bIsRGBA16)            /* 16-bit input row ? */
4491       {
4492         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
4493              iX += pData->iColinc)
4494         {                              /* get alpha values */
4495           if ((s = pDataline[6]) != 0)       /* any opacity at all ? */
4496           {                            /* fully opaque or background fully transparent ? */
4497             if (s == 255)
4498             {                          /* plain copy it */
4499               pScanline[0] = pDataline[4];
4500               pScanline[1] = pDataline[2];
4501               pScanline[2] = pDataline[0];
4502               pScanline[3] = 255;
4503             }
4504             else
4505             {                          /* now blend (premultiplied) */
4506               t = 255 - s;
4507 #ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
4508               {
4509                 int i;
4510                 for (i=2; i >= 0; i--)
4511                 {
4512                   pScanline[i] = DIV255B8(s * pDataline[4-i-i] + t *
4513                      pScanline[i]);
4514                 }
4515               }
4516 #else
4517               pScanline[0] = DIV255B8(s * pDataline[4] + t * pScanline[0]);
4518               pScanline[1] = DIV255B8(s * pDataline[2] + t * pScanline[1]);
4519               pScanline[2] = DIV255B8(s * pDataline[0] + t * pScanline[2]);
4520 #endif
4521               pScanline[3] = (mng_uint8)(255 - DIV255B8(t * (255 - pScanline[3])));
4522             }
4523           }
4524 
4525           pScanline += (pData->iColinc << 2);
4526           pDataline += 8;
4527         }
4528       }
4529       else
4530       {
4531         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
4532              iX += pData->iColinc)
4533         {
4534           if ((s = pDataline[3]) != 0)       /* any opacity at all ? */
4535           {                            /* fully opaque ? */
4536             if (s == 255)
4537             {                          /* then simply copy the values */
4538               pScanline[0] = pDataline[2];
4539               pScanline[1] = pDataline[1];
4540               pScanline[2] = pDataline[0];
4541               pScanline[3] = 255;
4542             }
4543             else
4544             {                          /* now blend (premultiplied) */
4545               t = 255 - s;
4546 #ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
4547               {
4548                 int i;
4549                 for (i=2; i >= 0; i--)
4550                 {
4551                   pScanline[i] = DIV255B8(s * pDataline[2-i] + t *
4552                      pScanline[i]);
4553                 }
4554               }
4555 #else
4556               pScanline[0] = DIV255B8(s * pDataline[2] + t * pScanline[0]);
4557               pScanline[1] = DIV255B8(s * pDataline[1] + t * pScanline[1]);
4558               pScanline[2] = DIV255B8(s * pDataline[0] + t * pScanline[2]);
4559 #endif
4560               pScanline[3] = (mng_uint8)(255 - DIV255B8(t * (255 - pScanline[3])));
4561             }
4562           }
4563 
4564           pScanline += (pData->iColinc << 2);
4565           pDataline += 4;
4566         }
4567       }
4568     }
4569   }
4570 
4571   check_update_region (pData);
4572 
4573 #ifdef MNG_SUPPORT_TRACE
4574   MNG_TRACE (pData, MNG_FN_DISPLAY_BGRA8PM, MNG_LC_END);
4575 #endif
4576 
4577   return MNG_NOERROR;
4578 }
4579 #else /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
mng_display_bgra8_pm(mng_datap pData)4580 mng_retcode mng_display_bgra8_pm (mng_datap pData)
4581 {
4582   mng_uint8p pScanline;
4583   mng_uint8p pDataline;
4584   mng_int32  iX;
4585   mng_uint32 s, t;
4586   mng_uint8  iBps;
4587 
4588 #ifdef MNG_SUPPORT_TRACE
4589   MNG_TRACE (pData, MNG_FN_DISPLAY_BGRA8PM, MNG_LC_START);
4590 #endif
4591 
4592   iBps=(mng_uint8)(pData->bIsRGBA16 ? 2:1);
4593                                        /* viewable row ? */
4594   if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
4595   {                                    /* address destination row */
4596     pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
4597                                                    pData->iRow + pData->iDestt -
4598                                                    pData->iSourcet);
4599                                        /* adjust destination row starting-point */
4600     pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
4601     pDataline = pData->pRGBArow;       /* address source row */
4602 
4603     /* adjust source row starting-point */
4604     pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << (iBps+1));
4605 
4606     if (pData->bIsOpaque)              /* forget about transparency ? */
4607     {
4608       if (pData->bIsRGBA16)            /* 16-bit input row ? */
4609       {
4610         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
4611              iX += pData->iColinc)
4612         {                              /* scale down by dropping the LSB */
4613           if ((s = pDataline[6]) == 0)
4614             *(mng_uint32*) pScanline = 0; /* set all components = 0 */
4615           else
4616           {
4617             if (s == 255)
4618             {
4619               pScanline[0] = pDataline[4];
4620               pScanline[1] = pDataline[2];
4621               pScanline[2] = pDataline[0];
4622               pScanline[3] = 255;
4623             }
4624             else
4625             {
4626 #ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
4627               int i;
4628               for (i=2; i >= 0; i--)
4629               {
4630                 pScanline[i] = DIV255B8(s * pDataline[4-i-i]);
4631               }
4632 #else
4633               pScanline[0] = DIV255B8(s * pDataline[4]);
4634               pScanline[1] = DIV255B8(s * pDataline[2]);
4635               pScanline[2] = DIV255B8(s * pDataline[0]);
4636 #endif
4637               pScanline[3] = (mng_uint8)s;
4638             }
4639           }
4640           pScanline += (pData->iColinc << 2);
4641           pDataline += 8;
4642         }
4643       }
4644       else
4645       {
4646         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
4647              iX += pData->iColinc)
4648         {                              /* copy the values and premultiply */
4649           if ((s = pDataline[3]) == 0)
4650             *(mng_uint32*) pScanline = 0; /* set all components = 0 */
4651           else
4652           {
4653             if (s == 255)
4654             {
4655               pScanline[0] = pDataline[2];
4656               pScanline[1] = pDataline[1];
4657               pScanline[2] = pDataline[0];
4658               pScanline[3] = 255;
4659             }
4660             else
4661             {
4662 #ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
4663               int i;
4664               for (i=2; i >= 0; i--)
4665               {
4666                 pScanline[i] = DIV255B8(s * pDataline[2-i]);
4667               }
4668 #else
4669               pScanline[0] = DIV255B8(s * pDataline[2]);
4670               pScanline[1] = DIV255B8(s * pDataline[1]);
4671               pScanline[2] = DIV255B8(s * pDataline[0]);
4672 #endif
4673               pScanline[3] = (mng_uint8)s;
4674             }
4675           }
4676 
4677           pScanline += (pData->iColinc << 2);
4678           pDataline += 4;
4679         }
4680       }
4681     }
4682     else
4683     {
4684       if (pData->bIsRGBA16)            /* 16-bit input row ? */
4685       {
4686         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
4687              iX += pData->iColinc)
4688         {                              /* get alpha values */
4689           if ((s = pDataline[6]) != 0)       /* any opacity at all ? */
4690           {                            /* fully opaque or background fully transparent ? */
4691             if (s == 255)
4692             {                          /* plain copy it */
4693               pScanline[0] = pDataline[4];
4694               pScanline[1] = pDataline[2];
4695               pScanline[2] = pDataline[0];
4696               pScanline[3] = 255;
4697             }
4698             else
4699             {                          /* now blend (premultiplied) */
4700               t = 255 - s;
4701 #ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
4702               {
4703                 int i;
4704                 for (i=2; i >= 0; i--)
4705                 {
4706                   pScanline[i] = DIV255B8(s * pDataline[4-i-i] + t *
4707                      pScanline[i]);
4708                 }
4709               }
4710 #else
4711               pScanline[0] = DIV255B8(s * pDataline[4] + t * pScanline[0]);
4712               pScanline[1] = DIV255B8(s * pDataline[2] + t * pScanline[1]);
4713               pScanline[2] = DIV255B8(s * pDataline[0] + t * pScanline[2]);
4714 #endif
4715               pScanline[3] = (mng_uint8)(255 - DIV255B8(t * (255 - pScanline[3])));
4716             }
4717           }
4718 
4719           pScanline += (pData->iColinc << 2);
4720           pDataline += 8;
4721         }
4722       }
4723       else
4724       {
4725         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
4726              iX += pData->iColinc)
4727         {
4728           if ((s = pDataline[3]) != 0)       /* any opacity at all ? */
4729           {                            /* fully opaque ? */
4730             if (s == 255)
4731             {                          /* then simply copy the values */
4732               pScanline[0] = pDataline[2];
4733               pScanline[1] = pDataline[1];
4734               pScanline[2] = pDataline[0];
4735               pScanline[3] = 255;
4736             }
4737             else
4738             {                          /* now blend (premultiplied) */
4739               t = 255 - s;
4740 #ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
4741               {
4742                 int i;
4743                 for (i=2; i >= 0; i--)
4744                 {
4745                   pScanline[i] = DIV255B8(s * pDataline[2-i] + t *
4746                      pScanline[i]);
4747                 }
4748               }
4749 #else
4750               pScanline[0] = DIV255B8(s * pDataline[2] + t * pScanline[0]);
4751               pScanline[1] = DIV255B8(s * pDataline[1] + t * pScanline[1]);
4752               pScanline[2] = DIV255B8(s * pDataline[0] + t * pScanline[2]);
4753 #endif
4754               pScanline[3] = (mng_uint8)(255 - DIV255B8(t * (255 - pScanline[3])));
4755             }
4756           }
4757 
4758           pScanline += (pData->iColinc << 2);
4759           pDataline += 4;
4760         }
4761       }
4762     }
4763   }
4764 
4765   check_update_region (pData);
4766 
4767 #ifdef MNG_SUPPORT_TRACE
4768   MNG_TRACE (pData, MNG_FN_DISPLAY_BGRA8PM, MNG_LC_END);
4769 #endif
4770 
4771   return MNG_NOERROR;
4772 }
4773 #endif /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
4774 #else /* MNG_NO_16BIT_SUPPORT */
mng_display_bgra8_pm(mng_datap pData)4775 mng_retcode mng_display_bgra8_pm (mng_datap pData)
4776 {
4777   mng_uint8p pScanline;
4778   mng_uint8p pDataline;
4779   mng_int32  iX;
4780   mng_uint32 s, t;
4781 
4782 #ifdef MNG_SUPPORT_TRACE
4783   MNG_TRACE (pData, MNG_FN_DISPLAY_BGRA8PM, MNG_LC_START);
4784 #endif
4785                                        /* viewable row ? */
4786   if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
4787   {                                    /* address destination row */
4788     pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
4789                                                    pData->iRow + pData->iDestt -
4790                                                    pData->iSourcet);
4791                                        /* adjust destination row starting-point */
4792     pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
4793     pDataline = pData->pRGBArow;       /* address source row */
4794 
4795       pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
4796 
4797     if (pData->bIsOpaque)              /* forget about transparency ? */
4798     {
4799       {
4800         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
4801              iX += pData->iColinc)
4802         {                              /* copy the values and premultiply */
4803           if ((s = pDataline[3]) == 0)
4804             *(mng_uint32*) pScanline = 0; /* set all components = 0 */
4805           else
4806           {
4807             if (s == 255)
4808             {
4809               pScanline[0] = pDataline[2];
4810               pScanline[1] = pDataline[1];
4811               pScanline[2] = pDataline[0];
4812               pScanline[3] = 255;
4813             }
4814             else
4815             {
4816 #ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
4817               int i;
4818               for (i=2; i >= 0; i--)
4819               {
4820                 pScanline[i] = DIV255B8(s * pDataline[2-i]);
4821               }
4822 #else
4823               pScanline[0] = DIV255B8(s * pDataline[2]);
4824               pScanline[1] = DIV255B8(s * pDataline[1]);
4825               pScanline[2] = DIV255B8(s * pDataline[0]);
4826 #endif
4827               pScanline[3] = (mng_uint8)s;
4828             }
4829           }
4830 
4831           pScanline += (pData->iColinc << 2);
4832           pDataline += 4;
4833         }
4834       }
4835     }
4836     else
4837     {
4838       {
4839         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
4840              iX += pData->iColinc)
4841         {
4842           if ((s = pDataline[3]) != 0)       /* any opacity at all ? */
4843           {                            /* fully opaque ? */
4844             if (s == 255)
4845             {                          /* then simply copy the values */
4846               pScanline[0] = pDataline[2];
4847               pScanline[1] = pDataline[1];
4848               pScanline[2] = pDataline[0];
4849               pScanline[3] = 255;
4850             }
4851             else
4852             {                          /* now blend (premultiplied) */
4853               t = 255 - s;
4854 #ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
4855               {
4856                 int i;
4857                 for (i=2; i >= 0; i--)
4858                 {
4859                   pScanline[i] = DIV255B8(s * pDataline[2-i] + t *
4860                      pScanline[i]);
4861                 }
4862               }
4863 #else
4864               pScanline[0] = DIV255B8(s * pDataline[2] + t * pScanline[0]);
4865               pScanline[1] = DIV255B8(s * pDataline[1] + t * pScanline[1]);
4866               pScanline[2] = DIV255B8(s * pDataline[0] + t * pScanline[2]);
4867 #endif
4868               pScanline[3] = (mng_uint8)(255 - DIV255B8(t * (255 - pScanline[3])));
4869             }
4870           }
4871 
4872           pScanline += (pData->iColinc << 2);
4873           pDataline += 4;
4874         }
4875       }
4876     }
4877   }
4878 
4879   check_update_region (pData);
4880 
4881 #ifdef MNG_SUPPORT_TRACE
4882   MNG_TRACE (pData, MNG_FN_DISPLAY_BGRA8PM, MNG_LC_END);
4883 #endif
4884 
4885   return MNG_NOERROR;
4886 }
4887 #endif /* MNG_NO_16BIT_SUPPORT */
4888 #endif /* MNG_SKIPCANVAS_BGRA8_PM */
4889 
4890 /* ************************************************************************** */
4891 
4892 #ifndef MNG_SKIPCANVAS_ABGR8
4893 #ifndef MNG_NO_16BIT_SUPPORT
4894 #ifndef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
mng_display_abgr8(mng_datap pData)4895 mng_retcode mng_display_abgr8 (mng_datap pData)
4896 {
4897   mng_uint8p pScanline;
4898   mng_uint8p pDataline;
4899   mng_int32  iX;
4900   mng_uint8  iFGa8, iBGa8, iCa8;
4901   mng_uint16 iFGa16, iBGa16, iCa16;
4902   mng_uint16 iFGr16, iFGg16, iFGb16;
4903   mng_uint16 iBGr16, iBGg16, iBGb16;
4904   mng_uint16 iCr16, iCg16, iCb16;
4905   mng_uint8  iCr8, iCg8, iCb8;
4906 
4907 #ifdef MNG_SUPPORT_TRACE
4908   MNG_TRACE (pData, MNG_FN_DISPLAY_ABGR8, MNG_LC_START);
4909 #endif
4910                                        /* viewable row ? */
4911   if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
4912   {                                    /* address destination row */
4913     pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
4914                                                    pData->iRow + pData->iDestt -
4915                                                    pData->iSourcet);
4916                                        /* adjust destination row starting-point */
4917     pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
4918     pDataline = pData->pRGBArow;       /* address source row */
4919 
4920     if (pData->bIsRGBA16)              /* adjust source row starting-point */
4921       pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 3);
4922     else
4923       pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
4924 
4925     if (pData->bIsOpaque)              /* forget about transparency ? */
4926     {
4927       if (pData->bIsRGBA16)            /* 16-bit input row ? */
4928       {
4929         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
4930              iX += pData->iColinc)
4931         {                              /* scale down by dropping the LSB */
4932           *pScanline     = *(pDataline+6);
4933           *(pScanline+1) = *(pDataline+4);
4934           *(pScanline+2) = *(pDataline+2);
4935           *(pScanline+3) = *pDataline;
4936 
4937           pScanline += (pData->iColinc << 2);
4938           pDataline += 8;
4939         }
4940       }
4941       else
4942       {
4943         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
4944              iX += pData->iColinc)
4945         {                              /* copy the values */
4946           *pScanline     = *(pDataline+3);
4947           *(pScanline+1) = *(pDataline+2);
4948           *(pScanline+2) = *(pDataline+1);
4949           *(pScanline+3) = *pDataline;
4950 
4951           pScanline += (pData->iColinc << 2);
4952           pDataline += 4;
4953         }
4954       }
4955     }
4956     else
4957     {
4958       if (pData->bIsRGBA16)            /* 16-bit input row ? */
4959       {
4960         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
4961              iX += pData->iColinc)
4962         {                              /* get alpha values */
4963           iFGa16 = mng_get_uint16 (pDataline+6);
4964           iBGa16 = (mng_uint16)(*pScanline);
4965           iBGa16 = (mng_uint16)(iBGa16 << 8) | iBGa16;
4966 
4967           if (iFGa16)                  /* any opacity at all ? */
4968           {                            /* fully opaque or background fully transparent ? */
4969             if ((iFGa16 == 0xFFFF) || (iBGa16 == 0))
4970             {                          /* plain copy it */
4971               *pScanline     = *(pDataline+6);
4972               *(pScanline+1) = *(pDataline+4);
4973               *(pScanline+2) = *(pDataline+2);
4974               *(pScanline+3) = *pDataline;
4975             }
4976             else
4977             {
4978               if (iBGa16 == 0xFFFF)    /* background fully opaque ? */
4979               {                        /* get the proper values */
4980                 iFGr16 = mng_get_uint16 (pDataline  );
4981                 iFGg16 = mng_get_uint16 (pDataline+2);
4982                 iFGb16 = mng_get_uint16 (pDataline+4);
4983                                        /* scale background up */
4984                 iBGr16 = (mng_uint16)(*(pScanline+3));
4985                 iBGg16 = (mng_uint16)(*(pScanline+2));
4986                 iBGb16 = (mng_uint16)(*(pScanline+1));
4987                 iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
4988                 iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
4989                 iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
4990                                        /* now compose */
4991                 MNG_COMPOSE16(iFGr16, iFGr16, iFGa16, iBGr16);
4992                 MNG_COMPOSE16(iFGg16, iFGg16, iFGa16, iBGg16);
4993                 MNG_COMPOSE16(iFGb16, iFGb16, iFGa16, iBGb16);
4994                                        /* and return the composed values */
4995                                        /* alpha itself remains fully opaque !!! */
4996                 *(pScanline+1) = (mng_uint8)(iFGb16 >> 8);
4997                 *(pScanline+2) = (mng_uint8)(iFGg16 >> 8);
4998                 *(pScanline+3) = (mng_uint8)(iFGr16 >> 8);
4999               }
5000               else
5001               {                        /* scale background up */
5002                 iBGr16 = (mng_uint16)(*(pScanline+3));
5003                 iBGg16 = (mng_uint16)(*(pScanline+2));
5004                 iBGb16 = (mng_uint16)(*(pScanline+1));
5005                 iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
5006                 iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
5007                 iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
5008                                        /* let's blend */
5009                 MNG_BLEND16 (mng_get_uint16 (pDataline  ),
5010                              mng_get_uint16 (pDataline+2),
5011                              mng_get_uint16 (pDataline+4), iFGa16,
5012                              iBGr16, iBGg16, iBGb16, iBGa16,
5013                              iCr16,  iCg16,  iCb16,  iCa16);
5014                                        /* and return the composed values */
5015                 *pScanline     = (mng_uint8)(iCa16 >> 8);
5016                 *(pScanline+1) = (mng_uint8)(iCb16 >> 8);
5017                 *(pScanline+2) = (mng_uint8)(iCg16 >> 8);
5018                 *(pScanline+3) = (mng_uint8)(iCr16 >> 8);
5019               }
5020             }
5021           }
5022 
5023           pScanline += (pData->iColinc << 2);
5024           pDataline += 8;
5025         }
5026       }
5027       else
5028       {
5029         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
5030              iX += pData->iColinc)
5031         {
5032           iFGa8 = *(pDataline+3);      /* get alpha values */
5033           iBGa8 = *pScanline;
5034 
5035           if (iFGa8)                   /* any opacity at all ? */
5036           {                            /* fully opaque or background fully transparent ? */
5037             if ((iFGa8 == 0xFF) || (iBGa8 == 0))
5038             {                          /* then simply copy the values */
5039               *pScanline     = *(pDataline+3);
5040               *(pScanline+1) = *(pDataline+2);
5041               *(pScanline+2) = *(pDataline+1);
5042               *(pScanline+3) = *pDataline;
5043             }
5044             else
5045             {
5046               if (iBGa8 == 0xFF)       /* background fully opaque ? */
5047               {                        /* do simple alpha composing */
5048                                        /* alpha itself remains fully opaque !!! */
5049                 MNG_COMPOSE8 (*(pScanline+1), *(pDataline+2), iFGa8, *(pScanline+1));
5050                 MNG_COMPOSE8 (*(pScanline+2), *(pDataline+1), iFGa8, *(pScanline+2));
5051                 MNG_COMPOSE8 (*(pScanline+3), *pDataline,     iFGa8, *(pScanline+3));
5052               }
5053               else
5054               {                        /* now blend */
5055                 MNG_BLEND8 (*pDataline,     *(pDataline+1), *(pDataline+2), iFGa8,
5056                             *(pScanline+3), *(pScanline+2), *(pScanline+1), iBGa8,
5057                             iCr8, iCg8, iCb8, iCa8);
5058                                        /* and return the composed values */
5059                 *pScanline     = iCa8;
5060                 *(pScanline+1) = iCb8;
5061                 *(pScanline+2) = iCg8;
5062                 *(pScanline+3) = iCr8;
5063               }
5064             }
5065           }
5066 
5067           pScanline += (pData->iColinc << 2);
5068           pDataline += 4;
5069         }
5070       }
5071     }
5072   }
5073 
5074   check_update_region (pData);
5075 
5076 #ifdef MNG_SUPPORT_TRACE
5077   MNG_TRACE (pData, MNG_FN_DISPLAY_ABGR8, MNG_LC_END);
5078 #endif
5079 
5080   return MNG_NOERROR;
5081 }
5082 #else /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
mng_display_abgr8(mng_datap pData)5083 mng_retcode mng_display_abgr8 (mng_datap pData)
5084 {
5085   mng_uint8p pScanline;
5086   mng_uint8p pDataline;
5087   mng_int32  iX;
5088   mng_uint8  iFGa8, iBGa8, iCa8;
5089   mng_uint16 iFGa16, iBGa16, iCa16;
5090   mng_uint16 iFGg16;
5091   mng_uint16 iBGr16, iBGg16, iBGb16;
5092   mng_uint16 iCr16, iCg16, iCb16;
5093   mng_uint8  iCr8, iCg8, iCb8;
5094   mng_uint8  iBps;
5095 
5096 #ifdef MNG_SUPPORT_TRACE
5097   MNG_TRACE (pData, MNG_FN_DISPLAY_ABGR8, MNG_LC_START);
5098 #endif
5099 
5100   iBps=(mng_uint8)(pData->bIsRGBA16 ? 2:1);
5101                                        /* viewable row ? */
5102   if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
5103   {                                    /* address destination row */
5104     pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
5105                                                    pData->iRow + pData->iDestt -
5106                                                    pData->iSourcet);
5107                                        /* adjust destination row starting-point */
5108     pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
5109     pDataline = pData->pRGBArow;       /* address source row */
5110 
5111     /* adjust source row starting-point */
5112     pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << (iBps+1));
5113 
5114     if (pData->bIsOpaque)              /* forget about transparency ? */
5115     {
5116         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
5117              iX += pData->iColinc)
5118         {                              /* scale down by dropping the LSB */
5119           *pScanline     = *(pDataline+3*iBps);
5120           *(pScanline+1) = *(pDataline+2*iBps);
5121           *(pScanline+2) = *(pDataline+iBps);
5122           *(pScanline+3) = *pDataline;
5123 
5124           pScanline += (pData->iColinc << 2);
5125           pDataline += 4*iBps;
5126         }
5127     }
5128     else
5129     {
5130       if (pData->bIsRGBA16)            /* 16-bit input row ? */
5131       {
5132         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
5133              iX += pData->iColinc)
5134         {                              /* get alpha values */
5135           iFGa16 = mng_get_uint16 (pDataline+6);
5136           iBGa16 = (mng_uint16)(*pScanline);
5137           iBGa16 = (mng_uint16)(iBGa16 << 8) | iBGa16;
5138 
5139           if (iFGa16)                  /* any opacity at all ? */
5140           {                            /* fully opaque or background fully transparent ? */
5141             if ((iFGa16 == 0xFFFF) || (iBGa16 == 0))
5142             {                          /* plain copy it */
5143               *pScanline     = *(pDataline+6);
5144               *(pScanline+1) = *(pDataline+4);
5145               *(pScanline+2) = *(pDataline+2);
5146               *(pScanline+3) = *pDataline;
5147             }
5148             else
5149             {
5150               if (iBGa16 == 0xFFFF)    /* background fully opaque ? */
5151               {                        /* get the proper values */
5152               int i;
5153               for (i=2; i >= 0; i--)
5154               {
5155                 iFGg16 = mng_get_uint16 (pDataline+i+i);
5156                                        /* scale background up */
5157                 iBGg16 = (mng_uint16)(*(pScanline+3-i));
5158                 iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
5159                                        /* now compose */
5160                 MNG_COMPOSE16(iFGg16, iFGg16, iFGa16, iBGg16);
5161                                        /* and return the composed values */
5162                                        /* alpha itself remains fully opaque !!! */
5163                 *(pScanline+3-i) = (mng_uint8)(iFGg16 >> 8);
5164               }
5165               }
5166               else
5167               {                        /* scale background up */
5168                 iBGr16 = (mng_uint16)(*(pScanline+3));
5169                 iBGg16 = (mng_uint16)(*(pScanline+2));
5170                 iBGb16 = (mng_uint16)(*(pScanline+1));
5171                 iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
5172                 iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
5173                 iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
5174                                        /* let's blend */
5175                 MNG_BLEND16 (mng_get_uint16 (pDataline  ),
5176                              mng_get_uint16 (pDataline+2),
5177                              mng_get_uint16 (pDataline+4), iFGa16,
5178                              iBGr16, iBGg16, iBGb16, iBGa16,
5179                              iCr16,  iCg16,  iCb16,  iCa16);
5180                                        /* and return the composed values */
5181                 *pScanline     = (mng_uint8)(iCa16 >> 8);
5182                 *(pScanline+1) = (mng_uint8)(iCb16 >> 8);
5183                 *(pScanline+2) = (mng_uint8)(iCg16 >> 8);
5184                 *(pScanline+3) = (mng_uint8)(iCr16 >> 8);
5185               }
5186             }
5187           }
5188 
5189           pScanline += (pData->iColinc << 2);
5190           pDataline += 8;
5191         }
5192       }
5193       else
5194       {
5195         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
5196              iX += pData->iColinc)
5197         {
5198           iFGa8 = *(pDataline+3);      /* get alpha values */
5199           iBGa8 = *pScanline;
5200 
5201           if (iFGa8)                   /* any opacity at all ? */
5202           {                            /* fully opaque or background fully transparent ? */
5203             if ((iFGa8 == 0xFF) || (iBGa8 == 0))
5204             {                          /* then simply copy the values */
5205               *pScanline     = *(pDataline+3);
5206               *(pScanline+1) = *(pDataline+2);
5207               *(pScanline+2) = *(pDataline+1);
5208               *(pScanline+3) = *pDataline;
5209             }
5210             else
5211             {
5212               if (iBGa8 == 0xFF)       /* background fully opaque ? */
5213               {                        /* do simple alpha composing */
5214                                        /* alpha itself remains fully opaque !!! */
5215                 int i;
5216                 for (i=2; i >= 0; i--)
5217                 {
5218                 MNG_COMPOSE8 (*(pScanline+i+1), *(pDataline+2-i), iFGa8, *(pScanline+i+1));
5219                 }
5220               }
5221               else
5222               {                        /* now blend */
5223                 MNG_BLEND8 (*pDataline,     *(pDataline+1), *(pDataline+2), iFGa8,
5224                             *(pScanline+3), *(pScanline+2), *(pScanline+1), iBGa8,
5225                             iCr8, iCg8, iCb8, iCa8);
5226                                        /* and return the composed values */
5227                 *pScanline     = iCa8;
5228                 *(pScanline+1) = iCb8;
5229                 *(pScanline+2) = iCg8;
5230                 *(pScanline+3) = iCr8;
5231               }
5232             }
5233           }
5234 
5235           pScanline += (pData->iColinc << 2);
5236           pDataline += 4;
5237         }
5238       }
5239     }
5240   }
5241 
5242   check_update_region (pData);
5243 
5244 #ifdef MNG_SUPPORT_TRACE
5245   MNG_TRACE (pData, MNG_FN_DISPLAY_ABGR8, MNG_LC_END);
5246 #endif
5247 
5248   return MNG_NOERROR;
5249 }
5250 #endif /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
5251 #else /* MNG_NO_16BIT_SUPPORT */
mng_display_abgr8(mng_datap pData)5252 mng_retcode mng_display_abgr8 (mng_datap pData)
5253 {
5254   mng_uint8p pScanline;
5255   mng_uint8p pDataline;
5256   mng_int32  iX;
5257   mng_uint8  iFGa8, iBGa8, iCa8;
5258   mng_uint8  iCr8, iCg8, iCb8;
5259 
5260 #ifdef MNG_SUPPORT_TRACE
5261   MNG_TRACE (pData, MNG_FN_DISPLAY_ABGR8, MNG_LC_START);
5262 #endif
5263                                        /* viewable row ? */
5264   if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
5265   {                                    /* address destination row */
5266     pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
5267                                                    pData->iRow + pData->iDestt -
5268                                                    pData->iSourcet);
5269                                        /* adjust destination row starting-point */
5270     pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
5271     pDataline = pData->pRGBArow;       /* address source row */
5272 
5273       pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
5274 
5275     if (pData->bIsOpaque)              /* forget about transparency ? */
5276     {
5277       {
5278         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
5279              iX += pData->iColinc)
5280         {                              /* copy the values */
5281           *pScanline     = *(pDataline+3);
5282           *(pScanline+1) = *(pDataline+2);
5283           *(pScanline+2) = *(pDataline+1);
5284           *(pScanline+3) = *pDataline;
5285 
5286           pScanline += (pData->iColinc << 2);
5287           pDataline += 4;
5288         }
5289       }
5290     }
5291     else
5292     {
5293       {
5294         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
5295              iX += pData->iColinc)
5296         {
5297           iFGa8 = *(pDataline+3);      /* get alpha values */
5298           iBGa8 = *pScanline;
5299 
5300           if (iFGa8)                   /* any opacity at all ? */
5301           {                            /* fully opaque or background fully transparent ? */
5302             if ((iFGa8 == 0xFF) || (iBGa8 == 0))
5303             {                          /* then simply copy the values */
5304               *pScanline     = *(pDataline+3);
5305               *(pScanline+1) = *(pDataline+2);
5306               *(pScanline+2) = *(pDataline+1);
5307               *(pScanline+3) = *pDataline;
5308             }
5309             else
5310             {
5311               if (iBGa8 == 0xFF)       /* background fully opaque ? */
5312               {                        /* do simple alpha composing */
5313                                        /* alpha itself remains fully opaque !!! */
5314 #ifdef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
5315                 int i;
5316                 for (i=2; i >= 0; i--)
5317                 {
5318                 MNG_COMPOSE8 (*(pScanline+i+1), *(pDataline+2-i), iFGa8, *(pScanline+i+1));
5319                 }
5320 #else
5321                 MNG_COMPOSE8 (*(pScanline+1), *(pDataline+2), iFGa8, *(pScanline+1));
5322                 MNG_COMPOSE8 (*(pScanline+2), *(pDataline+1), iFGa8, *(pScanline+2));
5323                 MNG_COMPOSE8 (*(pScanline+3), *pDataline,     iFGa8, *(pScanline+3));
5324 #endif
5325               }
5326               else
5327               {                        /* now blend */
5328                 MNG_BLEND8 (*pDataline,     *(pDataline+1), *(pDataline+2), iFGa8,
5329                             *(pScanline+3), *(pScanline+2), *(pScanline+1), iBGa8,
5330                             iCr8, iCg8, iCb8, iCa8);
5331                                        /* and return the composed values */
5332                 *pScanline     = iCa8;
5333                 *(pScanline+1) = iCb8;
5334                 *(pScanline+2) = iCg8;
5335                 *(pScanline+3) = iCr8;
5336               }
5337             }
5338           }
5339 
5340           pScanline += (pData->iColinc << 2);
5341           pDataline += 4;
5342         }
5343       }
5344     }
5345   }
5346 
5347   check_update_region (pData);
5348 
5349 #ifdef MNG_SUPPORT_TRACE
5350   MNG_TRACE (pData, MNG_FN_DISPLAY_ABGR8, MNG_LC_END);
5351 #endif
5352 
5353   return MNG_NOERROR;
5354 }
5355 #endif /* MNG_NO_16BIT_SUPPORT */
5356 #endif /* MNG_SKIPCANVAS_ABGR8 */
5357 
5358 /* ************************************************************************** */
5359 
5360 #ifndef MNG_SKIPCANVAS_ABGR8_PM
5361 #ifndef MNG_NO_16BIT_SUPPORT
5362 #ifndef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
mng_display_abgr8_pm(mng_datap pData)5363 mng_retcode mng_display_abgr8_pm (mng_datap pData)
5364 {
5365   mng_uint8p pScanline;
5366   mng_uint8p pDataline;
5367   mng_int32  iX;
5368   mng_uint32 s, t;
5369 
5370 #ifdef MNG_SUPPORT_TRACE
5371   MNG_TRACE (pData, MNG_FN_DISPLAY_ABGR8_PM, MNG_LC_START);
5372 #endif
5373                                        /* viewable row ? */
5374   if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
5375   {                                    /* address destination row */
5376     pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
5377                                                    pData->iRow + pData->iDestt -
5378                                                    pData->iSourcet);
5379                                        /* adjust destination row starting-point */
5380     pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
5381     pDataline = pData->pRGBArow;       /* address source row */
5382 
5383     if (pData->bIsRGBA16)              /* adjust source row starting-point */
5384       pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 3);
5385     else
5386       pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
5387 
5388     if (pData->bIsOpaque)              /* forget about transparency ? */
5389     {
5390       if (pData->bIsRGBA16)            /* 16-bit input row ? */
5391       {
5392         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
5393              iX += pData->iColinc)
5394         {                              /* scale down by dropping the LSB */
5395 		  if ((s = pDataline[6]) == 0)
5396 			*(mng_uint32*) pScanline = 0; /* set all components = 0 */
5397 		  else
5398 		  {
5399 			if (s == 255)
5400 			{
5401               pScanline[0] = 255;
5402 		      pScanline[1] = pDataline[4];
5403               pScanline[2] = pDataline[2];
5404               pScanline[3] = pDataline[0];
5405 			}
5406 			else
5407 			{
5408               pScanline[0] = (mng_uint8)s;
5409 #ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
5410               {
5411                 int i;
5412                 for (i=2; i >= 0; i--)
5413                 {
5414                   pScanline[i+1] = DIV255B8(s * pDataline[4-i-i]);
5415                 }
5416               }
5417 #else
5418               pScanline[1] = DIV255B8(s * pDataline[4]);
5419               pScanline[2] = DIV255B8(s * pDataline[2]);
5420               pScanline[3] = DIV255B8(s * pDataline[0]);
5421 #endif
5422 			}
5423 		  }
5424           pScanline += (pData->iColinc << 2);
5425           pDataline += 8;
5426         }
5427       }
5428       else
5429       {
5430         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
5431              iX += pData->iColinc)
5432         {                              /* copy the values and premultiply */
5433 		  if ((s = pDataline[3]) == 0)
5434 			*(mng_uint32*) pScanline = 0; /* set all components = 0 */
5435 		  else
5436 		  {
5437 			if (s == 255)
5438 			{
5439               pScanline[0] = 255;
5440 		      pScanline[1] = pDataline[2];
5441               pScanline[2] = pDataline[1];
5442               pScanline[3] = pDataline[0];
5443 			}
5444 			else
5445 			{
5446               pScanline[0] = (mng_uint8)s;
5447 #ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
5448               {
5449                 int i;
5450                 for (i=2; i >= 0; i--)
5451                 {
5452                   pScanline[i+1] = DIV255B8(s * pDataline[2-i]);
5453                 }
5454               }
5455 #else
5456               pScanline[1] = DIV255B8(s * pDataline[2]);
5457               pScanline[2] = DIV255B8(s * pDataline[1]);
5458 		      pScanline[3] = DIV255B8(s * pDataline[0]);
5459 #endif
5460 			}
5461 		  }
5462 
5463           pScanline += (pData->iColinc << 2);
5464           pDataline += 4;
5465         }
5466       }
5467     }
5468     else
5469     {
5470       if (pData->bIsRGBA16)            /* 16-bit input row ? */
5471       {
5472         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
5473              iX += pData->iColinc)
5474         {                              /* get alpha values */
5475           if ((s = pDataline[6]) != 0)       /* any opacity at all ? */
5476           {                            /* fully opaque or background fully transparent ? */
5477             if (s == 255)
5478             {                          /* plain copy it */
5479               pScanline[0] = 255;
5480               pScanline[1] = pDataline[4];
5481               pScanline[2] = pDataline[2];
5482               pScanline[3] = pDataline[0];
5483             }
5484             else
5485             {                          /* now blend (premultiplied) */
5486 			  t = 255 - s;
5487               pScanline[0] = (mng_uint8)(255 - DIV255B8(t * (255 - pScanline[0])));
5488 #ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
5489               {
5490                 int i;
5491                 for (i=2; i >= 0; i--)
5492                 {
5493                   pScanline[i+1] = DIV255B8(s * pDataline[4-i-i] + t *
5494                      pScanline[i+1]);
5495                 }
5496               }
5497 #else
5498 			  pScanline[1] = DIV255B8(s * pDataline[4] + t * pScanline[1]);
5499               pScanline[2] = DIV255B8(s * pDataline[2] + t * pScanline[2]);
5500               pScanline[3] = DIV255B8(s * pDataline[0] + t * pScanline[3]);
5501 #endif
5502             }
5503           }
5504 
5505           pScanline += (pData->iColinc << 2);
5506           pDataline += 8;
5507         }
5508       }
5509       else
5510       {
5511         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
5512              iX += pData->iColinc)
5513         {
5514           if ((s = pDataline[3]) != 0)       /* any opacity at all ? */
5515           {                            /* fully opaque ? */
5516             if (s == 255)
5517             {                          /* then simply copy the values */
5518               pScanline[0] = 255;
5519               pScanline[1] = pDataline[2];
5520               pScanline[2] = pDataline[1];
5521               pScanline[3] = pDataline[0];
5522             }
5523             else
5524             {                          /* now blend (premultiplied) */
5525 			  t = 255 - s;
5526               pScanline[0] = (mng_uint8)(255 - DIV255B8(t * (255 - pScanline[0])));
5527 #ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
5528               {
5529                 int i;
5530                 for (i=2; i >= 0; i--)
5531                 {
5532                   pScanline[i+1] = DIV255B8(s * pDataline[2-i] + t *
5533                      pScanline[i+1]);
5534                 }
5535               }
5536 #else
5537 			  pScanline[1] = DIV255B8(s * pDataline[2] + t * pScanline[1]);
5538               pScanline[2] = DIV255B8(s * pDataline[1] + t * pScanline[2]);
5539               pScanline[3] = DIV255B8(s * pDataline[0] + t * pScanline[3]);
5540 #endif
5541             }
5542           }
5543 
5544           pScanline += (pData->iColinc << 2);
5545           pDataline += 4;
5546         }
5547       }
5548     }
5549   }
5550 
5551   check_update_region (pData);
5552 
5553 #ifdef MNG_SUPPORT_TRACE
5554   MNG_TRACE (pData, MNG_FN_DISPLAY_ABGR8_PM, MNG_LC_END);
5555 #endif
5556 
5557   return MNG_NOERROR;
5558 }
5559 #else /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
mng_display_abgr8_pm(mng_datap pData)5560 mng_retcode mng_display_abgr8_pm (mng_datap pData)
5561 {
5562   mng_uint8p pScanline;
5563   mng_uint8p pDataline;
5564   mng_int32  iX;
5565   mng_uint32 s, t;
5566   mng_uint8  iBps;
5567 
5568 #ifdef MNG_SUPPORT_TRACE
5569   MNG_TRACE (pData, MNG_FN_DISPLAY_ABGR8_PM, MNG_LC_START);
5570 #endif
5571 
5572   iBps=(mng_uint8)(pData->bIsRGBA16 ? 2:1);
5573                                        /* viewable row ? */
5574   if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
5575   {                                    /* address destination row */
5576     pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
5577                                                    pData->iRow + pData->iDestt -
5578                                                    pData->iSourcet);
5579                                        /* adjust destination row starting-point */
5580     pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
5581     pDataline = pData->pRGBArow;       /* address source row */
5582 
5583     /* adjust source row starting-point */
5584     pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << (iBps+1));
5585 
5586     if (pData->bIsOpaque)              /* forget about transparency ? */
5587     {
5588       if (pData->bIsRGBA16)            /* 16-bit input row ? */
5589       {
5590         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
5591              iX += pData->iColinc)
5592         {                              /* scale down by dropping the LSB */
5593 		  if ((s = pDataline[6]) == 0)
5594 			*(mng_uint32*) pScanline = 0; /* set all components = 0 */
5595 		  else
5596 		  {
5597 			if (s == 255)
5598 			{
5599               pScanline[0] = 255;
5600 		      pScanline[1] = pDataline[4];
5601               pScanline[2] = pDataline[2];
5602               pScanline[3] = pDataline[0];
5603 			}
5604 			else
5605 			{
5606               pScanline[0] = (mng_uint8)s;
5607 #ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
5608               {
5609                 int i;
5610                 for (i=2; i >= 0; i--)
5611                 {
5612                   pScanline[i+1] = DIV255B8(s * pDataline[4-i-i]);
5613                 }
5614               }
5615 #else
5616               pScanline[1] = DIV255B8(s * pDataline[4]);
5617               pScanline[2] = DIV255B8(s * pDataline[2]);
5618               pScanline[3] = DIV255B8(s * pDataline[0]);
5619 #endif
5620 			}
5621 		  }
5622           pScanline += (pData->iColinc << 2);
5623           pDataline += 8;
5624         }
5625       }
5626       else
5627       {
5628         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
5629              iX += pData->iColinc)
5630         {                              /* copy the values and premultiply */
5631 		  if ((s = pDataline[3]) == 0)
5632 			*(mng_uint32*) pScanline = 0; /* set all components = 0 */
5633 		  else
5634 		  {
5635 			if (s == 255)
5636 			{
5637               pScanline[0] = 255;
5638 		      pScanline[1] = pDataline[2];
5639               pScanline[2] = pDataline[1];
5640               pScanline[3] = pDataline[0];
5641 			}
5642 			else
5643 			{
5644               pScanline[0] = (mng_uint8)s;
5645 #ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
5646               {
5647                 int i;
5648                 for (i=2; i >= 0; i--)
5649                 {
5650                   pScanline[i+1] = DIV255B8(s * pDataline[2-i]);
5651                 }
5652               }
5653 #else
5654               pScanline[1] = DIV255B8(s * pDataline[2]);
5655               pScanline[2] = DIV255B8(s * pDataline[1]);
5656 		      pScanline[3] = DIV255B8(s * pDataline[0]);
5657 #endif
5658 			}
5659 		  }
5660 
5661           pScanline += (pData->iColinc << 2);
5662           pDataline += 4;
5663         }
5664       }
5665     }
5666     else
5667     {
5668       if (pData->bIsRGBA16)            /* 16-bit input row ? */
5669       {
5670         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
5671              iX += pData->iColinc)
5672         {                              /* get alpha values */
5673           if ((s = pDataline[6]) != 0)       /* any opacity at all ? */
5674           {                            /* fully opaque or background fully transparent ? */
5675             if (s == 255)
5676             {                          /* plain copy it */
5677               pScanline[0] = 255;
5678               pScanline[1] = pDataline[4];
5679               pScanline[2] = pDataline[2];
5680               pScanline[3] = pDataline[0];
5681             }
5682             else
5683             {                          /* now blend (premultiplied) */
5684 			  t = 255 - s;
5685               pScanline[0] = (mng_uint8)(255 - DIV255B8(t * (255 - pScanline[0])));
5686 #ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
5687               {
5688                 int i;
5689                 for (i=2; i >= 0; i--)
5690                 {
5691                   pScanline[i+1] = DIV255B8(s * pDataline[4-i-i] + t *
5692                      pScanline[i+1]);
5693                 }
5694               }
5695 #else
5696 			  pScanline[1] = DIV255B8(s * pDataline[4] + t * pScanline[1]);
5697               pScanline[2] = DIV255B8(s * pDataline[2] + t * pScanline[2]);
5698               pScanline[3] = DIV255B8(s * pDataline[0] + t * pScanline[3]);
5699 #endif
5700             }
5701           }
5702 
5703           pScanline += (pData->iColinc << 2);
5704           pDataline += 8;
5705         }
5706       }
5707       else
5708       {
5709         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
5710              iX += pData->iColinc)
5711         {
5712           if ((s = pDataline[3]) != 0)       /* any opacity at all ? */
5713           {                            /* fully opaque ? */
5714             if (s == 255)
5715             {                          /* then simply copy the values */
5716               pScanline[0] = 255;
5717               pScanline[1] = pDataline[2];
5718               pScanline[2] = pDataline[1];
5719               pScanline[3] = pDataline[0];
5720             }
5721             else
5722             {                          /* now blend (premultiplied) */
5723 			  t = 255 - s;
5724               pScanline[0] = (mng_uint8)(255 - DIV255B8(t * (255 - pScanline[0])));
5725 #ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
5726               {
5727                 int i;
5728                 for (i=2; i >= 0; i--)
5729                 {
5730                   pScanline[i+1] = DIV255B8(s * pDataline[2-i] + t *
5731                      pScanline[i+1]);
5732                 }
5733               }
5734 #else
5735 			  pScanline[1] = DIV255B8(s * pDataline[2] + t * pScanline[1]);
5736               pScanline[2] = DIV255B8(s * pDataline[1] + t * pScanline[2]);
5737               pScanline[3] = DIV255B8(s * pDataline[0] + t * pScanline[3]);
5738 #endif
5739             }
5740           }
5741 
5742           pScanline += (pData->iColinc << 2);
5743           pDataline += 4;
5744         }
5745       }
5746     }
5747   }
5748 
5749   check_update_region (pData);
5750 
5751 #ifdef MNG_SUPPORT_TRACE
5752   MNG_TRACE (pData, MNG_FN_DISPLAY_ABGR8_PM, MNG_LC_END);
5753 #endif
5754 
5755   return MNG_NOERROR;
5756 }
5757 #endif /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
5758 #else /* MNG_NO_16BIT_SUPPORT */
mng_display_abgr8_pm(mng_datap pData)5759 mng_retcode mng_display_abgr8_pm (mng_datap pData)
5760 {
5761   mng_uint8p pScanline;
5762   mng_uint8p pDataline;
5763   mng_int32  iX;
5764   mng_uint32 s, t;
5765 
5766 #ifdef MNG_SUPPORT_TRACE
5767   MNG_TRACE (pData, MNG_FN_DISPLAY_ABGR8_PM, MNG_LC_START);
5768 #endif
5769                                        /* viewable row ? */
5770   if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
5771   {                                    /* address destination row */
5772     pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
5773                                                    pData->iRow + pData->iDestt -
5774                                                    pData->iSourcet);
5775                                        /* adjust destination row starting-point */
5776     pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
5777     pDataline = pData->pRGBArow;       /* address source row */
5778 
5779       pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
5780 
5781     if (pData->bIsOpaque)              /* forget about transparency ? */
5782     {
5783       {
5784         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
5785              iX += pData->iColinc)
5786         {                              /* copy the values and premultiply */
5787 		  if ((s = pDataline[3]) == 0)
5788 			*(mng_uint32*) pScanline = 0; /* set all components = 0 */
5789 		  else
5790 		  {
5791 			if (s == 255)
5792 			{
5793               pScanline[0] = 255;
5794 		      pScanline[1] = pDataline[2];
5795               pScanline[2] = pDataline[1];
5796               pScanline[3] = pDataline[0];
5797 			}
5798 			else
5799 			{
5800               pScanline[0] = (mng_uint8)s;
5801 #ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
5802               {
5803                 int i;
5804                 for (i=2; i >= 0; i--)
5805                 {
5806                   pScanline[i+1] = DIV255B8(s * pDataline[2-i]);
5807                 }
5808               }
5809 #else
5810               pScanline[1] = DIV255B8(s * pDataline[2]);
5811               pScanline[2] = DIV255B8(s * pDataline[1]);
5812 		      pScanline[3] = DIV255B8(s * pDataline[0]);
5813 #endif
5814 			}
5815 		  }
5816 
5817           pScanline += (pData->iColinc << 2);
5818           pDataline += 4;
5819         }
5820       }
5821     }
5822     else
5823     {
5824       {
5825         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
5826              iX += pData->iColinc)
5827         {
5828           if ((s = pDataline[3]) != 0)       /* any opacity at all ? */
5829           {                            /* fully opaque ? */
5830             if (s == 255)
5831             {                          /* then simply copy the values */
5832               pScanline[0] = 255;
5833               pScanline[1] = pDataline[2];
5834               pScanline[2] = pDataline[1];
5835               pScanline[3] = pDataline[0];
5836             }
5837             else
5838             {                          /* now blend (premultiplied) */
5839 			  t = 255 - s;
5840               pScanline[0] = (mng_uint8)(255 - DIV255B8(t * (255 - pScanline[0])));
5841 #ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
5842               {
5843                 int i;
5844                 for (i=2; i >= 0; i--)
5845                 {
5846                   pScanline[i+1] = DIV255B8(s * pDataline[2-i] + t *
5847                      pScanline[i+1]);
5848                 }
5849               }
5850 #else
5851 			  pScanline[1] = DIV255B8(s * pDataline[2] + t * pScanline[1]);
5852               pScanline[2] = DIV255B8(s * pDataline[1] + t * pScanline[2]);
5853               pScanline[3] = DIV255B8(s * pDataline[0] + t * pScanline[3]);
5854 #endif
5855             }
5856           }
5857 
5858           pScanline += (pData->iColinc << 2);
5859           pDataline += 4;
5860         }
5861       }
5862     }
5863   }
5864 
5865   check_update_region (pData);
5866 
5867 #ifdef MNG_SUPPORT_TRACE
5868   MNG_TRACE (pData, MNG_FN_DISPLAY_ABGR8_PM, MNG_LC_END);
5869 #endif
5870 
5871   return MNG_NOERROR;
5872 }
5873 #endif /* MNG_NO_16BIT_SUPPORT */
5874 #endif /* MNG_SKIPCANVAS_ABGR8_PM */
5875 
5876 /* ************************************************************************** */
5877 
5878 #ifndef MNG_SKIPCANVAS_BGR565
5879 #ifndef MNG_NO_16BIT_SUPPORT
5880 #ifndef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
mng_display_bgr565(mng_datap pData)5881 mng_retcode mng_display_bgr565 (mng_datap pData)
5882 {
5883   mng_uint8p pScanline;
5884   mng_uint8p pDataline;
5885   mng_int32  iX;
5886   mng_uint16 iA16;
5887   mng_uint16 iFGr16, iFGg16, iFGb16;
5888   mng_uint16 iBGr16, iBGg16, iBGb16;
5889   mng_uint8  iA8;
5890 
5891 #ifdef MNG_SUPPORT_TRACE
5892   MNG_TRACE (pData, MNG_FN_DISPLAY_BGR565, MNG_LC_START);
5893 #endif
5894                                        /* viewable row ? */
5895   if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
5896   {                                    /* address destination row */
5897     pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
5898                                                    pData->iRow + pData->iDestt -
5899                                                    pData->iSourcet);
5900                                        /* adjust destination row starting-point */
5901     pScanline = pScanline + (pData->iCol * 2) + (pData->iDestl * 2);
5902     pDataline = pData->pRGBArow;       /* address source row */
5903 
5904     if (pData->bIsRGBA16)              /* adjust source row starting-point */
5905       pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 3);
5906     else
5907       pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
5908 
5909     if (pData->bIsOpaque)              /* forget about transparency ? */
5910     {
5911       if (pData->bIsRGBA16)            /* 16-bit input row ? */
5912       {
5913         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
5914              iX += pData->iColinc)
5915         {                              /* scale down by dropping the LSB */
5916           *(pScanline+1) = (mng_uint8)( ( (*(pDataline))&0xF8 ) | (   (*(pDataline+2)>>5)       ) );
5917           *pScanline     = (mng_uint8)( ( (*(pDataline+4)) >>3) | (   (*(pDataline+2)&0xFC) << 3) );
5918 
5919           pScanline += (pData->iColinc * 2);
5920           pDataline += 8;
5921         }
5922       }
5923       else
5924       {
5925         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
5926              iX += pData->iColinc)
5927         {                              /* copy the values */
5928           *(pScanline+1) = (mng_uint8)( ( (*(pDataline))&0xF8 )  |  ( (*(pDataline+1)>>5   )     ) );
5929           *pScanline     = (mng_uint8)( (  *(pDataline+2) >>3 )  |  ( (*(pDataline+1)&0xFC ) << 3) );
5930 
5931 
5932           pScanline += (pData->iColinc * 2);
5933           pDataline += 4;
5934         }
5935       }
5936     }
5937     else
5938     {
5939       if (pData->bIsRGBA16)            /* 16-bit input row ? */
5940       {
5941 
5942         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
5943              iX += pData->iColinc)
5944         {
5945           iA16 = mng_get_uint16 (pDataline+6);
5946 
5947           if (iA16)                    /* any opacity at all ? */
5948           {
5949             if (iA16 == 0xFFFF)        /* fully opaque ? */
5950             {                          /* scale down by dropping the LSB */
5951               *(pScanline+1) = (mng_uint8)( (*(pDataline))&0xF8 )  |  (mng_uint8)( (*(pDataline+2)>>5  )     );
5952               *pScanline     = (mng_uint8)( (*(pDataline+4)) >>3)  |  (mng_uint8)( (*(pDataline+2)&0xFC) << 3);
5953             }
5954             else
5955             {                          /* get the proper values */
5956               iFGr16 = mng_get_uint16 (pDataline  );
5957               iFGg16 = mng_get_uint16 (pDataline+2);
5958               iFGb16 = mng_get_uint16 (pDataline+4);
5959                                        /* scale background up */
5960 
5961               iBGb16 = (mng_uint16)( (*(pScanline+1)) & 0xF8 );
5962               iBGg16 = (mng_uint16)( (*(pScanline+1) << 5)  |  (((*(pScanline  )) & 0xE0) >>3 ) );
5963               iBGr16 = (mng_uint16)( (*(pScanline  )) << 3   );
5964 
5965               iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
5966               iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
5967               iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
5968                                        /* now compose */
5969               MNG_COMPOSE16(iFGr16, iFGr16, iA16, iBGr16);
5970               MNG_COMPOSE16(iFGg16, iFGg16, iA16, iBGg16);
5971               MNG_COMPOSE16(iFGb16, iFGb16, iA16, iBGb16);
5972                                        /* and return the composed values */
5973               *(pScanline+1) = (mng_uint8) ( ( (iFGr16 >> 8)&0xF8 )  |  ( (mng_uint8)(iFGg16>>8) >> 5)      );
5974               *pScanline     = (mng_uint8) ( ( (iFGb16>>11)       )  |  (((mng_uint8)(iFGg16>>8)&0xFC) << 3) );
5975             }
5976           }
5977 
5978           pScanline += (pData->iColinc * 2);
5979           pDataline += 8;
5980         }
5981       }
5982       else
5983       {
5984         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
5985              iX += pData->iColinc)
5986         {
5987           iA8 = *(pDataline+3);        /* get alpha value */
5988 
5989           if (iA8)                     /* any opacity at all ? */
5990           {
5991             if (iA8 == 0xFF)           /* fully opaque ? */
5992             {                          /* then simply copy the values */
5993               *(pScanline+1) = (mng_uint8)( (  (*(pDataline)) &0xF8 )  |   (*(pDataline+1) >>5 )       );
5994               *pScanline     = (mng_uint8)( ( ((*(pDataline+2))>>3) )  |  ((*(pDataline+1)&0xFC) << 3) );
5995             }
5996             else
5997             {                          /* do alpha composing */
5998               mng_uint8 iRed, iGreen, iBlue;
5999 
6000               iRed   = (mng_uint8) (  *(pScanline+1) & 0xF8 );
6001               iGreen = (mng_uint8) ( (*(pScanline+1) << 5)  |  ( ((*pScanline) & 0xE0)>>3 ) );
6002               iBlue  = (mng_uint8) ( (*pScanline << 3) );
6003 
6004               MNG_COMPOSE8 (iRed,     *pDataline,     iA8, iRed    );
6005               MNG_COMPOSE8 (iGreen,   *(pDataline+1), iA8, iGreen  );
6006               MNG_COMPOSE8 (iBlue,    *(pDataline+2), iA8, iBlue   );
6007 
6008               *(pScanline+1) = (mng_uint8) ( ( iRed  & 0xF8 )  |   (iGreen>>5) );
6009               *pScanline     = (mng_uint8) ( ( iBlue >>  3  )  | ( (iGreen & 0xFC) << 3) );
6010             }
6011           }
6012 
6013           pScanline += (pData->iColinc * 2);
6014           pDataline += 4;
6015         }
6016       }
6017     }
6018   }
6019 
6020   check_update_region (pData);
6021 
6022 #ifdef MNG_SUPPORT_TRACE
6023   MNG_TRACE (pData, MNG_FN_DISPLAY_BGR565, MNG_LC_END);
6024 #endif
6025 
6026   return MNG_NOERROR;
6027 }
6028 #else /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
mng_display_bgr565(mng_datap pData)6029 mng_retcode mng_display_bgr565 (mng_datap pData)
6030 {
6031   mng_uint8p pScanline;
6032   mng_uint8p pDataline;
6033   mng_int32  iX;
6034   mng_uint16 iA16;
6035   mng_uint16 iFGr16, iFGg16, iFGb16;
6036   mng_uint16 iBGr16, iBGg16, iBGb16;
6037   mng_uint8  iA8;
6038   mng_uint8  iBps;
6039 
6040 #ifdef MNG_SUPPORT_TRACE
6041   MNG_TRACE (pData, MNG_FN_DISPLAY_BGR565, MNG_LC_START);
6042 #endif
6043 
6044   iBps=(mng_uint8)(pData->bIsRGBA16 ? 2:1);
6045                                        /* viewable row ? */
6046   if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
6047   {                                    /* address destination row */
6048     pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
6049                                                    pData->iRow + pData->iDestt -
6050                                                    pData->iSourcet);
6051                                        /* adjust destination row starting-point */
6052     pScanline = pScanline + (pData->iCol * 2) + (pData->iDestl * 2);
6053     pDataline = pData->pRGBArow;       /* address source row */
6054 
6055     /* adjust source row starting-point */
6056     pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << (iBps+1));
6057 
6058     if (pData->bIsOpaque)              /* forget about transparency ? */
6059     {
6060         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
6061              iX += pData->iColinc)
6062         {                              /* scale down by dropping the LSB */
6063           *(pScanline+1) = (mng_uint8)( ( (*(pDataline))&0xF8 ) |
6064            (   (*(pDataline+iBps)>>5)       ) );
6065           *pScanline     = (mng_uint8)( ( (*(pDataline+2*iBps)) >>3) |
6066            (   (*(pDataline+iBps)&0xFC) << 3) );
6067 
6068           pScanline += (pData->iColinc * 2);
6069           pDataline += 4*iBps;
6070         }
6071     }
6072     else
6073     {
6074       if (pData->bIsRGBA16)            /* 16-bit input row ? */
6075       {
6076 
6077         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
6078              iX += pData->iColinc)
6079         {
6080           iA16 = mng_get_uint16 (pDataline+6);
6081 
6082           if (iA16)                    /* any opacity at all ? */
6083           {
6084             if (iA16 == 0xFFFF)        /* fully opaque ? */
6085             {                          /* scale down by dropping the LSB */
6086               *(pScanline+1) = (mng_uint8)( (*(pDataline))&0xF8 )  |  (mng_uint8)( (*(pDataline+2)>>5  )     );
6087               *pScanline     = (mng_uint8)( (*(pDataline+4)) >>3)  |  (mng_uint8)( (*(pDataline+2)&0xFC) << 3);
6088             }
6089             else
6090             {                          /* get the proper values */
6091               iFGr16 = mng_get_uint16 (pDataline  );
6092               iFGg16 = mng_get_uint16 (pDataline+2);
6093               iFGb16 = mng_get_uint16 (pDataline+4);
6094                                        /* scale background up */
6095 
6096               iBGb16 = (mng_uint16)( (*(pScanline+1)) & 0xF8 );
6097               iBGg16 = (mng_uint16)( (*(pScanline+1) << 5)  |  (((*(pScanline  )) & 0xE0) >>3 ) );
6098               iBGr16 = (mng_uint16)( (*(pScanline  )) << 3   );
6099 
6100               iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
6101               iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
6102               iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
6103                                        /* now compose */
6104               MNG_COMPOSE16(iFGr16, iFGr16, iA16, iBGr16);
6105               MNG_COMPOSE16(iFGg16, iFGg16, iA16, iBGg16);
6106               MNG_COMPOSE16(iFGb16, iFGb16, iA16, iBGb16);
6107                                        /* and return the composed values */
6108               *(pScanline+1) = (mng_uint8) ( ( (iFGr16 >> 8)&0xF8 )  |  ( (mng_uint8)(iFGg16>>8) >> 5)      );
6109               *pScanline     = (mng_uint8) ( ( (iFGb16>>11)       )  |  (((mng_uint8)(iFGg16>>8)&0xFC) << 3) );
6110             }
6111           }
6112 
6113           pScanline += (pData->iColinc * 2);
6114           pDataline += 8;
6115         }
6116       }
6117       else
6118       {
6119         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
6120              iX += pData->iColinc)
6121         {
6122           iA8 = *(pDataline+3);        /* get alpha value */
6123 
6124           if (iA8)                     /* any opacity at all ? */
6125           {
6126             if (iA8 == 0xFF)           /* fully opaque ? */
6127             {                          /* then simply copy the values */
6128               *(pScanline+1) = (mng_uint8)( (  (*(pDataline)) &0xF8 )  |   (*(pDataline+1) >>5 )       );
6129               *pScanline     = (mng_uint8)( ( ((*(pDataline+2))>>3) )  |  ((*(pDataline+1)&0xFC) << 3) );
6130             }
6131             else
6132             {                          /* do alpha composing */
6133               mng_uint8 iRed, iGreen, iBlue;
6134 
6135               iRed   = (mng_uint8) (  *(pScanline+1) & 0xF8 );
6136               iGreen = (mng_uint8) ( (*(pScanline+1) << 5)  |  ( ((*pScanline) & 0xE0)>>3 ) );
6137               iBlue  = (mng_uint8) ( (*pScanline << 3) );
6138 
6139               MNG_COMPOSE8 (iRed,     *pDataline,     iA8, iRed    );
6140               MNG_COMPOSE8 (iGreen,   *(pDataline+1), iA8, iGreen  );
6141               MNG_COMPOSE8 (iBlue,    *(pDataline+2), iA8, iBlue   );
6142 
6143               *(pScanline+1) = (mng_uint8) ( ( iRed  & 0xF8 )  |   (iGreen>>5) );
6144               *pScanline     = (mng_uint8) ( ( iBlue >>  3  )  | ( (iGreen & 0xFC) << 3) );
6145             }
6146           }
6147 
6148           pScanline += (pData->iColinc * 2);
6149           pDataline += 4;
6150         }
6151       }
6152     }
6153   }
6154 
6155   check_update_region (pData);
6156 
6157 #ifdef MNG_SUPPORT_TRACE
6158   MNG_TRACE (pData, MNG_FN_DISPLAY_BGR565, MNG_LC_END);
6159 #endif
6160 
6161   return MNG_NOERROR;
6162 }
6163 #endif /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
6164 #else /* MNG_NO_16BIT_SUPPORT */
mng_display_bgr565(mng_datap pData)6165 mng_retcode mng_display_bgr565 (mng_datap pData)
6166 {
6167   mng_uint8p pScanline;
6168   mng_uint8p pDataline;
6169   mng_int32  iX;
6170   mng_uint8  iA8;
6171 
6172 #ifdef MNG_SUPPORT_TRACE
6173   MNG_TRACE (pData, MNG_FN_DISPLAY_BGR565, MNG_LC_START);
6174 #endif
6175                                        /* viewable row ? */
6176   if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
6177   {                                    /* address destination row */
6178     pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
6179                                                    pData->iRow + pData->iDestt -
6180                                                    pData->iSourcet);
6181                                        /* adjust destination row starting-point */
6182     pScanline = pScanline + (pData->iCol * 2) + (pData->iDestl * 2);
6183     pDataline = pData->pRGBArow;       /* address source row */
6184 
6185       pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
6186 
6187     if (pData->bIsOpaque)              /* forget about transparency ? */
6188     {
6189       {
6190         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
6191              iX += pData->iColinc)
6192         {                              /* copy the values */
6193           *(pScanline+1) = (mng_uint8)( ( (*(pDataline))&0xF8 )  |  ( (*(pDataline+1)>>5   )     ) );
6194           *pScanline     = (mng_uint8)( (  *(pDataline+2) >>3 )  |  ( (*(pDataline+1)&0xFC ) << 3) );
6195 
6196 
6197           pScanline += (pData->iColinc * 2);
6198           pDataline += 4;
6199         }
6200       }
6201     }
6202     else
6203     {
6204       {
6205         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
6206              iX += pData->iColinc)
6207         {
6208           iA8 = *(pDataline+3);        /* get alpha value */
6209 
6210           if (iA8)                     /* any opacity at all ? */
6211           {
6212             if (iA8 == 0xFF)           /* fully opaque ? */
6213             {                          /* then simply copy the values */
6214               *(pScanline+1) = (mng_uint8)( (  (*(pDataline)) &0xF8 )  |   (*(pDataline+1) >>5 )       );
6215               *pScanline     = (mng_uint8)( ( ((*(pDataline+2))>>3) )  |  ((*(pDataline+1)&0xFC) << 3) );
6216             }
6217             else
6218             {                          /* do alpha composing */
6219               mng_uint8 iRed, iGreen, iBlue;
6220 
6221               iRed   = (mng_uint8) (  *(pScanline+1) & 0xF8 );
6222               iGreen = (mng_uint8) ( (*(pScanline+1) << 5)  |  ( ((*pScanline) & 0xE0)>>3 ) );
6223               iBlue  = (mng_uint8) ( (*pScanline << 3) );
6224 
6225               MNG_COMPOSE8 (iRed,     *pDataline,     iA8, iRed    );
6226               MNG_COMPOSE8 (iGreen,   *(pDataline+1), iA8, iGreen  );
6227               MNG_COMPOSE8 (iBlue,    *(pDataline+2), iA8, iBlue   );
6228 
6229               *(pScanline+1) = (mng_uint8) ( ( iRed  & 0xF8 )  |   (iGreen>>5) );
6230               *pScanline     = (mng_uint8) ( ( iBlue >>  3  )  | ( (iGreen & 0xFC) << 3) );
6231             }
6232           }
6233 
6234           pScanline += (pData->iColinc * 2);
6235           pDataline += 4;
6236         }
6237       }
6238     }
6239   }
6240 
6241   check_update_region (pData);
6242 
6243 #ifdef MNG_SUPPORT_TRACE
6244   MNG_TRACE (pData, MNG_FN_DISPLAY_BGR565, MNG_LC_END);
6245 #endif
6246 
6247   return MNG_NOERROR;
6248 }
6249 #endif /* MNG_NO_16BIT_SUPPORT */
6250 #endif /* MNG_SKIPCANVAS_BGR565 */
6251 
6252 /* ************************************************************************** */
6253 
6254 #ifndef MNG_SKIPCANVAS_RGB565
6255 #ifndef MNG_NO_16BIT_SUPPORT
6256 #ifndef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
mng_display_rgb565(mng_datap pData)6257 mng_retcode mng_display_rgb565 (mng_datap pData)
6258 {
6259   mng_uint8p pScanline;
6260   mng_uint8p pDataline;
6261   mng_int32  iX;
6262   mng_uint16 iA16;
6263   mng_uint16 iFGr16, iFGg16, iFGb16;
6264   mng_uint16 iBGr16, iBGg16, iBGb16;
6265   mng_uint8  iA8;
6266 
6267 #ifdef MNG_SUPPORT_TRACE
6268   MNG_TRACE (pData, MNG_FN_DISPLAY_RGB565, MNG_LC_START);
6269 #endif
6270                                        /* viewable row ? */
6271   if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
6272   {                                    /* address destination row */
6273     pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
6274                                                    pData->iRow + pData->iDestt -
6275                                                    pData->iSourcet);
6276                                        /* adjust destination row starting-point */
6277     pScanline = pScanline + (pData->iCol * 2) + (pData->iDestl * 2);
6278     pDataline = pData->pRGBArow;       /* address source row */
6279 
6280     if (pData->bIsRGBA16)              /* adjust source row starting-point */
6281       pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 3);
6282     else
6283       pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
6284 
6285     if (pData->bIsOpaque)              /* forget about transparency ? */
6286     {
6287       if (pData->bIsRGBA16)            /* 16-bit input row ? */
6288       {
6289         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
6290              iX += pData->iColinc)
6291         {                              /* scale down by dropping the LSB */
6292           *(pScanline+1) = (mng_uint8)( ( ( *(pDataline+4)) & 0xF8)  |   (*(pDataline+2) >> 5  )       );
6293           *pScanline     = (mng_uint8)( ( ( *(pDataline  )) >> 3  )  |  ((*(pDataline+2) & 0xFC) << 3) );
6294 
6295           pScanline += (pData->iColinc * 2);
6296           pDataline += 8;
6297         }
6298       }
6299       else
6300       {
6301         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
6302              iX += pData->iColinc)
6303         {                              /* copy the values */
6304           *(pScanline+1) = (mng_uint8)( ( (*(pDataline+2)) & 0xF8)  |   (*(pDataline+1) >> 5        ) );
6305           *pScanline     = (mng_uint8)( (  *(pDataline  )  >> 3  )  |  ((*(pDataline+1) & 0xFC) << 3) );
6306 
6307           pScanline += (pData->iColinc * 2);
6308           pDataline += 4;
6309         }
6310       }
6311     }
6312     else
6313     {
6314       if (pData->bIsRGBA16)            /* 16-bit input row ? */
6315       {
6316 
6317         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
6318              iX += pData->iColinc)
6319         {
6320           iA16 = mng_get_uint16 (pDataline+6);
6321 
6322           if (iA16)                    /* any opacity at all ? */
6323           {
6324             if (iA16 == 0xFFFF)        /* fully opaque ? */
6325             {                          /* scale down by dropping the LSB */
6326               *(pScanline+1) = (mng_uint8)( ( (*(pDataline+4)) & 0xF8)  |   (*(pDataline+2)>>5) );
6327               *pScanline     = (mng_uint8)( ( (*(pDataline  )) >> 3  )  |  ((*(pDataline+2)&0xFC) << 3) );
6328             }
6329             else
6330             {                          /* get the proper values */
6331               iFGr16 = mng_get_uint16 (pDataline  );
6332               iFGg16 = mng_get_uint16 (pDataline+2);
6333               iFGb16 = mng_get_uint16 (pDataline+4);
6334 
6335 			                           /* scale background up */
6336               iBGr16 = (mng_uint8)(  *(pScanline+1) & 0xF8 );
6337               iBGg16 = (mng_uint8)( (*(pScanline+1) << 5)  |  ( ((*pScanline) & 0xE0) >> 3 ) );
6338               iBGb16 = (mng_uint8)(  *(pScanline  ) << 3   );
6339 
6340               iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
6341               iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
6342               iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
6343                                        /* now compose */
6344               MNG_COMPOSE16(iFGr16, iFGr16, iA16, iBGr16);
6345               MNG_COMPOSE16(iFGg16, iFGg16, iA16, iBGg16);
6346               MNG_COMPOSE16(iFGb16, iFGb16, iA16, iBGb16);
6347                                        /* and return the composed values */
6348               *(pScanline+1) = (mng_uint8)( (mng_uint8)((iFGb16 >> 8) &0xF8) |   (   (mng_uint8)(iFGg16 >> 8) >> 5  )        );
6349               *pScanline     = (mng_uint8)( (mng_uint8) (iFGr16 >>11)        |   ( ( (mng_uint8)(iFGg16 >> 8) & 0xFC) << 3)  );
6350             }
6351           }
6352 
6353           pScanline += (pData->iColinc * 2);
6354           pDataline += 8;
6355         }
6356       }
6357       else
6358       {
6359         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
6360              iX += pData->iColinc)
6361         {
6362           iA8 = *(pDataline+3);        /* get alpha value */
6363 
6364           if (iA8)                     /* any opacity at all ? */
6365           {
6366             if (iA8 == 0xFF)           /* fully opaque ? */
6367             {                          /* then simply copy the values */
6368               *(pScanline+1) = (mng_uint8)( ( (*(pDataline+2)) & 0xF8)  |  (  *(pDataline+1) >> 5         ) );
6369               *pScanline     = (mng_uint8)( ( (*(pDataline  )) >> 3  )  |  ( (*(pDataline+1) & 0xFC) << 3 ) );
6370             }
6371             else
6372             {                          /* do alpha composing */
6373               mng_uint8 iRed, iGreen, iBlue;
6374 
6375               iRed   = (mng_uint8)(   *(pScanline+1) & 0xF8);
6376               iGreen = (mng_uint8)( ( *(pScanline+1) << 5  )  |  ( ( (*pScanline)&0xE0)>>3 ) );
6377               iBlue  = (mng_uint8)(   *(pScanline  ) << 3 );
6378 
6379               MNG_COMPOSE8 (iRed,     *(pDataline+2), iA8, iRed    );
6380               MNG_COMPOSE8 (iGreen,   *(pDataline+1), iA8, iGreen  );
6381               MNG_COMPOSE8 (iBlue,    *(pDataline+0), iA8, iBlue   );
6382 
6383               *(pScanline+1) = (mng_uint8)( ( iRed & 0xF8)  |  (  iGreen >> 5        ) );
6384               *pScanline     = (mng_uint8)( (iBlue >> 3  )  |  ( (iGreen & 0xFC) << 3) );
6385             }
6386           }
6387 
6388           pScanline += (pData->iColinc * 2);
6389           pDataline += 4;
6390         }
6391       }
6392     }
6393   }
6394 
6395   check_update_region (pData);
6396 
6397 #ifdef MNG_SUPPORT_TRACE
6398   MNG_TRACE (pData, MNG_FN_DISPLAY_RGB565, MNG_LC_END);
6399 #endif
6400 
6401   return MNG_NOERROR;
6402 }
6403 #else /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
mng_display_rgb565(mng_datap pData)6404 mng_retcode mng_display_rgb565 (mng_datap pData)
6405 {
6406   mng_uint8p pScanline;
6407   mng_uint8p pDataline;
6408   mng_int32  iX;
6409   mng_uint16 iA16;
6410   mng_uint16 iFGr16, iFGg16, iFGb16;
6411   mng_uint16 iBGr16, iBGg16, iBGb16;
6412   mng_uint8  iA8;
6413   mng_uint8  iBps;
6414 
6415 #ifdef MNG_SUPPORT_TRACE
6416   MNG_TRACE (pData, MNG_FN_DISPLAY_RGB565, MNG_LC_START);
6417 #endif
6418 
6419   iBps=(mng_uint8)(pData->bIsRGBA16 ? 2:1);
6420                                        /* viewable row ? */
6421   if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
6422   {                                    /* address destination row */
6423     pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
6424                                                    pData->iRow + pData->iDestt -
6425                                                    pData->iSourcet);
6426                                        /* adjust destination row starting-point */
6427     pScanline = pScanline + (pData->iCol * 2) + (pData->iDestl * 2);
6428     pDataline = pData->pRGBArow;       /* address source row */
6429 
6430     /* adjust source row starting-point */
6431     pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << (iBps+1));
6432 
6433     if (pData->bIsOpaque)              /* forget about transparency ? */
6434     {
6435         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
6436              iX += pData->iColinc)
6437         {                              /* scale down by dropping the LSB */
6438           *(pScanline+1) = (mng_uint8)( ( ( *(pDataline+2*iBps)) & 0xF8)  |
6439               (*(pDataline+iBps) >> 5  )       );
6440           *pScanline     = (mng_uint8)( ( ( *(pDataline  )) >> 3  )  |
6441              ((*(pDataline+iBps) & 0xFC) << 3) );
6442 
6443           pScanline += (pData->iColinc * 2);
6444           pDataline += 4*iBps;
6445         }
6446     }
6447     else
6448     {
6449       if (pData->bIsRGBA16)            /* 16-bit input row ? */
6450       {
6451 
6452         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
6453              iX += pData->iColinc)
6454         {
6455           iA16 = mng_get_uint16 (pDataline+6);
6456 
6457           if (iA16)                    /* any opacity at all ? */
6458           {
6459             if (iA16 == 0xFFFF)        /* fully opaque ? */
6460             {                          /* scale down by dropping the LSB */
6461               *(pScanline+1) = (mng_uint8)( ( (*(pDataline+4)) & 0xF8)  |   (*(pDataline+2)>>5) );
6462               *pScanline     = (mng_uint8)( ( (*(pDataline  )) >> 3  )  |  ((*(pDataline+2)&0xFC) << 3) );
6463             }
6464             else
6465             {                          /* get the proper values */
6466               iFGr16 = mng_get_uint16 (pDataline  );
6467               iFGg16 = mng_get_uint16 (pDataline+2);
6468               iFGb16 = mng_get_uint16 (pDataline+4);
6469 
6470 			                           /* scale background up */
6471               iBGr16 = (mng_uint8)(  *(pScanline+1) & 0xF8 );
6472               iBGg16 = (mng_uint8)( (*(pScanline+1) << 5)  |  ( ((*pScanline) & 0xE0) >> 3 ) );
6473               iBGb16 = (mng_uint8)(  *(pScanline  ) << 3   );
6474 
6475               iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
6476               iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
6477               iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
6478                                        /* now compose */
6479               MNG_COMPOSE16(iFGr16, iFGr16, iA16, iBGr16);
6480               MNG_COMPOSE16(iFGg16, iFGg16, iA16, iBGg16);
6481               MNG_COMPOSE16(iFGb16, iFGb16, iA16, iBGb16);
6482                                        /* and return the composed values */
6483               *(pScanline+1) = (mng_uint8)( (mng_uint8)((iFGb16 >> 8) &0xF8) |   (   (mng_uint8)(iFGg16 >> 8) >> 5  )        );
6484               *pScanline     = (mng_uint8)( (mng_uint8) (iFGr16 >>11)        |   ( ( (mng_uint8)(iFGg16 >> 8) & 0xFC) << 3)  );
6485             }
6486           }
6487 
6488           pScanline += (pData->iColinc * 2);
6489           pDataline += 8;
6490         }
6491       }
6492       else
6493       {
6494         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
6495              iX += pData->iColinc)
6496         {
6497           iA8 = *(pDataline+3);        /* get alpha value */
6498 
6499           if (iA8)                     /* any opacity at all ? */
6500           {
6501             if (iA8 == 0xFF)           /* fully opaque ? */
6502             {                          /* then simply copy the values */
6503               *(pScanline+1) = (mng_uint8)( ( (*(pDataline+2)) & 0xF8)  |  (  *(pDataline+1) >> 5         ) );
6504               *pScanline     = (mng_uint8)( ( (*(pDataline  )) >> 3  )  |  ( (*(pDataline+1) & 0xFC) << 3 ) );
6505             }
6506             else
6507             {                          /* do alpha composing */
6508               mng_uint8 iRed, iGreen, iBlue;
6509 
6510               iRed   = (mng_uint8)(   *(pScanline+1) & 0xF8);
6511               iGreen = (mng_uint8)( ( *(pScanline+1) << 5  )  |  ( ( (*pScanline)&0xE0)>>3 ) );
6512               iBlue  = (mng_uint8)(   *(pScanline  ) << 3 );
6513 
6514               MNG_COMPOSE8 (iRed,     *(pDataline+2), iA8, iRed    );
6515               MNG_COMPOSE8 (iGreen,   *(pDataline+1), iA8, iGreen  );
6516               MNG_COMPOSE8 (iBlue,    *(pDataline+0), iA8, iBlue   );
6517 
6518               *(pScanline+1) = (mng_uint8)( ( iRed & 0xF8)  |  (  iGreen >> 5        ) );
6519               *pScanline     = (mng_uint8)( (iBlue >> 3  )  |  ( (iGreen & 0xFC) << 3) );
6520             }
6521           }
6522 
6523           pScanline += (pData->iColinc * 2);
6524           pDataline += 4;
6525         }
6526       }
6527     }
6528   }
6529 
6530   check_update_region (pData);
6531 
6532 #ifdef MNG_SUPPORT_TRACE
6533   MNG_TRACE (pData, MNG_FN_DISPLAY_RGB565, MNG_LC_END);
6534 #endif
6535 
6536   return MNG_NOERROR;
6537 }
6538 #endif /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
6539 #else /* MNG_NO_16BIT_SUPPORT */
mng_display_rgb565(mng_datap pData)6540 mng_retcode mng_display_rgb565 (mng_datap pData)
6541 {
6542   mng_uint8p pScanline;
6543   mng_uint8p pDataline;
6544   mng_int32  iX;
6545   mng_uint8  iA8;
6546 
6547 #ifdef MNG_SUPPORT_TRACE
6548   MNG_TRACE (pData, MNG_FN_DISPLAY_RGB565, MNG_LC_START);
6549 #endif
6550                                        /* viewable row ? */
6551   if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
6552   {                                    /* address destination row */
6553     pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
6554                                                    pData->iRow + pData->iDestt -
6555                                                    pData->iSourcet);
6556                                        /* adjust destination row starting-point */
6557     pScanline = pScanline + (pData->iCol * 2) + (pData->iDestl * 2);
6558     pDataline = pData->pRGBArow;       /* address source row */
6559 
6560       pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
6561 
6562     if (pData->bIsOpaque)              /* forget about transparency ? */
6563     {
6564       {
6565         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
6566              iX += pData->iColinc)
6567         {                              /* copy the values */
6568           *(pScanline+1) = (mng_uint8)( ( (*(pDataline+2)) & 0xF8)  |   (*(pDataline+1) >> 5        ) );
6569           *pScanline     = (mng_uint8)( (  *(pDataline  )  >> 3  )  |  ((*(pDataline+1) & 0xFC) << 3) );
6570 
6571           pScanline += (pData->iColinc * 2);
6572           pDataline += 4;
6573         }
6574       }
6575     }
6576     else
6577     {
6578       {
6579         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
6580              iX += pData->iColinc)
6581         {
6582           iA8 = *(pDataline+3);        /* get alpha value */
6583 
6584           if (iA8)                     /* any opacity at all ? */
6585           {
6586             if (iA8 == 0xFF)           /* fully opaque ? */
6587             {                          /* then simply copy the values */
6588               *(pScanline+1) = (mng_uint8)( ( (*(pDataline+2)) & 0xF8)  |  (  *(pDataline+1) >> 5         ) );
6589               *pScanline     = (mng_uint8)( ( (*(pDataline  )) >> 3  )  |  ( (*(pDataline+1) & 0xFC) << 3 ) );
6590             }
6591             else
6592             {                          /* do alpha composing */
6593               mng_uint8 iRed, iGreen, iBlue;
6594 
6595               iRed   = (mng_uint8)(   *(pScanline+1) & 0xF8);
6596               iGreen = (mng_uint8)( ( *(pScanline+1) << 5  )  |  ( ( (*pScanline)&0xE0)>>3 ) );
6597               iBlue  = (mng_uint8)(   *(pScanline  ) << 3 );
6598 
6599               MNG_COMPOSE8 (iRed,     *(pDataline+2), iA8, iRed    );
6600               MNG_COMPOSE8 (iGreen,   *(pDataline+1), iA8, iGreen  );
6601               MNG_COMPOSE8 (iBlue,    *(pDataline+0), iA8, iBlue   );
6602 
6603               *(pScanline+1) = (mng_uint8)( ( iRed & 0xF8)  |  (  iGreen >> 5        ) );
6604               *pScanline     = (mng_uint8)( (iBlue >> 3  )  |  ( (iGreen & 0xFC) << 3) );
6605             }
6606           }
6607 
6608           pScanline += (pData->iColinc * 2);
6609           pDataline += 4;
6610         }
6611       }
6612     }
6613   }
6614 
6615   check_update_region (pData);
6616 
6617 #ifdef MNG_SUPPORT_TRACE
6618   MNG_TRACE (pData, MNG_FN_DISPLAY_RGB565, MNG_LC_END);
6619 #endif
6620 
6621   return MNG_NOERROR;
6622 }
6623 #endif /* MNG_NO_16BIT_SUPPORT */
6624 #endif /* MNG_SKIPCANVAS_RGB565 */
6625 
6626 /* ************************************************************************** */
6627 
6628 #ifndef MNG_SKIPCANVAS_BGRA565
6629 #ifndef MNG_NO_16BIT_SUPPORT
6630 #ifndef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
mng_display_bgra565(mng_datap pData)6631 mng_retcode mng_display_bgra565 (mng_datap pData)
6632 {
6633   mng_uint8p pScanline;
6634   mng_uint8p pDataline;
6635   mng_int32  iX;
6636   mng_uint8  iFGa8, iBGa8, iCa8;
6637   mng_uint16 iFGa16, iBGa16, iCa16;
6638   mng_uint16 iFGr16, iFGg16, iFGb16;
6639   mng_uint16 iBGr16, iBGg16, iBGb16;
6640   mng_uint16 iCr16, iCg16, iCb16;
6641   mng_uint8  iCr8, iCg8, iCb8;
6642 
6643 #ifdef MNG_SUPPORT_TRACE
6644   MNG_TRACE (pData, MNG_FN_DISPLAY_BGRA565, MNG_LC_START);
6645 #endif
6646                                        /* viewable row ? */
6647   if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
6648   {                                    /* address destination row */
6649     pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
6650                                                    pData->iRow + pData->iDestt -
6651                                                    pData->iSourcet);
6652                                        /* adjust destination row starting-point */
6653     pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl * 3);
6654     pDataline = pData->pRGBArow;       /* address source row */
6655 
6656     if (pData->bIsRGBA16)              /* adjust source row starting-point */
6657       pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 3);
6658     else
6659       pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
6660 
6661     if (pData->bIsOpaque)              /* forget about transparency ? */
6662     {
6663       if (pData->bIsRGBA16)            /* 16-bit input row ? */
6664       {
6665         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
6666              iX += pData->iColinc)
6667         {                              /* scale down by dropping the LSB */
6668           *(pScanline+1) = (mng_uint8)( ( (*(pDataline))&0xF8 ) | (   (*(pDataline+2)>>5)       ) );
6669           *pScanline     = (mng_uint8)( ( (*(pDataline+4)) >>3) | (   (*(pDataline+2)&0xFC) << 3) );
6670           *(pScanline+2) = *(pDataline+6);
6671 
6672           pScanline += (pData->iColinc * 3);
6673           pDataline += 8;
6674         }
6675       }
6676       else
6677       {
6678         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
6679              iX += pData->iColinc)
6680         {                              /* copy the values */
6681           *(pScanline+1) = (mng_uint8)( ( (*(pDataline))&0xF8 )  |  ( (*(pDataline+1)>>5   )     ) );
6682           *pScanline     = (mng_uint8)( (  *(pDataline+2) >>3 )  |  ( (*(pDataline+1)&0xFC ) << 3) );
6683           *(pScanline+2) = *(pDataline+3);
6684 
6685           pScanline += (pData->iColinc * 3);
6686           pDataline += 4;
6687         }
6688       }
6689     }
6690     else
6691     {
6692       if (pData->bIsRGBA16)            /* 16-bit input row ? */
6693       {
6694         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
6695              iX += pData->iColinc)
6696         {                              /* get alpha values */
6697           iFGa16 = mng_get_uint16 (pDataline+6);
6698           iBGa16 = (mng_uint16)(*(pScanline+2));
6699           iBGa16 = (mng_uint16)(iBGa16 << 8) | iBGa16;
6700 
6701           if (iFGa16)                  /* any opacity at all ? */
6702           {                            /* fully opaque or background fully transparent ? */
6703             if ((iFGa16 == 0xFFFF) || (iBGa16 == 0))
6704             {                          /* plain copy it */
6705               *(pScanline+1) = (mng_uint8)( (*(pDataline))&0xF8 )  |  (mng_uint8)( (*(pDataline+2)>>5  )     );
6706               *pScanline     = (mng_uint8)( (*(pDataline+4)) >>3)  |  (mng_uint8)( (*(pDataline+2)&0xFC) << 3);
6707 			  *(pScanline+2) = *(pDataline+6);
6708             }
6709             else
6710             {
6711               if (iBGa16 == 0xFFFF)    /* background fully opaque ? */
6712               {                        /* get the proper values */
6713                 iFGr16 = mng_get_uint16 (pDataline  );
6714                 iFGg16 = mng_get_uint16 (pDataline+2);
6715                 iFGb16 = mng_get_uint16 (pDataline+4);
6716                                        /* scale background up */
6717                 iBGb16 = (mng_uint16)( (*(pScanline+1)) & 0xF8 );
6718                 iBGg16 = (mng_uint16)( (*(pScanline+1) << 5)  |  (((*(pScanline  )) & 0xE0) >>3 ) );
6719                 iBGr16 = (mng_uint16)( (*(pScanline  )) << 3   );
6720 
6721 				iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
6722                 iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
6723                 iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
6724 
6725                                        /* now compose */
6726                 MNG_COMPOSE16(iFGr16, iFGr16, iFGa16, iBGr16);
6727                 MNG_COMPOSE16(iFGg16, iFGg16, iFGa16, iBGg16);
6728                 MNG_COMPOSE16(iFGb16, iFGb16, iFGa16, iBGb16);
6729                                        /* and return the composed values */
6730                 *(pScanline+1) = (mng_uint8) ( ( (iFGr16 >> 8)&0xF8 )  |  ( (mng_uint8)(iFGg16>>8) >> 5)      );
6731                 *pScanline     = (mng_uint8) ( ( (iFGb16>>11)       )  |  (((mng_uint8)(iFGg16>>8)&0xFC) << 3) );
6732               }
6733               else
6734               {                        /* scale background up */
6735                 iBGb16 = (mng_uint16)( (*(pScanline+1)) & 0xF8 );
6736                 iBGg16 = (mng_uint16)( (*(pScanline+1) << 5)  |  (((*(pScanline  )) & 0xE0) >>3 ) );
6737                 iBGr16 = (mng_uint16)( (*(pScanline  )) << 3   );
6738 
6739 				iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
6740                 iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
6741                 iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
6742                                        /* let's blend */
6743                 MNG_BLEND16 (mng_get_uint16 (pDataline  ),
6744                              mng_get_uint16 (pDataline+2),
6745                              mng_get_uint16 (pDataline+4), iFGa16,
6746                              iBGr16, iBGg16, iBGb16, iBGa16,
6747                              iCr16,  iCg16,  iCb16,  iCa16);
6748                                        /* and return the composed values */
6749                 *(pScanline+1) = (mng_uint8) ( ( (iCr16 >>  8) & 0xF8 )  |  ( (mng_uint8)(iCg16 >> 8) >> 5  )       );
6750                 *pScanline     = (mng_uint8) ( ( (iCb16 >> 11)        )  |  (((mng_uint8)(iCg16 >> 8) & 0xFC) << 3) );
6751                 *(pScanline+2) = (mng_uint8)(iCa16 >> 8);
6752               }
6753             }
6754           }
6755 
6756           pScanline += (pData->iColinc * 3);
6757           pDataline += 8;
6758         }
6759       }
6760       else
6761       {
6762         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
6763              iX += pData->iColinc)
6764         {
6765           iFGa8 = *(pDataline+3);      /* get alpha values */
6766           iBGa8 = *(pScanline+2);
6767 
6768           if (iFGa8)                   /* any opacity at all ? */
6769           {                            /* fully opaque or background fully transparent ? */
6770             if ((iFGa8 == 0xFF) || (iBGa8 == 0))
6771             {                          /* then simply copy the values */
6772               *(pScanline+1) = (mng_uint8)( (  (*(pDataline)) &0xF8 )  |   (*(pDataline+1) >>5 )       );
6773               *pScanline     = (mng_uint8)( ( ((*(pDataline+2))>>3) )  |  ((*(pDataline+1)&0xFC) << 3) );
6774               *(pScanline+2) = *(pDataline+3);
6775             }
6776             else
6777             {
6778               mng_uint8 iRed, iGreen, iBlue;
6779 
6780               iRed   = (mng_uint8) (  *(pScanline+1) & 0xF8 );
6781               iGreen = (mng_uint8) ( (*(pScanline+1) << 5)  |  ( ((*pScanline) & 0xE0)>>3 ) );
6782               iBlue  = (mng_uint8) ( (*pScanline << 3) );
6783 
6784               if (iBGa8 == 0xFF)       /* background fully opaque ? */
6785               {                        /* do alpha composing */
6786                 MNG_COMPOSE8 (iRed,   *pDataline,     iFGa8, iRed   );
6787                 MNG_COMPOSE8 (iGreen, *(pDataline+1), iFGa8, iGreen );
6788                 MNG_COMPOSE8 (iBlue,  *(pDataline+2), iFGa8, iBlue  );
6789                                        /* alpha remains fully opaque !!! */
6790                 *(pScanline+1) = (mng_uint8) ( ( iRed  & 0xF8 )  |   (iGreen>>5) );
6791                 *pScanline     = (mng_uint8) ( ( iBlue >>  3  )  | ( (iGreen & 0xFC) << 3) );
6792               }
6793               else
6794               {                        /* now blend */
6795                 MNG_BLEND8 (*pDataline, *(pDataline+1), *(pDataline+2), iFGa8,
6796                             iRed      , iGreen        , iBlue         , iBGa8,
6797                             iCr8, iCg8, iCb8, iCa8);
6798                                        /* and return the composed values */
6799 
6800 
6801                 *pScanline     = (mng_uint8) ( ( iCb8 >>  3  )  | ( (iCg8 & 0xFC) << 3) );
6802                 *(pScanline+1) = (mng_uint8) ( ( iCr8  & 0xF8 )  |   (iCg8>>5) );
6803 				*(pScanline+2) = (mng_uint8) iCa8;
6804               }
6805             }
6806           }
6807 
6808           pScanline += (pData->iColinc *3);
6809           pDataline += 4;
6810         }
6811       }
6812     }
6813   }
6814 
6815   check_update_region (pData);
6816 
6817 #ifdef MNG_SUPPORT_TRACE
6818   MNG_TRACE (pData, MNG_FN_DISPLAY_BGRA565, MNG_LC_END);
6819 #endif
6820 
6821   return MNG_NOERROR;
6822 }
6823 #else /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
mng_display_bgra565(mng_datap pData)6824 mng_retcode mng_display_bgra565 (mng_datap pData)
6825 {
6826   mng_uint8p pScanline;
6827   mng_uint8p pDataline;
6828   mng_int32  iX;
6829   mng_uint8  iFGa8, iBGa8, iCa8;
6830   mng_uint16 iFGa16, iBGa16, iCa16;
6831   mng_uint16 iFGr16, iFGg16, iFGb16;
6832   mng_uint16 iBGr16, iBGg16, iBGb16;
6833   mng_uint16 iCr16, iCg16, iCb16;
6834   mng_uint8  iCr8, iCg8, iCb8;
6835   mng_uint8  iBps;
6836 
6837 #ifdef MNG_SUPPORT_TRACE
6838   MNG_TRACE (pData, MNG_FN_DISPLAY_BGRA565, MNG_LC_START);
6839 #endif
6840 
6841   iBps=(mng_uint8)(pData->bIsRGBA16 ? 2:1);
6842                                        /* viewable row ? */
6843   if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
6844   {                                    /* address destination row */
6845     pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
6846                                                    pData->iRow + pData->iDestt -
6847                                                    pData->iSourcet);
6848                                        /* adjust destination row starting-point */
6849     pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl * 3);
6850     pDataline = pData->pRGBArow;       /* address source row */
6851 
6852     /* adjust source row starting-point */
6853     pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << (iBps+1));
6854 
6855     if (pData->bIsOpaque)              /* forget about transparency ? */
6856     {
6857         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
6858              iX += pData->iColinc)
6859         {                              /* scale down by dropping the LSB */
6860           *(pScanline+1) = (mng_uint8)( ( (*(pDataline))&0xF8 ) |
6861               (   (*(pDataline+iBps)>>5)       ) );
6862           *pScanline     = (mng_uint8)( ( (*(pDataline+2*iBps)) >>3) |
6863               (   (*(pDataline+iBps)&0xFC) << 3) );
6864           *(pScanline+2) = *(pDataline+3*iBps);
6865 
6866           pScanline += (pData->iColinc * 3);
6867           pDataline += 4*iBps;
6868         }
6869     }
6870     else
6871     {
6872       if (pData->bIsRGBA16)            /* 16-bit input row ? */
6873       {
6874         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
6875              iX += pData->iColinc)
6876         {                              /* get alpha values */
6877           iFGa16 = mng_get_uint16 (pDataline+6);
6878           iBGa16 = (mng_uint16)(*(pScanline+2));
6879           iBGa16 = (mng_uint16)(iBGa16 << 8) | iBGa16;
6880 
6881           if (iFGa16)                  /* any opacity at all ? */
6882           {                            /* fully opaque or background fully transparent ? */
6883             if ((iFGa16 == 0xFFFF) || (iBGa16 == 0))
6884             {                          /* plain copy it */
6885               *(pScanline+1) = (mng_uint8)( (*(pDataline))&0xF8 )  |  (mng_uint8)( (*(pDataline+2)>>5  )     );
6886               *pScanline     = (mng_uint8)( (*(pDataline+4)) >>3)  |  (mng_uint8)( (*(pDataline+2)&0xFC) << 3);
6887 			  *(pScanline+2) = *(pDataline+6);
6888             }
6889             else
6890             {
6891               if (iBGa16 == 0xFFFF)    /* background fully opaque ? */
6892               {                        /* get the proper values */
6893                 iFGr16 = mng_get_uint16 (pDataline  );
6894                 iFGg16 = mng_get_uint16 (pDataline+2);
6895                 iFGb16 = mng_get_uint16 (pDataline+4);
6896                                        /* scale background up */
6897                 iBGb16 = (mng_uint16)( (*(pScanline+1)) & 0xF8 );
6898                 iBGg16 = (mng_uint16)( (*(pScanline+1) << 5)  |  (((*(pScanline  )) & 0xE0) >>3 ) );
6899                 iBGr16 = (mng_uint16)( (*(pScanline  )) << 3   );
6900 
6901 				iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
6902                 iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
6903                 iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
6904 
6905                                        /* now compose */
6906                 MNG_COMPOSE16(iFGr16, iFGr16, iFGa16, iBGr16);
6907                 MNG_COMPOSE16(iFGg16, iFGg16, iFGa16, iBGg16);
6908                 MNG_COMPOSE16(iFGb16, iFGb16, iFGa16, iBGb16);
6909                                        /* and return the composed values */
6910                 *(pScanline+1) = (mng_uint8) ( ( (iFGr16 >> 8)&0xF8 )  |  ( (mng_uint8)(iFGg16>>8) >> 5)      );
6911                 *pScanline     = (mng_uint8) ( ( (iFGb16>>11)       )  |  (((mng_uint8)(iFGg16>>8)&0xFC) << 3) );
6912               }
6913               else
6914               {                        /* scale background up */
6915                 iBGb16 = (mng_uint16)( (*(pScanline+1)) & 0xF8 );
6916                 iBGg16 = (mng_uint16)( (*(pScanline+1) << 5)  |  (((*(pScanline  )) & 0xE0) >>3 ) );
6917                 iBGr16 = (mng_uint16)( (*(pScanline  )) << 3   );
6918 
6919 				iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
6920                 iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
6921                 iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
6922                                        /* let's blend */
6923                 MNG_BLEND16 (mng_get_uint16 (pDataline  ),
6924                              mng_get_uint16 (pDataline+2),
6925                              mng_get_uint16 (pDataline+4), iFGa16,
6926                              iBGr16, iBGg16, iBGb16, iBGa16,
6927                              iCr16,  iCg16,  iCb16,  iCa16);
6928                                        /* and return the composed values */
6929                 *(pScanline+1) = (mng_uint8) ( ( (iCr16 >>  8) & 0xF8 )  |  ( (mng_uint8)(iCg16 >> 8) >> 5  )       );
6930                 *pScanline     = (mng_uint8) ( ( (iCb16 >> 11)        )  |  (((mng_uint8)(iCg16 >> 8) & 0xFC) << 3) );
6931                 *(pScanline+2) = (mng_uint8)(iCa16 >> 8);
6932               }
6933             }
6934           }
6935 
6936           pScanline += (pData->iColinc * 3);
6937           pDataline += 8;
6938         }
6939       }
6940       else
6941       {
6942         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
6943              iX += pData->iColinc)
6944         {
6945           iFGa8 = *(pDataline+3);      /* get alpha values */
6946           iBGa8 = *(pScanline+2);
6947 
6948           if (iFGa8)                   /* any opacity at all ? */
6949           {                            /* fully opaque or background fully transparent ? */
6950             if ((iFGa8 == 0xFF) || (iBGa8 == 0))
6951             {                          /* then simply copy the values */
6952               *(pScanline+1) = (mng_uint8)( (  (*(pDataline)) &0xF8 )  |   (*(pDataline+1) >>5 )       );
6953               *pScanline     = (mng_uint8)( ( ((*(pDataline+2))>>3) )  |  ((*(pDataline+1)&0xFC) << 3) );
6954               *(pScanline+2) = *(pDataline+3);
6955             }
6956             else
6957             {
6958               mng_uint8 iRed, iGreen, iBlue;
6959 
6960               iRed   = (mng_uint8) (  *(pScanline+1) & 0xF8 );
6961               iGreen = (mng_uint8) ( (*(pScanline+1) << 5)  |  ( ((*pScanline) & 0xE0)>>3 ) );
6962               iBlue  = (mng_uint8) ( (*pScanline << 3) );
6963 
6964               if (iBGa8 == 0xFF)       /* background fully opaque ? */
6965               {                        /* do alpha composing */
6966                 MNG_COMPOSE8 (iRed,   *pDataline,     iFGa8, iRed   );
6967                 MNG_COMPOSE8 (iGreen, *(pDataline+1), iFGa8, iGreen );
6968                 MNG_COMPOSE8 (iBlue,  *(pDataline+2), iFGa8, iBlue  );
6969                                        /* alpha remains fully opaque !!! */
6970                 *(pScanline+1) = (mng_uint8) ( ( iRed  & 0xF8 )  |   (iGreen>>5) );
6971                 *pScanline     = (mng_uint8) ( ( iBlue >>  3  )  | ( (iGreen & 0xFC) << 3) );
6972               }
6973               else
6974               {                        /* now blend */
6975                 MNG_BLEND8 (*pDataline, *(pDataline+1), *(pDataline+2), iFGa8,
6976                             iRed      , iGreen        , iBlue         , iBGa8,
6977                             iCr8, iCg8, iCb8, iCa8);
6978                                        /* and return the composed values */
6979 
6980 
6981                 *pScanline     = (mng_uint8) ( ( iCb8 >>  3  )  | ( (iCg8 & 0xFC) << 3) );
6982                 *(pScanline+1) = (mng_uint8) ( ( iCr8  & 0xF8 )  |   (iCg8>>5) );
6983 				*(pScanline+2) = (mng_uint8) iCa8;
6984               }
6985             }
6986           }
6987 
6988           pScanline += (pData->iColinc *3);
6989           pDataline += 4;
6990         }
6991       }
6992     }
6993   }
6994 
6995   check_update_region (pData);
6996 
6997 #ifdef MNG_SUPPORT_TRACE
6998   MNG_TRACE (pData, MNG_FN_DISPLAY_BGRA565, MNG_LC_END);
6999 #endif
7000 
7001   return MNG_NOERROR;
7002 }
7003 #endif /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
7004 #else /* MNG_NO_16BIT_SUPPORT */
mng_display_bgra565(mng_datap pData)7005 mng_retcode mng_display_bgra565 (mng_datap pData)
7006 {
7007   mng_uint8p pScanline;
7008   mng_uint8p pDataline;
7009   mng_int32  iX;
7010   mng_uint8  iFGa8, iBGa8, iCa8;
7011   mng_uint8  iCr8, iCg8, iCb8;
7012 
7013 #ifdef MNG_SUPPORT_TRACE
7014   MNG_TRACE (pData, MNG_FN_DISPLAY_BGRA565, MNG_LC_START);
7015 #endif
7016                                        /* viewable row ? */
7017   if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
7018   {                                    /* address destination row */
7019     pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
7020                                                    pData->iRow + pData->iDestt -
7021                                                    pData->iSourcet);
7022                                        /* adjust destination row starting-point */
7023     pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl * 3);
7024     pDataline = pData->pRGBArow;       /* address source row */
7025 
7026       pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
7027 
7028     if (pData->bIsOpaque)              /* forget about transparency ? */
7029     {
7030       {
7031         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
7032              iX += pData->iColinc)
7033         {                              /* copy the values */
7034           *(pScanline+1) = (mng_uint8)( ( (*(pDataline))&0xF8 )  |  ( (*(pDataline+1)>>5   )     ) );
7035           *pScanline     = (mng_uint8)( (  *(pDataline+2) >>3 )  |  ( (*(pDataline+1)&0xFC ) << 3) );
7036           *(pScanline+2) = *(pDataline+3);
7037 
7038           pScanline += (pData->iColinc * 3);
7039           pDataline += 4;
7040         }
7041       }
7042     }
7043     else
7044     {
7045       {
7046         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
7047              iX += pData->iColinc)
7048         {
7049           iFGa8 = *(pDataline+3);      /* get alpha values */
7050           iBGa8 = *(pScanline+2);
7051 
7052           if (iFGa8)                   /* any opacity at all ? */
7053           {                            /* fully opaque or background fully transparent ? */
7054             if ((iFGa8 == 0xFF) || (iBGa8 == 0))
7055             {                          /* then simply copy the values */
7056               *(pScanline+1) = (mng_uint8)( (  (*(pDataline)) &0xF8 )  |   (*(pDataline+1) >>5 )       );
7057               *pScanline     = (mng_uint8)( ( ((*(pDataline+2))>>3) )  |  ((*(pDataline+1)&0xFC) << 3) );
7058               *(pScanline+2) = *(pDataline+3);
7059             }
7060             else
7061             {
7062               mng_uint8 iRed, iGreen, iBlue;
7063 
7064               iRed   = (mng_uint8) (  *(pScanline+1) & 0xF8 );
7065               iGreen = (mng_uint8) ( (*(pScanline+1) << 5)  |  ( ((*pScanline) & 0xE0)>>3 ) );
7066               iBlue  = (mng_uint8) ( (*pScanline << 3) );
7067 
7068               if (iBGa8 == 0xFF)       /* background fully opaque ? */
7069               {                        /* do alpha composing */
7070                 MNG_COMPOSE8 (iRed,   *pDataline,     iFGa8, iRed   );
7071                 MNG_COMPOSE8 (iGreen, *(pDataline+1), iFGa8, iGreen );
7072                 MNG_COMPOSE8 (iBlue,  *(pDataline+2), iFGa8, iBlue  );
7073                                        /* alpha remains fully opaque !!! */
7074                 *(pScanline+1) = (mng_uint8) ( ( iRed  & 0xF8 )  |   (iGreen>>5) );
7075                 *pScanline     = (mng_uint8) ( ( iBlue >>  3  )  | ( (iGreen & 0xFC) << 3) );
7076               }
7077               else
7078               {                        /* now blend */
7079                 MNG_BLEND8 (*pDataline, *(pDataline+1), *(pDataline+2), iFGa8,
7080                             iRed      , iGreen        , iBlue         , iBGa8,
7081                             iCr8, iCg8, iCb8, iCa8);
7082                                        /* and return the composed values */
7083 
7084 
7085                 *pScanline     = (mng_uint8) ( ( iCb8 >>  3  )  | ( (iCg8 & 0xFC) << 3) );
7086                 *(pScanline+1) = (mng_uint8) ( ( iCr8  & 0xF8 )  |   (iCg8>>5) );
7087 				*(pScanline+2) = (mng_uint8) iCa8;
7088               }
7089             }
7090           }
7091 
7092           pScanline += (pData->iColinc *3);
7093           pDataline += 4;
7094         }
7095       }
7096     }
7097   }
7098 
7099   check_update_region (pData);
7100 
7101 #ifdef MNG_SUPPORT_TRACE
7102   MNG_TRACE (pData, MNG_FN_DISPLAY_BGRA565, MNG_LC_END);
7103 #endif
7104 
7105   return MNG_NOERROR;
7106 }
7107 #endif /* MNG_NO_16BIT_SUPPORT */
7108 #endif /* MNG_SKIPCANVAS_BGRA565 */
7109 
7110 /* ************************************************************************** */
7111 
7112 #ifndef MNG_SKIPCANVAS_RGBA565
7113 #ifndef MNG_NO_16BIT_SUPPORT
7114 #ifndef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
mng_display_rgba565(mng_datap pData)7115 mng_retcode mng_display_rgba565 (mng_datap pData)
7116 {
7117   mng_uint8p pScanline;
7118   mng_uint8p pDataline;
7119   mng_int32  iX;
7120   mng_uint8  iFGa8, iBGa8, iCa8;
7121   mng_uint16 iFGa16, iBGa16, iCa16;
7122   mng_uint16 iFGr16, iFGg16, iFGb16;
7123   mng_uint16 iBGr16, iBGg16, iBGb16;
7124   mng_uint16 iCr16, iCg16, iCb16;
7125   mng_uint8  iCr8, iCg8, iCb8;
7126 
7127 #ifdef MNG_SUPPORT_TRACE
7128   MNG_TRACE (pData, MNG_FN_DISPLAY_RGBA565, MNG_LC_START);
7129 #endif
7130                                        /* viewable row ? */
7131   if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
7132   {                                    /* address destination row */
7133     pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
7134                                                    pData->iRow + pData->iDestt -
7135                                                    pData->iSourcet);
7136                                        /* adjust destination row starting-point */
7137     pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl * 3);
7138     pDataline = pData->pRGBArow;       /* address source row */
7139 
7140     if (pData->bIsRGBA16)              /* adjust source row starting-point */
7141       pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 3);
7142     else
7143       pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
7144 
7145     if (pData->bIsOpaque)              /* forget about transparency ? */
7146     {
7147       if (pData->bIsRGBA16)            /* 16-bit input row ? */
7148       {
7149         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
7150              iX += pData->iColinc)
7151         {                              /* scale down by dropping the LSB */
7152           *(pScanline+1) = (mng_uint8)( ( (*(pDataline+4))&0xF8 ) | (   (*(pDataline+2)>>5)       ) );
7153           *pScanline     = (mng_uint8)( ( (*(pDataline)) >>3) | (   (*(pDataline+2)&0xFC) << 3) );
7154           *(pScanline+2) = *(pDataline+6);
7155 
7156           pScanline += (pData->iColinc * 3);
7157           pDataline += 8;
7158         }
7159       }
7160       else
7161       {
7162         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
7163              iX += pData->iColinc)
7164         {                              /* copy the values */
7165           *(pScanline+1) = (mng_uint8)( ( (*(pDataline+2))&0xF8 )  |  ( (*(pDataline+1)>>5   )     ) );
7166           *pScanline     = (mng_uint8)( (  *(pDataline) >>3 )  |  ( (*(pDataline+1)&0xFC ) << 3) );
7167           *(pScanline+2) = *(pDataline+3);
7168 
7169           pScanline += (pData->iColinc * 3);
7170           pDataline += 4;
7171         }
7172       }
7173     }
7174     else
7175     {
7176       if (pData->bIsRGBA16)            /* 16-bit input row ? */
7177       {
7178         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
7179              iX += pData->iColinc)
7180         {                              /* get alpha values */
7181           iFGa16 = mng_get_uint16 (pDataline+6);
7182           iBGa16 = (mng_uint16)(*(pScanline+2));
7183           iBGa16 = (mng_uint16)(iBGa16 << 8) | iBGa16;
7184 
7185           if (iFGa16)                  /* any opacity at all ? */
7186           {                            /* fully opaque or background fully transparent ? */
7187             if ((iFGa16 == 0xFFFF) || (iBGa16 == 0))
7188             {                          /* plain copy it */
7189               *(pScanline+1) = (mng_uint8)( (*(pDataline+4))&0xF8 )  |  (mng_uint8)( (*(pDataline+2)>>5  )     );
7190               *pScanline     = (mng_uint8)( (*(pDataline)) >>3)  |  (mng_uint8)( (*(pDataline+2)&0xFC) << 3);
7191 			  *(pScanline+2) = *(pDataline+6);
7192             }
7193             else
7194             {
7195               if (iBGa16 == 0xFFFF)    /* background fully opaque ? */
7196               {                        /* get the proper values */
7197                 iFGr16 = mng_get_uint16 (pDataline  );
7198                 iFGg16 = mng_get_uint16 (pDataline+2);
7199                 iFGb16 = mng_get_uint16 (pDataline+4);
7200                                        /* scale background up */
7201                 iBGr16 = (mng_uint16)( (*(pScanline+1)) & 0xF8 );
7202                 iBGg16 = (mng_uint16)( (*(pScanline+1) << 5)  |  (((*(pScanline  )) & 0xE0) >>3 ) );
7203                 iBGb16 = (mng_uint16)( (*(pScanline  )) << 3   );
7204 
7205 				iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
7206                 iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
7207                 iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
7208 
7209                                        /* now compose */
7210                 MNG_COMPOSE16(iFGr16, iFGr16, iFGa16, iBGr16);
7211                 MNG_COMPOSE16(iFGg16, iFGg16, iFGa16, iBGg16);
7212                 MNG_COMPOSE16(iFGb16, iFGb16, iFGa16, iBGb16);
7213                                        /* and return the composed values */
7214                 *(pScanline+1) = (mng_uint8) ( ( (iFGb16 >> 8)&0xF8 )  |  ( (mng_uint8)(iFGg16>>8) >> 5)      );
7215                 *pScanline     = (mng_uint8) ( ( (iFGr16>>11)       )  |  (((mng_uint8)(iFGg16>>8)&0xFC) << 3) );
7216               }
7217               else
7218               {                        /* scale background up */
7219                 iBGr16 = (mng_uint16)( (*(pScanline+1)) & 0xF8 );
7220                 iBGg16 = (mng_uint16)( (*(pScanline+1) << 5)  |  (((*(pScanline  )) & 0xE0) >>3 ) );
7221                 iBGb16 = (mng_uint16)( (*(pScanline  )) << 3   );
7222 
7223 				iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
7224                 iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
7225                 iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
7226                                        /* let's blend */
7227                 MNG_BLEND16 (mng_get_uint16 (pDataline  ),
7228                              mng_get_uint16 (pDataline+2),
7229                              mng_get_uint16 (pDataline+4), iFGa16,
7230                              iBGr16, iBGg16, iBGb16, iBGa16,
7231                              iCr16,  iCg16,  iCb16,  iCa16);
7232                                        /* and return the composed values */
7233                 *(pScanline+1) = (mng_uint8) ( ( (iCb16 >>  8) & 0xF8 )  |  ( (mng_uint8)(iCg16 >> 8) >> 5  )       );
7234                 *pScanline     = (mng_uint8) ( ( (iCr16 >> 11)        )  |  (((mng_uint8)(iCg16 >> 8) & 0xFC) << 3) );
7235                 *(pScanline+2) = (mng_uint8)(iCa16 >> 8);
7236               }
7237             }
7238           }
7239 
7240           pScanline += (pData->iColinc * 3);
7241           pDataline += 8;
7242         }
7243       }
7244       else
7245       {
7246         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
7247              iX += pData->iColinc)
7248         {
7249           iFGa8 = *(pDataline+3);      /* get alpha values */
7250           iBGa8 = *(pScanline+2);
7251 
7252           if (iFGa8)                   /* any opacity at all ? */
7253           {                            /* fully opaque or background fully transparent ? */
7254             if ((iFGa8 == 0xFF) || (iBGa8 == 0))
7255             {                          /* then simply copy the values */
7256               *(pScanline+1) = (mng_uint8)( (  (*(pDataline+2)) &0xF8 )  |   (*(pDataline+1) >>5 )       );
7257               *pScanline     = (mng_uint8)( ( ((*(pDataline))>>3) )  |  ((*(pDataline+1)&0xFC) << 3) );
7258               *(pScanline+2) = *(pDataline+3);
7259             }
7260             else
7261             {
7262               mng_uint8 iRed, iGreen, iBlue;
7263 
7264               iBlue   = (mng_uint8) (  *(pScanline+1) & 0xF8 );
7265               iGreen = (mng_uint8) ( (*(pScanline+1) << 5)  |  ( ((*pScanline) & 0xE0)>>3 ) );
7266               iRed  = (mng_uint8) ( (*pScanline << 3) );
7267 
7268               if (iBGa8 == 0xFF)       /* background fully opaque ? */
7269               {                        /* do alpha composing */
7270                 MNG_COMPOSE8 (iRed,   *pDataline,     iFGa8, iRed   );
7271                 MNG_COMPOSE8 (iGreen, *(pDataline+1), iFGa8, iGreen );
7272                 MNG_COMPOSE8 (iBlue,  *(pDataline+2), iFGa8, iBlue  );
7273                                        /* alpha remains fully opaque !!! */
7274                 *(pScanline+1) = (mng_uint8) ( ( iBlue  & 0xF8 )  |   (iGreen>>5) );
7275                 *pScanline     = (mng_uint8) ( ( iRed >>  3  )  | ( (iGreen & 0xFC) << 3) );
7276               }
7277               else
7278               {                        /* now blend */
7279                 MNG_BLEND8 (*pDataline, *(pDataline+1), *(pDataline+2), iFGa8,
7280                             iRed      , iGreen        , iBlue         , iBGa8,
7281                             iCr8, iCg8, iCb8, iCa8);
7282                                        /* and return the composed values */
7283 
7284 
7285                 *pScanline     = (mng_uint8) ( ( iCr8 >>  3  )  | ( (iCg8 & 0xFC) << 3) );
7286                 *(pScanline+1) = (mng_uint8) ( ( iCb8  & 0xF8 )  |   (iCg8>>5) );
7287 				*(pScanline+2) = (mng_uint8) iCa8;
7288               }
7289             }
7290           }
7291 
7292           pScanline += (pData->iColinc *3);
7293           pDataline += 4;
7294         }
7295       }
7296     }
7297   }
7298 
7299   check_update_region (pData);
7300 
7301 #ifdef MNG_SUPPORT_TRACE
7302   MNG_TRACE (pData, MNG_FN_DISPLAY_RGBA565, MNG_LC_END);
7303 #endif
7304 
7305   return MNG_NOERROR;
7306 }
7307 #else /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
mng_display_rgba565(mng_datap pData)7308 mng_retcode mng_display_rgba565 (mng_datap pData)
7309 {
7310   mng_uint8p pScanline;
7311   mng_uint8p pDataline;
7312   mng_int32  iX;
7313   mng_uint8  iFGa8, iBGa8, iCa8;
7314   mng_uint16 iFGa16, iBGa16, iCa16;
7315   mng_uint16 iFGr16, iFGg16, iFGb16;
7316   mng_uint16 iBGr16, iBGg16, iBGb16;
7317   mng_uint16 iCr16, iCg16, iCb16;
7318   mng_uint8  iCr8, iCg8, iCb8;
7319   mng_uint8  iBps;
7320 
7321 #ifdef MNG_SUPPORT_TRACE
7322   MNG_TRACE (pData, MNG_FN_DISPLAY_RGBA565, MNG_LC_START);
7323 #endif
7324 
7325   iBps=(mng_uint8)(pData->bIsRGBA16 ? 2:1);
7326                                        /* viewable row ? */
7327   if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
7328   {                                    /* address destination row */
7329     pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
7330                                                    pData->iRow + pData->iDestt -
7331                                                    pData->iSourcet);
7332                                        /* adjust destination row starting-point */
7333     pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl * 3);
7334     pDataline = pData->pRGBArow;       /* address source row */
7335 
7336     /* adjust source row starting-point */
7337     pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << (iBps+1));
7338 
7339     if (pData->bIsOpaque)              /* forget about transparency ? */
7340     {
7341         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
7342              iX += pData->iColinc)
7343         {                              /* scale down by dropping the LSB */
7344           *(pScanline+1) = (mng_uint8)( ( (*(pDataline+2*iBps))&0xF8 ) |
7345              (   (*(pDataline+iBps)>>5)       ) );
7346           *pScanline     = (mng_uint8)( ( (*(pDataline)) >>3) |
7347              (   (*(pDataline+iBps)&0xFC) << 3) );
7348           *(pScanline+2) = *(pDataline+3*iBps);
7349 
7350           pScanline += (pData->iColinc * 3);
7351           pDataline += 4*iBps;
7352         }
7353     }
7354     else
7355     {
7356       if (pData->bIsRGBA16)            /* 16-bit input row ? */
7357       {
7358         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
7359              iX += pData->iColinc)
7360         {                              /* get alpha values */
7361           iFGa16 = mng_get_uint16 (pDataline+6);
7362           iBGa16 = (mng_uint16)(*(pScanline+2));
7363           iBGa16 = (mng_uint16)(iBGa16 << 8) | iBGa16;
7364 
7365           if (iFGa16)                  /* any opacity at all ? */
7366           {                            /* fully opaque or background fully transparent ? */
7367             if ((iFGa16 == 0xFFFF) || (iBGa16 == 0))
7368             {                          /* plain copy it */
7369               *(pScanline+1) = (mng_uint8)( (*(pDataline+4))&0xF8 )  |  (mng_uint8)( (*(pDataline+2)>>5  )     );
7370               *pScanline     = (mng_uint8)( (*(pDataline)) >>3)  |  (mng_uint8)( (*(pDataline+2)&0xFC) << 3);
7371 			  *(pScanline+2) = *(pDataline+6);
7372             }
7373             else
7374             {
7375               if (iBGa16 == 0xFFFF)    /* background fully opaque ? */
7376               {                        /* get the proper values */
7377                 iFGr16 = mng_get_uint16 (pDataline  );
7378                 iFGg16 = mng_get_uint16 (pDataline+2);
7379                 iFGb16 = mng_get_uint16 (pDataline+4);
7380                                        /* scale background up */
7381                 iBGr16 = (mng_uint16)( (*(pScanline+1)) & 0xF8 );
7382                 iBGg16 = (mng_uint16)( (*(pScanline+1) << 5)  |  (((*(pScanline  )) & 0xE0) >>3 ) );
7383                 iBGb16 = (mng_uint16)( (*(pScanline  )) << 3   );
7384 
7385 				iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
7386                 iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
7387                 iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
7388 
7389                                        /* now compose */
7390                 MNG_COMPOSE16(iFGr16, iFGr16, iFGa16, iBGr16);
7391                 MNG_COMPOSE16(iFGg16, iFGg16, iFGa16, iBGg16);
7392                 MNG_COMPOSE16(iFGb16, iFGb16, iFGa16, iBGb16);
7393                                        /* and return the composed values */
7394                 *(pScanline+1) = (mng_uint8) ( ( (iFGb16 >> 8)&0xF8 )  |  ( (mng_uint8)(iFGg16>>8) >> 5)      );
7395                 *pScanline     = (mng_uint8) ( ( (iFGr16>>11)       )  |  (((mng_uint8)(iFGg16>>8)&0xFC) << 3) );
7396               }
7397               else
7398               {                        /* scale background up */
7399                 iBGr16 = (mng_uint16)( (*(pScanline+1)) & 0xF8 );
7400                 iBGg16 = (mng_uint16)( (*(pScanline+1) << 5)  |  (((*(pScanline  )) & 0xE0) >>3 ) );
7401                 iBGb16 = (mng_uint16)( (*(pScanline  )) << 3   );
7402 
7403 				iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
7404                 iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
7405                 iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
7406                                        /* let's blend */
7407                 MNG_BLEND16 (mng_get_uint16 (pDataline  ),
7408                              mng_get_uint16 (pDataline+2),
7409                              mng_get_uint16 (pDataline+4), iFGa16,
7410                              iBGr16, iBGg16, iBGb16, iBGa16,
7411                              iCr16,  iCg16,  iCb16,  iCa16);
7412                                        /* and return the composed values */
7413                 *(pScanline+1) = (mng_uint8) ( ( (iCb16 >>  8) & 0xF8 )  |  ( (mng_uint8)(iCg16 >> 8) >> 5  )       );
7414                 *pScanline     = (mng_uint8) ( ( (iCr16 >> 11)        )  |  (((mng_uint8)(iCg16 >> 8) & 0xFC) << 3) );
7415                 *(pScanline+2) = (mng_uint8)(iCa16 >> 8);
7416               }
7417             }
7418           }
7419 
7420           pScanline += (pData->iColinc * 3);
7421           pDataline += 8;
7422         }
7423       }
7424       else
7425       {
7426         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
7427              iX += pData->iColinc)
7428         {
7429           iFGa8 = *(pDataline+3);      /* get alpha values */
7430           iBGa8 = *(pScanline+2);
7431 
7432           if (iFGa8)                   /* any opacity at all ? */
7433           {                            /* fully opaque or background fully transparent ? */
7434             if ((iFGa8 == 0xFF) || (iBGa8 == 0))
7435             {                          /* then simply copy the values */
7436               *(pScanline+1) = (mng_uint8)( (  (*(pDataline+2)) &0xF8 )  |   (*(pDataline+1) >>5 )       );
7437               *pScanline     = (mng_uint8)( ( ((*(pDataline))>>3) )  |  ((*(pDataline+1)&0xFC) << 3) );
7438               *(pScanline+2) = *(pDataline+3);
7439             }
7440             else
7441             {
7442               mng_uint8 iRed, iGreen, iBlue;
7443 
7444               iBlue   = (mng_uint8) (  *(pScanline+1) & 0xF8 );
7445               iGreen = (mng_uint8) ( (*(pScanline+1) << 5)  |  ( ((*pScanline) & 0xE0)>>3 ) );
7446               iRed  = (mng_uint8) ( (*pScanline << 3) );
7447 
7448               if (iBGa8 == 0xFF)       /* background fully opaque ? */
7449               {                        /* do alpha composing */
7450                 MNG_COMPOSE8 (iRed,   *pDataline,     iFGa8, iRed   );
7451                 MNG_COMPOSE8 (iGreen, *(pDataline+1), iFGa8, iGreen );
7452                 MNG_COMPOSE8 (iBlue,  *(pDataline+2), iFGa8, iBlue  );
7453                                        /* alpha remains fully opaque !!! */
7454                 *(pScanline+1) = (mng_uint8) ( ( iBlue  & 0xF8 )  |   (iGreen>>5) );
7455                 *pScanline     = (mng_uint8) ( ( iRed >>  3  )  | ( (iGreen & 0xFC) << 3) );
7456               }
7457               else
7458               {                        /* now blend */
7459                 MNG_BLEND8 (*pDataline, *(pDataline+1), *(pDataline+2), iFGa8,
7460                             iRed      , iGreen        , iBlue         , iBGa8,
7461                             iCr8, iCg8, iCb8, iCa8);
7462                                        /* and return the composed values */
7463 
7464 
7465                 *pScanline     = (mng_uint8) ( ( iCr8 >>  3  )  | ( (iCg8 & 0xFC) << 3) );
7466                 *(pScanline+1) = (mng_uint8) ( ( iCb8  & 0xF8 )  |   (iCg8>>5) );
7467 				*(pScanline+2) = (mng_uint8) iCa8;
7468               }
7469             }
7470           }
7471 
7472           pScanline += (pData->iColinc *3);
7473           pDataline += 4;
7474         }
7475       }
7476     }
7477   }
7478 
7479   check_update_region (pData);
7480 
7481 #ifdef MNG_SUPPORT_TRACE
7482   MNG_TRACE (pData, MNG_FN_DISPLAY_RGBA565, MNG_LC_END);
7483 #endif
7484 
7485   return MNG_NOERROR;
7486 }
7487 #endif /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
7488 #else /* MNG_NO_16BIT_SUPPORT */
mng_display_rgba565(mng_datap pData)7489 mng_retcode mng_display_rgba565 (mng_datap pData)
7490 {
7491   mng_uint8p pScanline;
7492   mng_uint8p pDataline;
7493   mng_int32  iX;
7494   mng_uint8  iFGa8, iBGa8, iCa8;
7495   mng_uint8  iCr8, iCg8, iCb8;
7496 
7497 #ifdef MNG_SUPPORT_TRACE
7498   MNG_TRACE (pData, MNG_FN_DISPLAY_RGBA565, MNG_LC_START);
7499 #endif
7500                                        /* viewable row ? */
7501   if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
7502   {                                    /* address destination row */
7503     pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
7504                                                    pData->iRow + pData->iDestt -
7505                                                    pData->iSourcet);
7506                                        /* adjust destination row starting-point */
7507     pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl * 3);
7508     pDataline = pData->pRGBArow;       /* address source row */
7509 
7510       pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
7511 
7512     if (pData->bIsOpaque)              /* forget about transparency ? */
7513     {
7514       {
7515         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
7516              iX += pData->iColinc)
7517         {                              /* copy the values */
7518           *(pScanline+1) = (mng_uint8)( ( (*(pDataline+2))&0xF8 )  |  ( (*(pDataline+1)>>5   )     ) );
7519           *pScanline     = (mng_uint8)( (  *(pDataline) >>3 )  |  ( (*(pDataline+1)&0xFC ) << 3) );
7520           *(pScanline+2) = *(pDataline+3);
7521 
7522           pScanline += (pData->iColinc * 3);
7523           pDataline += 4;
7524         }
7525       }
7526     }
7527     else
7528     {
7529       {
7530         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
7531              iX += pData->iColinc)
7532         {
7533           iFGa8 = *(pDataline+3);      /* get alpha values */
7534           iBGa8 = *(pScanline+2);
7535 
7536           if (iFGa8)                   /* any opacity at all ? */
7537           {                            /* fully opaque or background fully transparent ? */
7538             if ((iFGa8 == 0xFF) || (iBGa8 == 0))
7539             {                          /* then simply copy the values */
7540               *(pScanline+1) = (mng_uint8)( (  (*(pDataline+2)) &0xF8 )  |   (*(pDataline+1) >>5 )       );
7541               *pScanline     = (mng_uint8)( ( ((*(pDataline))>>3) )  |  ((*(pDataline+1)&0xFC) << 3) );
7542               *(pScanline+2) = *(pDataline+3);
7543             }
7544             else
7545             {
7546               mng_uint8 iRed, iGreen, iBlue;
7547 
7548               iBlue   = (mng_uint8) (  *(pScanline+1) & 0xF8 );
7549               iGreen = (mng_uint8) ( (*(pScanline+1) << 5)  |  ( ((*pScanline) & 0xE0)>>3 ) );
7550               iRed  = (mng_uint8) ( (*pScanline << 3) );
7551 
7552               if (iBGa8 == 0xFF)       /* background fully opaque ? */
7553               {                        /* do alpha composing */
7554                 MNG_COMPOSE8 (iRed,   *pDataline,     iFGa8, iRed   );
7555                 MNG_COMPOSE8 (iGreen, *(pDataline+1), iFGa8, iGreen );
7556                 MNG_COMPOSE8 (iBlue,  *(pDataline+2), iFGa8, iBlue  );
7557                                        /* alpha remains fully opaque !!! */
7558                 *(pScanline+1) = (mng_uint8) ( ( iBlue  & 0xF8 )  |   (iGreen>>5) );
7559                 *pScanline     = (mng_uint8) ( ( iRed >>  3  )  | ( (iGreen & 0xFC) << 3) );
7560               }
7561               else
7562               {                        /* now blend */
7563                 MNG_BLEND8 (*pDataline, *(pDataline+1), *(pDataline+2), iFGa8,
7564                             iRed      , iGreen        , iBlue         , iBGa8,
7565                             iCr8, iCg8, iCb8, iCa8);
7566                                        /* and return the composed values */
7567 
7568 
7569                 *pScanline     = (mng_uint8) ( ( iCr8 >>  3  )  | ( (iCg8 & 0xFC) << 3) );
7570                 *(pScanline+1) = (mng_uint8) ( ( iCb8  & 0xF8 )  |   (iCg8>>5) );
7571 				*(pScanline+2) = (mng_uint8) iCa8;
7572               }
7573             }
7574           }
7575 
7576           pScanline += (pData->iColinc *3);
7577           pDataline += 4;
7578         }
7579       }
7580     }
7581   }
7582 
7583   check_update_region (pData);
7584 
7585 #ifdef MNG_SUPPORT_TRACE
7586   MNG_TRACE (pData, MNG_FN_DISPLAY_RGBA565, MNG_LC_END);
7587 #endif
7588 
7589   return MNG_NOERROR;
7590 }
7591 #endif /* MNG_NO_16BIT_SUPPORT */
7592 #endif /* MNG_SKIPCANVAS_RGBA565 */
7593 
7594 /* ************************************************************************** */
7595 
7596 #ifndef MNG_SKIPCANVAS_BGR565_A8
7597 #ifndef MNG_NO_16BIT_SUPPORT
7598 #ifndef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
mng_display_bgr565_a8(mng_datap pData)7599 mng_retcode mng_display_bgr565_a8 (mng_datap pData)
7600 {
7601   mng_uint8p pScanline;
7602   mng_uint8p pAlphaline;
7603   mng_uint8p pDataline;
7604   mng_int32  iX;
7605   mng_uint16 iA16;
7606   mng_uint16 iFGr16, iFGg16, iFGb16;
7607   mng_uint16 iBGr16, iBGg16, iBGb16, iBGa16;
7608   mng_uint16 iCr16,  iCg16,  iCb16,  iCa16;
7609   mng_uint8  iA8, iBGa8, iCa8;
7610   mng_uint8  iCr8, iCg8, iCb8;
7611 
7612 #ifdef MNG_SUPPORT_TRACE
7613   MNG_TRACE (pData, MNG_FN_DISPLAY_BGR565_A8, MNG_LC_START);
7614 #endif
7615                                        /* viewable row ? */
7616   if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
7617   {                                    /* address destination row */
7618     pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
7619                                                    pData->iRow + pData->iDestt -
7620                                                    pData->iSourcet);
7621     pAlphaline = (mng_uint8p)pData->fGetalphaline  (((mng_handle)pData),
7622                                                     pData->iRow + pData->iDestt -
7623                                                     pData->iSourcet);
7624                                        /* adjust destination row
7625 starting-point */
7626     pScanline = pScanline + (pData->iCol * 2) + (pData->iDestl * 2);
7627     pAlphaline = pAlphaline + pData->iCol + pData->iDestl;
7628     pDataline = pData->pRGBArow;       /* address source row */
7629 
7630     if (pData->bIsRGBA16)       /* adjust source row starting-point */
7631       pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 3);
7632     else
7633       pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
7634 
7635     if (pData->bIsOpaque)              /* forget about transparency ? */
7636     {
7637       if (pData->bIsRGBA16)            /* 16-bit input row ? */
7638       {
7639         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
7640              iX += pData->iColinc)
7641         {                              /* scale down by dropping the LSB */
7642           *(pScanline+1) = (mng_uint8)( ( (*(pDataline))&0xF8 ) | ((*(pDataline+2)>>5)       ) );
7643           *pScanline     = (mng_uint8)( ( (*(pDataline+4)) >>3) | ((*(pDataline+2)&0xFC) << 3) );
7644           *pAlphaline    = (mng_uint8)(*(pDataline+6));
7645 
7646           pScanline += (pData->iColinc * 2);
7647           pAlphaline += pData->iColinc;
7648           pDataline += 8;
7649         }
7650       }
7651       else
7652       {
7653         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
7654              iX += pData->iColinc)
7655         {                              /* copy the values */
7656           *(pScanline+1) = (mng_uint8)( ( (*(pDataline))&0xF8 )  |  ((*(pDataline+1)>>5   )     ) );
7657           *pScanline     = (mng_uint8)( (  *(pDataline+2) >>3 )  |  ((*(pDataline+1)&0xFC ) << 3) );
7658           *pAlphaline    = (mng_uint8)(*(pDataline+3));
7659 
7660           pScanline += (pData->iColinc * 2);
7661           pAlphaline += pData->iColinc;
7662           pDataline += 4;
7663         }
7664       }
7665     }
7666     else /* Not fully opaque */
7667     {
7668       if (pData->bIsRGBA16)            /* 16-bit input row ? */
7669       {
7670 
7671         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
7672              iX += pData->iColinc)
7673         {
7674           iA16 = mng_get_uint16 (pDataline+6);
7675           iBGa16 = (mng_uint16)(*pAlphaline);
7676           iBGa16 = (mng_uint16)(iBGa16 << 8) | iBGa16;
7677 
7678           if (iA16)                    /* any opacity at all ? */
7679           {
7680             if ((iA16 == 0xFFFF) || (iBGa16 == 0))       /* fully opaque or background fully transparent ? */
7681             {                          /* scale down by dropping the LSB */
7682               *(pScanline+1) = (mng_uint8)( (*(pDataline))&0xF8 )  | (mng_uint8)( (*(pDataline+2)>>5  )     );
7683               *pScanline     = (mng_uint8)( (*(pDataline+4)) >>3)  | (mng_uint8)( (*(pDataline+2)&0xFC) << 3);
7684               *pAlphaline    = *(pDataline+6);
7685             }
7686             else
7687             {
7688               if (iBGa16 == 0xFFFF)    /* background fully opaque ? */
7689               {
7690                                         /* get the proper values */
7691                 iFGr16 = mng_get_uint16 (pDataline  );
7692                 iFGg16 = mng_get_uint16 (pDataline+2);
7693                 iFGb16 = mng_get_uint16 (pDataline+4);
7694                                          /* scale background up */
7695 
7696                 iBGb16 = (mng_uint16)( (*(pScanline+1)) & 0xF8 );
7697                 iBGg16 = (mng_uint16)( (*(pScanline+1) << 5)  | (((*(pScanline  )) & 0xE0) >>3 ) );
7698                 iBGr16 = (mng_uint16)( (*(pScanline  )) << 3   );
7699 
7700                 iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
7701                 iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
7702                 iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
7703                                          /* now compose */
7704                 MNG_COMPOSE16(iFGr16, iFGr16, iA16, iBGr16);
7705                 MNG_COMPOSE16(iFGg16, iFGg16, iA16, iBGg16);
7706                 MNG_COMPOSE16(iFGb16, iFGb16, iA16, iBGb16);
7707                                          /* and return the composed values */
7708                 *(pScanline+1) = (mng_uint8) ( ( (iFGr16 >> 8)&0xF8 )  | ( (mng_uint8)(iFGg16>>8) >> 5)       );
7709                 *pScanline     = (mng_uint8) ( ( (iFGb16>>11)       )  | (((mng_uint8)(iFGg16>>8)&0xFC) << 3) );
7710                 *pAlphaline    = (mng_uint8)(iA16>>8);
7711               }
7712               else /* background is not fully opaque */
7713               {                         /* scale background up */
7714                 iBGb16 = (mng_uint16)( (*(pScanline+1)) & 0xF8 );
7715                 iBGg16 = (mng_uint16)( (*(pScanline+1) << 5)  | (((*(pScanline  )) & 0xE0) >>3 ) );
7716                 iBGr16 = (mng_uint16)( (*(pScanline  )) << 3   );
7717 
7718                 iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
7719                 iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
7720                 iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
7721                                        /* let's blend */
7722                 MNG_BLEND16 (mng_get_uint16 (pDataline  ),
7723                              mng_get_uint16 (pDataline+2),
7724                              mng_get_uint16 (pDataline+4), iA16,
7725                              iBGr16, iBGg16, iBGb16, iBGa16,
7726                              iCr16,  iCg16,  iCb16,  iCa16);
7727                                        /* and return the composed values */
7728                 *(pScanline+1) = (mng_uint8) ( ( (iCr16 >> 8)&0xF8 )  | ( (mng_uint8)(iCg16>>8) >> 5)       );
7729                 *pScanline     = (mng_uint8) ( ( (iCb16>>11)       )  | (((mng_uint8)(iCg16>>8)&0xFC) << 3) );
7730                 *pAlphaline    = (mng_uint8)(iCa16 >> 8);
7731               }
7732             }
7733           }
7734 
7735           pScanline += (pData->iColinc * 2);
7736           pAlphaline += pData->iColinc;
7737           pDataline += 8;
7738         }
7739       }
7740       else
7741       {
7742         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
7743 iX += pData->iColinc)
7744         {
7745           iA8 = *(pDataline+3);        /* get alpha value */
7746           iBGa8 = *pAlphaline;
7747 
7748           if (iA8)                     /* any opacity at all ? */
7749           {                            /* fully opaque or background fully transparent ? */
7750             if ((iA8 == 0xFF) || (iBGa8 == 0))
7751             {                          /* then simply copy the values */
7752               *(pScanline+1) = (mng_uint8)( (  (*(pDataline)) &0xF8 )  | (*(pDataline+1) >>5 )        );
7753               *pScanline     = (mng_uint8)( ( ((*(pDataline+2))>>3) )  | ((*(pDataline+1)&0xFC) << 3) );
7754               *pAlphaline    = *(pDataline+3);
7755             }
7756             else
7757             {
7758               if (iBGa8 == 0xFF)       /* background fully opaque ? */
7759               {
7760                 /* do alpha composing */
7761                 mng_uint8 iRed, iGreen, iBlue;
7762 
7763                 iRed   = (mng_uint8) (  *(pScanline+1) & 0xF8 );
7764                 iGreen = (mng_uint8) ( (*(pScanline+1) << 5)  |  (((*pScanline) & 0xE0)>>3 ) );
7765                 iBlue  = (mng_uint8) ( (*pScanline << 3) );
7766 
7767                 MNG_COMPOSE8 (iRed,     *pDataline,     iA8, iRed    );
7768                 MNG_COMPOSE8 (iGreen,   *(pDataline+1), iA8, iGreen  );
7769                 MNG_COMPOSE8 (iBlue,    *(pDataline+2), iA8, iBlue   );
7770 
7771                 *(pScanline+1) = (mng_uint8) ( ( iRed  & 0xF8 )  | (iGreen>>5) );
7772                 *pScanline     = (mng_uint8) ( ( iBlue >>  3  )  | ((iGreen & 0xFC) << 3) );
7773                 *pAlphaline    = iA8;
7774               }
7775               else /* background not fully opaque */
7776               {
7777                 MNG_BLEND8 (*pDataline, *(pDataline+1), *(pDataline+2), iA8,
7778                             *pScanline, *(pScanline+1), *(pScanline+2), iBGa8,
7779                             iCr8, iCg8, iCb8, iCa8);
7780                                        /* and return the composed values */
7781                 *(pScanline+1) = (mng_uint8) ( ( iCr8  & 0xF8 )  | (iCg8>>5) );
7782                 *pScanline     = (mng_uint8) ( ( iCb8 >>  3  )  | ((iCg8 & 0xFC) << 3) );
7783                 *pAlphaline    = iCa8;
7784               }
7785             }
7786           }
7787 
7788           pScanline += (pData->iColinc * 2);
7789           pAlphaline += pData->iColinc;
7790           pDataline += 4;
7791         }
7792       }
7793     }
7794   }
7795 
7796   check_update_region (pData);
7797 
7798 #ifdef MNG_SUPPORT_TRACE
7799   MNG_TRACE (pData, MNG_FN_DISPLAY_BGR565_A8, MNG_LC_END);
7800 #endif
7801 
7802   return MNG_NOERROR;
7803 }
7804 #else /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
mng_display_bgr565_a8(mng_datap pData)7805 mng_retcode mng_display_bgr565_a8 (mng_datap pData)
7806 {
7807   mng_uint8p pScanline;
7808   mng_uint8p pAlphaline;
7809   mng_uint8p pDataline;
7810   mng_int32  iX;
7811   mng_uint16 iA16;
7812   mng_uint16 iFGr16, iFGg16, iFGb16;
7813   mng_uint16 iBGr16, iBGg16, iBGb16, iBGa16;
7814   mng_uint16 iCr16,  iCg16,  iCb16,  iCa16;
7815   mng_uint8  iA8, iBGa8, iCa8;
7816   mng_uint8  iCr8, iCg8, iCb8;
7817   mng_uint8  iBps;
7818 
7819 
7820 #ifdef MNG_SUPPORT_TRACE
7821   MNG_TRACE (pData, MNG_FN_DISPLAY_BGR565_A8, MNG_LC_START);
7822 #endif
7823 
7824   iBps=(mng_uint8)(pData->bIsRGBA16 ? 2:1);
7825                                        /* viewable row ? */
7826   if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
7827   {                                    /* address destination row */
7828     pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
7829                                                    pData->iRow + pData->iDestt -
7830                                                    pData->iSourcet);
7831     pAlphaline = (mng_uint8p)pData->fGetalphaline  (((mng_handle)pData),
7832                                                     pData->iRow + pData->iDestt -
7833                                                     pData->iSourcet);
7834                                        /* adjust destination row
7835 starting-point */
7836     pScanline = pScanline + (pData->iCol * 2) + (pData->iDestl * 2);
7837     pAlphaline = pAlphaline + pData->iCol + pData->iDestl;
7838     pDataline = pData->pRGBArow;       /* address source row */
7839 
7840     /* adjust source row starting-point */
7841     pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << (iBps+1));
7842 
7843     if (pData->bIsOpaque)              /* forget about transparency ? */
7844     {
7845         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
7846              iX += pData->iColinc)
7847         {                              /* scale down by dropping the LSB */
7848           *(pScanline+1) = (mng_uint8)( ( (*(pDataline))&0xF8 ) |
7849               ((*(pDataline+iBps)>>5)       ) );
7850           *pScanline     = (mng_uint8)( ( (*(pDataline+2*iBps)) >>3) |
7851               ((*(pDataline+iBps)&0xFC) << 3) );
7852           *pAlphaline    = (mng_uint8)(*(pDataline+6));
7853 
7854           pScanline += (pData->iColinc * 2);
7855           pAlphaline += pData->iColinc;
7856           pDataline += 8;
7857         }
7858     }
7859     else /* Not fully opaque */
7860     {
7861       if (pData->bIsRGBA16)            /* 16-bit input row ? */
7862       {
7863 
7864         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
7865              iX += pData->iColinc)
7866         {
7867           iA16 = mng_get_uint16 (pDataline+6);
7868           iBGa16 = (mng_uint16)(*pAlphaline);
7869           iBGa16 = (mng_uint16)(iBGa16 << 8) | iBGa16;
7870 
7871           if (iA16)                    /* any opacity at all ? */
7872           {
7873             if ((iA16 == 0xFFFF) || (iBGa16 == 0))       /* fully opaque or background fully transparent ? */
7874             {                          /* scale down by dropping the LSB */
7875               *(pScanline+1) = (mng_uint8)( (*(pDataline))&0xF8 )  | (mng_uint8)( (*(pDataline+2)>>5  )     );
7876               *pScanline     = (mng_uint8)( (*(pDataline+4)) >>3)  | (mng_uint8)( (*(pDataline+2)&0xFC) << 3);
7877               *pAlphaline    = *(pDataline+6);
7878             }
7879             else
7880             {
7881               if (iBGa16 == 0xFFFF)    /* background fully opaque ? */
7882               {
7883                                         /* get the proper values */
7884                 iFGr16 = mng_get_uint16 (pDataline  );
7885                 iFGg16 = mng_get_uint16 (pDataline+2);
7886                 iFGb16 = mng_get_uint16 (pDataline+4);
7887                                          /* scale background up */
7888 
7889                 iBGb16 = (mng_uint16)( (*(pScanline+1)) & 0xF8 );
7890                 iBGg16 = (mng_uint16)( (*(pScanline+1) << 5)  | (((*(pScanline  )) & 0xE0) >>3 ) );
7891                 iBGr16 = (mng_uint16)( (*(pScanline  )) << 3   );
7892 
7893                 iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
7894                 iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
7895                 iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
7896                                          /* now compose */
7897                 MNG_COMPOSE16(iFGr16, iFGr16, iA16, iBGr16);
7898                 MNG_COMPOSE16(iFGg16, iFGg16, iA16, iBGg16);
7899                 MNG_COMPOSE16(iFGb16, iFGb16, iA16, iBGb16);
7900                                          /* and return the composed values */
7901                 *(pScanline+1) = (mng_uint8) ( ( (iFGr16 >> 8)&0xF8 )  | ( (mng_uint8)(iFGg16>>8) >> 5)       );
7902                 *pScanline     = (mng_uint8) ( ( (iFGb16>>11)       )  | (((mng_uint8)(iFGg16>>8)&0xFC) << 3) );
7903                 *pAlphaline    = (mng_uint8)(iA16>>8);
7904               }
7905               else /* background is not fully opaque */
7906               {                         /* scale background up */
7907                 iBGb16 = (mng_uint16)( (*(pScanline+1)) & 0xF8 );
7908                 iBGg16 = (mng_uint16)( (*(pScanline+1) << 5)  | (((*(pScanline  )) & 0xE0) >>3 ) );
7909                 iBGr16 = (mng_uint16)( (*(pScanline  )) << 3   );
7910 
7911                 iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
7912                 iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
7913                 iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
7914                                        /* let's blend */
7915                 MNG_BLEND16 (mng_get_uint16 (pDataline  ),
7916                              mng_get_uint16 (pDataline+2),
7917                              mng_get_uint16 (pDataline+4), iA16,
7918                              iBGr16, iBGg16, iBGb16, iBGa16,
7919                              iCr16,  iCg16,  iCb16,  iCa16);
7920                                        /* and return the composed values */
7921                 *(pScanline+1) = (mng_uint8) ( ( (iCr16 >> 8)&0xF8 )  | ( (mng_uint8)(iCg16>>8) >> 5)       );
7922                 *pScanline     = (mng_uint8) ( ( (iCb16>>11)       )  | (((mng_uint8)(iCg16>>8)&0xFC) << 3) );
7923                 *pAlphaline    = (mng_uint8)(iCa16 >> 8);
7924               }
7925             }
7926           }
7927 
7928           pScanline += (pData->iColinc * 2);
7929           pAlphaline += pData->iColinc;
7930           pDataline += 8;
7931         }
7932       }
7933       else
7934       {
7935         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
7936 iX += pData->iColinc)
7937         {
7938           iA8 = *(pDataline+3);        /* get alpha value */
7939           iBGa8 = *pAlphaline;
7940 
7941           if (iA8)                     /* any opacity at all ? */
7942           {                            /* fully opaque or background fully transparent ? */
7943             if ((iA8 == 0xFF) || (iBGa8 == 0))
7944             {                          /* then simply copy the values */
7945               *(pScanline+1) = (mng_uint8)( (  (*(pDataline)) &0xF8 )  | (*(pDataline+1) >>5 )        );
7946               *pScanline     = (mng_uint8)( ( ((*(pDataline+2))>>3) )  | ((*(pDataline+1)&0xFC) << 3) );
7947               *pAlphaline    = *(pDataline+3);
7948             }
7949             else
7950             {
7951               if (iBGa8 == 0xFF)       /* background fully opaque ? */
7952               {
7953                 /* do alpha composing */
7954                 mng_uint8 iRed, iGreen, iBlue;
7955 
7956                 iRed   = (mng_uint8) (  *(pScanline+1) & 0xF8 );
7957                 iGreen = (mng_uint8) ( (*(pScanline+1) << 5)  |  (((*pScanline) & 0xE0)>>3 ) );
7958                 iBlue  = (mng_uint8) ( (*pScanline << 3) );
7959 
7960                 MNG_COMPOSE8 (iRed,     *pDataline,     iA8, iRed    );
7961                 MNG_COMPOSE8 (iGreen,   *(pDataline+1), iA8, iGreen  );
7962                 MNG_COMPOSE8 (iBlue,    *(pDataline+2), iA8, iBlue   );
7963 
7964                 *(pScanline+1) = (mng_uint8) ( ( iRed  & 0xF8 )  | (iGreen>>5) );
7965                 *pScanline     = (mng_uint8) ( ( iBlue >>  3  )  | ((iGreen & 0xFC) << 3) );
7966                 *pAlphaline    = iA8;
7967               }
7968               else /* background not fully opaque */
7969               {
7970                 MNG_BLEND8 (*pDataline, *(pDataline+1), *(pDataline+2), iA8,
7971                             *pScanline, *(pScanline+1), *(pScanline+2), iBGa8,
7972                             iCr8, iCg8, iCb8, iCa8);
7973                                        /* and return the composed values */
7974                 *(pScanline+1) = (mng_uint8) ( ( iCr8  & 0xF8 )  | (iCg8>>5) );
7975                 *pScanline     = (mng_uint8) ( ( iCb8 >>  3  )  | ((iCg8 & 0xFC) << 3) );
7976                 *pAlphaline    = iCa8;
7977               }
7978             }
7979           }
7980 
7981           pScanline += (pData->iColinc * 2);
7982           pAlphaline += pData->iColinc;
7983           pDataline += 4;
7984         }
7985       }
7986     }
7987   }
7988 
7989   check_update_region (pData);
7990 
7991 #ifdef MNG_SUPPORT_TRACE
7992   MNG_TRACE (pData, MNG_FN_DISPLAY_BGR565_A8, MNG_LC_END);
7993 #endif
7994 
7995   return MNG_NOERROR;
7996 }
7997 #endif /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
7998 #else /* MNG_NO_16BIT_SUPPORT */
mng_display_bgr565_a8(mng_datap pData)7999 mng_retcode mng_display_bgr565_a8 (mng_datap pData)
8000 {
8001   mng_uint8p pScanline;
8002   mng_uint8p pAlphaline;
8003   mng_uint8p pDataline;
8004   mng_int32  iX;
8005   mng_uint8  iA8, iBGa8, iCa8;
8006   mng_uint8  iCr8, iCg8, iCb8;
8007 
8008 
8009 #ifdef MNG_SUPPORT_TRACE
8010   MNG_TRACE (pData, MNG_FN_DISPLAY_BGR565_A8, MNG_LC_START);
8011 #endif
8012                                        /* viewable row ? */
8013   if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
8014   {                                    /* address destination row */
8015     pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
8016                                                    pData->iRow + pData->iDestt -
8017                                                    pData->iSourcet);
8018     pAlphaline = (mng_uint8p)pData->fGetalphaline  (((mng_handle)pData),
8019                                                     pData->iRow + pData->iDestt -
8020                                                     pData->iSourcet);
8021                                        /* adjust destination row
8022 starting-point */
8023     pScanline = pScanline + (pData->iCol * 2) + (pData->iDestl * 2);
8024     pAlphaline = pAlphaline + pData->iCol + pData->iDestl;
8025     pDataline = pData->pRGBArow;       /* address source row */
8026 
8027       pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
8028 
8029     if (pData->bIsOpaque)              /* forget about transparency ? */
8030     {
8031       {
8032         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
8033              iX += pData->iColinc)
8034         {                              /* copy the values */
8035           *(pScanline+1) = (mng_uint8)( ( (*(pDataline))&0xF8 )  |  ((*(pDataline+1)>>5   )     ) );
8036           *pScanline     = (mng_uint8)( (  *(pDataline+2) >>3 )  |  ((*(pDataline+1)&0xFC ) << 3) );
8037           *pAlphaline    = (mng_uint8)(*(pDataline+3));
8038 
8039           pScanline += (pData->iColinc * 2);
8040           pAlphaline += pData->iColinc;
8041           pDataline += 4;
8042         }
8043       }
8044     }
8045     else /* Not fully opaque */
8046     {
8047       {
8048         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
8049 iX += pData->iColinc)
8050         {
8051           iA8 = *(pDataline+3);        /* get alpha value */
8052           iBGa8 = *pAlphaline;
8053 
8054           if (iA8)                     /* any opacity at all ? */
8055           {                            /* fully opaque or background fully transparent ? */
8056             if ((iA8 == 0xFF) || (iBGa8 == 0))
8057             {                          /* then simply copy the values */
8058               *(pScanline+1) = (mng_uint8)( (  (*(pDataline)) &0xF8 )  | (*(pDataline+1) >>5 )        );
8059               *pScanline     = (mng_uint8)( ( ((*(pDataline+2))>>3) )  | ((*(pDataline+1)&0xFC) << 3) );
8060               *pAlphaline    = *(pDataline+3);
8061             }
8062             else
8063             {
8064               if (iBGa8 == 0xFF)       /* background fully opaque ? */
8065               {
8066                 /* do alpha composing */
8067                 mng_uint8 iRed, iGreen, iBlue;
8068 
8069                 iRed   = (mng_uint8) (  *(pScanline+1) & 0xF8 );
8070                 iGreen = (mng_uint8) ( (*(pScanline+1) << 5)  |  (((*pScanline) & 0xE0)>>3 ) );
8071                 iBlue  = (mng_uint8) ( (*pScanline << 3) );
8072 
8073                 MNG_COMPOSE8 (iRed,     *pDataline,     iA8, iRed    );
8074                 MNG_COMPOSE8 (iGreen,   *(pDataline+1), iA8, iGreen  );
8075                 MNG_COMPOSE8 (iBlue,    *(pDataline+2), iA8, iBlue   );
8076 
8077                 *(pScanline+1) = (mng_uint8) ( ( iRed  & 0xF8 )  | (iGreen>>5) );
8078                 *pScanline     = (mng_uint8) ( ( iBlue >>  3  )  | ((iGreen & 0xFC) << 3) );
8079                 *pAlphaline    = iA8;
8080               }
8081               else /* background not fully opaque */
8082               {
8083                 MNG_BLEND8 (*pDataline, *(pDataline+1), *(pDataline+2), iA8,
8084                             *pScanline, *(pScanline+1), *(pScanline+2), iBGa8,
8085                             iCr8, iCg8, iCb8, iCa8);
8086                                        /* and return the composed values */
8087                 *(pScanline+1) = (mng_uint8) ( ( iCr8  & 0xF8 )  | (iCg8>>5) );
8088                 *pScanline     = (mng_uint8) ( ( iCb8 >>  3  )  | ((iCg8 & 0xFC) << 3) );
8089                 *pAlphaline    = iCa8;
8090               }
8091             }
8092           }
8093 
8094           pScanline += (pData->iColinc * 2);
8095           pAlphaline += pData->iColinc;
8096           pDataline += 4;
8097         }
8098       }
8099     }
8100   }
8101 
8102   check_update_region (pData);
8103 
8104 #ifdef MNG_SUPPORT_TRACE
8105   MNG_TRACE (pData, MNG_FN_DISPLAY_BGR565_A8, MNG_LC_END);
8106 #endif
8107 
8108   return MNG_NOERROR;
8109 }
8110 #endif /* MNG_NO_16BIT_SUPPORT */
8111 #endif /* MNG_SKIPCANVAS_BGR565_A8 */
8112 
8113 /* ************************************************************************** */
8114 
8115 #ifndef MNG_SKIPCANVAS_RGB555
8116 #ifndef MNG_NO_16BIT_SUPPORT
8117 #ifndef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
mng_display_rgb555(mng_datap pData)8118 mng_retcode mng_display_rgb555 (mng_datap pData)
8119 {
8120   mng_uint8p pScanline;
8121   mng_uint8p pDataline;
8122   mng_int32  iX;
8123   mng_uint16 iA16;
8124   mng_uint16 iFGr16, iFGg16, iFGb16;
8125   mng_uint16 iBGr16, iBGg16, iBGb16;
8126   mng_uint8  iA8;
8127 
8128 #ifdef MNG_SUPPORT_TRACE
8129   MNG_TRACE (pData, MNG_FN_DISPLAY_RGB555, MNG_LC_START);
8130 #endif
8131                                        /* viewable row ? */
8132   if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
8133   {                                    /* address destination row */
8134     pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
8135                                                    pData->iRow + pData->iDestt -
8136                                                    pData->iSourcet);
8137                                        /* adjust destination row starting-point */
8138     pScanline = pScanline + (pData->iCol * 2) + (pData->iDestl * 2);
8139     pDataline = pData->pRGBArow;       /* address source row */
8140 
8141     if (pData->bIsRGBA16)              /* adjust source row starting-point */
8142       pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 3);
8143     else
8144       pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
8145 
8146     if (pData->bIsOpaque)              /* forget about transparency ? */
8147     {
8148       if (pData->bIsRGBA16)            /* 16-bit input row ? */
8149       {
8150         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
8151              iX += pData->iColinc)
8152         {                              /* scale down by dropping the LSB */
8153           *(pScanline+1) = (mng_uint8)( ((*(pDataline+4) & 0xF8) >> 1 ) |  (*(pDataline+2)         >> 6 ) );
8154           *pScanline     = (mng_uint8)( ( *(pDataline  )         >> 3 ) | ((*(pDataline+2) & 0xF8) << 2 ) );
8155 
8156           pScanline += (pData->iColinc * 2);
8157           pDataline += 8;
8158         }
8159       }
8160       else
8161       {
8162         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
8163              iX += pData->iColinc)
8164         {                              /* copy the values */
8165           *(pScanline+1) = (mng_uint8)( ((*(pDataline+2) & 0xF8) >> 1 ) |  (*(pDataline+1)         >> 6 ) );
8166           *pScanline     = (mng_uint8)( ( *(pDataline  )         >> 3 ) | ((*(pDataline+1) & 0xF8) << 2 ) );
8167 
8168           pScanline += (pData->iColinc * 2);
8169           pDataline += 4;
8170         }
8171       }
8172     }
8173     else
8174     {
8175       if (pData->bIsRGBA16)            /* 16-bit input row ? */
8176       {
8177 
8178         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
8179              iX += pData->iColinc)
8180         {
8181           iA16 = mng_get_uint16 (pDataline+6);
8182 
8183           if (iA16)                    /* any opacity at all ? */
8184           {
8185             if (iA16 == 0xFFFF)        /* fully opaque ? */
8186             {                          /* scale down by dropping the LSB */
8187               *(pScanline+1) = (mng_uint8)( ((*(pDataline+4) & 0xF8) >> 1 ) |  (*(pDataline+2)         >> 6 ) );
8188               *pScanline     = (mng_uint8)( ( *(pDataline  )         >> 3 ) | ((*(pDataline+2) & 0xF8) << 2 ) );
8189             }
8190             else
8191             {                          /* get the proper values */
8192               iFGr16 = mng_get_uint16 (pDataline  );
8193               iFGg16 = mng_get_uint16 (pDataline+2);
8194               iFGb16 = mng_get_uint16 (pDataline+4);
8195 
8196 			                           /* scale background up */
8197               iBGr16 = (mng_uint8)( (*(pScanline+1) & 0xF8) << 1 );
8198               iBGg16 = (mng_uint8)( (*(pScanline+1)         << 6 )  |  ( ((*pScanline) & 0xE0) >> 2 ) );
8199               iBGb16 = (mng_uint8)(  *(pScanline  )         << 3 );
8200 
8201               iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
8202               iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
8203               iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
8204                                        /* now compose */
8205               MNG_COMPOSE16(iFGr16, iFGr16, iA16, iBGr16);
8206               MNG_COMPOSE16(iFGg16, iFGg16, iA16, iBGg16);
8207               MNG_COMPOSE16(iFGb16, iFGb16, iA16, iBGb16);
8208                                        /* and return the composed values */
8209               *(pScanline+1) = (mng_uint8)( (mng_uint8)(((iFGb16 >> 8) & 0xF8) >> 1 ) | (   (mng_uint8)(iFGg16 >> 8)         >> 6 ) );
8210               *pScanline     = (mng_uint8)( (mng_uint8) ((iFGr16 >>11)         >> 3 ) | ( ( (mng_uint8)(iFGg16 >> 8) & 0xF8) << 2 ) );
8211             }
8212           }
8213 
8214           pScanline += (pData->iColinc * 2);
8215           pDataline += 8;
8216         }
8217       }
8218       else
8219       {
8220         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
8221              iX += pData->iColinc)
8222         {
8223           iA8 = *(pDataline+3);        /* get alpha value */
8224 
8225           if (iA8)                     /* any opacity at all ? */
8226           {
8227             if (iA8 == 0xFF)           /* fully opaque ? */
8228             {                          /* then simply copy the values */
8229               *(pScanline+1) = (mng_uint8)( ((*(pDataline+2) & 0xF8) >> 1 ) |  (*(pDataline+1)         >> 6 ) );
8230               *pScanline     = (mng_uint8)( ( *(pDataline  )         >> 3 ) | ((*(pDataline+1) & 0xF8) << 2 ) );
8231             }
8232             else
8233             {                          /* do alpha composing */
8234               mng_uint8 iRed, iGreen, iBlue;
8235 
8236               iRed   = (mng_uint8)( (*(pScanline+1) & 0xF8) << 1 );
8237               iGreen = (mng_uint8)( (*(pScanline+1)         << 6 )  |  ( ((*pScanline) & 0xE0) >> 2 ) );
8238               iBlue  = (mng_uint8)(  *(pScanline  )         << 3 );
8239 
8240               MNG_COMPOSE8 (iRed,     *(pDataline+2), iA8, iRed    );
8241               MNG_COMPOSE8 (iGreen,   *(pDataline+1), iA8, iGreen  );
8242               MNG_COMPOSE8 (iBlue,    *(pDataline+0), iA8, iBlue   );
8243 
8244               *(pScanline+1) = (mng_uint8)( ( (iRed & 0xF8) >> 1 )  |  (  iGreen         >> 6 ) );
8245               *pScanline     = (mng_uint8)(   (iBlue        >> 3 )  |  ( (iGreen & 0xF8) << 2 ) );
8246             }
8247           }
8248 
8249           pScanline += (pData->iColinc * 2);
8250           pDataline += 4;
8251         }
8252       }
8253     }
8254   }
8255 
8256   check_update_region (pData);
8257 
8258 #ifdef MNG_SUPPORT_TRACE
8259   MNG_TRACE (pData, MNG_FN_DISPLAY_RGB555, MNG_LC_END);
8260 #endif
8261 
8262   return MNG_NOERROR;
8263 }
8264 #else /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
mng_display_rgb555(mng_datap pData)8265 mng_retcode mng_display_rgb555 (mng_datap pData)
8266 {
8267   mng_uint8p pScanline;
8268   mng_uint8p pDataline;
8269   mng_int32  iX;
8270   mng_uint16 iA16;
8271   mng_uint16 iFGr16, iFGg16, iFGb16;
8272   mng_uint16 iBGr16, iBGg16, iBGb16;
8273   mng_uint8  iA8;
8274   mng_uint8  iBps;
8275 
8276 #ifdef MNG_SUPPORT_TRACE
8277   MNG_TRACE (pData, MNG_FN_DISPLAY_RGB555, MNG_LC_START);
8278 #endif
8279 
8280   iBps=(mng_uint8)(pData->bIsRGBA16 ? 2:1);
8281                                        /* viewable row ? */
8282   if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
8283   {                                    /* address destination row */
8284     pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
8285                                                    pData->iRow + pData->iDestt -
8286                                                    pData->iSourcet);
8287                                        /* adjust destination row starting-point */
8288     pScanline = pScanline + (pData->iCol * 2) + (pData->iDestl * 2);
8289     pDataline = pData->pRGBArow;       /* address source row */
8290 
8291     /* adjust source row starting-point */
8292     pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << (iBps+1));
8293 
8294     if (pData->bIsOpaque)              /* forget about transparency ? */
8295     {
8296         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
8297              iX += pData->iColinc)
8298         {                              /* scale down by dropping the LSB */
8299           *(pScanline+1) = (mng_uint8)( ((*(pDataline+2*iBps) & 0xF8) >> 1 ) |  (*(pDataline+iBps)         >> 6 ) );
8300           *pScanline     = (mng_uint8)( ( *(pDataline       )         >> 3 ) | ((*(pDataline+iBps) & 0xF8) << 2 ) );
8301 
8302           pScanline += (pData->iColinc * 2);
8303           pDataline += 4*iBps;
8304         }
8305     }
8306     else
8307     {
8308       if (pData->bIsRGBA16)            /* 16-bit input row ? */
8309       {
8310 
8311         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
8312              iX += pData->iColinc)
8313         {
8314           iA16 = mng_get_uint16 (pDataline+6);
8315 
8316           if (iA16)                    /* any opacity at all ? */
8317           {
8318             if (iA16 == 0xFFFF)        /* fully opaque ? */
8319             {                          /* scale down by dropping the LSB */
8320               *(pScanline+1) = (mng_uint8)( ((*(pDataline+4) & 0xF8) >> 1 ) |  (*(pDataline+2)         >> 6 ) );
8321               *pScanline     = (mng_uint8)( ( *(pDataline  )         >> 3 ) | ((*(pDataline+2) & 0xF8) << 2 ) );
8322             }
8323             else
8324             {                          /* get the proper values */
8325               iFGr16 = mng_get_uint16 (pDataline  );
8326               iFGg16 = mng_get_uint16 (pDataline+2);
8327               iFGb16 = mng_get_uint16 (pDataline+4);
8328 
8329 			                           /* scale background up */
8330               iBGr16 = (mng_uint8)( (*(pScanline+1) & 0xF8) << 1 );
8331               iBGg16 = (mng_uint8)( (*(pScanline+1)         << 6 )  |  ( ((*pScanline) & 0xE0) >> 2 ) );
8332               iBGb16 = (mng_uint8)(  *(pScanline  )         << 3 );
8333 
8334               iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
8335               iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
8336               iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
8337                                        /* now compose */
8338               MNG_COMPOSE16(iFGr16, iFGr16, iA16, iBGr16);
8339               MNG_COMPOSE16(iFGg16, iFGg16, iA16, iBGg16);
8340               MNG_COMPOSE16(iFGb16, iFGb16, iA16, iBGb16);
8341                                        /* and return the composed values */
8342               *(pScanline+1) = (mng_uint8)( (mng_uint8)(((iFGb16 >> 8) & 0xF8) >> 1 ) | (   (mng_uint8)(iFGg16 >> 8)         >> 6 ) );
8343               *pScanline     = (mng_uint8)( (mng_uint8) ((iFGr16 >>11)         >> 3 ) | ( ( (mng_uint8)(iFGg16 >> 8) & 0xF8) << 2 ) );
8344             }
8345           }
8346 
8347           pScanline += (pData->iColinc * 2);
8348           pDataline += 8;
8349         }
8350       }
8351       else
8352       {
8353         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
8354              iX += pData->iColinc)
8355         {
8356           iA8 = *(pDataline+3);        /* get alpha value */
8357 
8358           if (iA8)                     /* any opacity at all ? */
8359           {
8360             if (iA8 == 0xFF)           /* fully opaque ? */
8361             {                          /* then simply copy the values */
8362               *(pScanline+1) = (mng_uint8)( ((*(pDataline+2) & 0xF8) >> 1 ) |  (*(pDataline+1)         >> 6 ) );
8363               *pScanline     = (mng_uint8)( ( *(pDataline  )         >> 3 ) | ((*(pDataline+1) & 0xF8) << 2 ) );
8364             }
8365             else
8366             {                          /* do alpha composing */
8367               mng_uint8 iRed, iGreen, iBlue;
8368 
8369               iRed   = (mng_uint8)( (*(pScanline+1) & 0xF8) << 1 );
8370               iGreen = (mng_uint8)( (*(pScanline+1)         << 6 )  |  ( ((*pScanline) & 0xE0) >> 2 ) );
8371               iBlue  = (mng_uint8)(  *(pScanline  )         << 3 );
8372 
8373               MNG_COMPOSE8 (iRed,     *(pDataline+2), iA8, iRed    );
8374               MNG_COMPOSE8 (iGreen,   *(pDataline+1), iA8, iGreen  );
8375               MNG_COMPOSE8 (iBlue,    *(pDataline+0), iA8, iBlue   );
8376 
8377               *(pScanline+1) = (mng_uint8)( ( (iRed & 0xF8) >> 1 )  |  (  iGreen         >> 6 ) );
8378               *pScanline     = (mng_uint8)(   (iBlue        >> 3 )  |  ( (iGreen & 0xF8) << 2 ) );
8379             }
8380           }
8381 
8382           pScanline += (pData->iColinc * 2);
8383           pDataline += 4;
8384         }
8385       }
8386     }
8387   }
8388 
8389   check_update_region (pData);
8390 
8391 #ifdef MNG_SUPPORT_TRACE
8392   MNG_TRACE (pData, MNG_FN_DISPLAY_RGB555, MNG_LC_END);
8393 #endif
8394 
8395   return MNG_NOERROR;
8396 }
8397 #endif /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
8398 #else /* MNG_NO_16BIT_SUPPORT */
mng_display_rgb555(mng_datap pData)8399 mng_retcode mng_display_rgb555 (mng_datap pData)
8400 {
8401   mng_uint8p pScanline;
8402   mng_uint8p pDataline;
8403   mng_int32  iX;
8404   mng_uint8  iA8;
8405 
8406 #ifdef MNG_SUPPORT_TRACE
8407   MNG_TRACE (pData, MNG_FN_DISPLAY_RGB555, MNG_LC_START);
8408 #endif
8409                                        /* viewable row ? */
8410   if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
8411   {                                    /* address destination row */
8412     pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
8413                                                    pData->iRow + pData->iDestt -
8414                                                    pData->iSourcet);
8415                                        /* adjust destination row starting-point */
8416     pScanline = pScanline + (pData->iCol * 2) + (pData->iDestl * 2);
8417     pDataline = pData->pRGBArow;       /* address source row */
8418 
8419       pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
8420 
8421     if (pData->bIsOpaque)              /* forget about transparency ? */
8422     {
8423       {
8424         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
8425              iX += pData->iColinc)
8426         {                              /* copy the values */
8427           *(pScanline+1) = (mng_uint8)( ((*(pDataline+2) & 0xF8) >> 1 ) |  (*(pDataline+1)         >> 6 ) );
8428           *pScanline     = (mng_uint8)( ( *(pDataline  )         >> 3 ) | ((*(pDataline+1) & 0xF8) << 2 ) );
8429 
8430           pScanline += (pData->iColinc * 2);
8431           pDataline += 4;
8432         }
8433       }
8434     }
8435     else
8436     {
8437       {
8438         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
8439              iX += pData->iColinc)
8440         {
8441           iA8 = *(pDataline+3);        /* get alpha value */
8442 
8443           if (iA8)                     /* any opacity at all ? */
8444           {
8445             if (iA8 == 0xFF)           /* fully opaque ? */
8446             {                          /* then simply copy the values */
8447               *(pScanline+1) = (mng_uint8)( ((*(pDataline+2) & 0xF8) >> 1 ) |  (*(pDataline+1)         >> 6 ) );
8448               *pScanline     = (mng_uint8)( ( *(pDataline  )         >> 3 ) | ((*(pDataline+1) & 0xF8) << 2 ) );
8449             }
8450             else
8451             {                          /* do alpha composing */
8452               mng_uint8 iRed, iGreen, iBlue;
8453 
8454               iRed   = (mng_uint8)( (*(pScanline+1) & 0xF8) << 1 );
8455               iGreen = (mng_uint8)( (*(pScanline+1)         << 6 )  |  ( ((*pScanline) & 0xE0) >> 2 ) );
8456               iBlue  = (mng_uint8)(  *(pScanline  )         << 3 );
8457 
8458               MNG_COMPOSE8 (iRed,     *(pDataline+2), iA8, iRed    );
8459               MNG_COMPOSE8 (iGreen,   *(pDataline+1), iA8, iGreen  );
8460               MNG_COMPOSE8 (iBlue,    *(pDataline+0), iA8, iBlue   );
8461 
8462               *(pScanline+1) = (mng_uint8)( ( (iRed & 0xF8) >> 1 )  |  (  iGreen         >> 6 ) );
8463               *pScanline     = (mng_uint8)(   (iBlue        >> 3 )  |  ( (iGreen & 0xF8) << 2 ) );
8464             }
8465           }
8466 
8467           pScanline += (pData->iColinc * 2);
8468           pDataline += 4;
8469         }
8470       }
8471     }
8472   }
8473 
8474   check_update_region (pData);
8475 
8476 #ifdef MNG_SUPPORT_TRACE
8477   MNG_TRACE (pData, MNG_FN_DISPLAY_RGB555, MNG_LC_END);
8478 #endif
8479 
8480   return MNG_NOERROR;
8481 }
8482 #endif /* MNG_NO_16BIT_SUPPORT */
8483 #endif /* MNG_SKIPCANVAS_RGB555 */
8484 
8485 /* ************************************************************************** */
8486 
8487 #ifndef MNG_SKIPCANVAS_BGR555
8488 #ifndef MNG_NO_16BIT_SUPPORT
8489 #ifndef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
mng_display_bgr555(mng_datap pData)8490 mng_retcode mng_display_bgr555 (mng_datap pData)
8491 {
8492   mng_uint8p pScanline;
8493   mng_uint8p pDataline;
8494   mng_int32  iX;
8495   mng_uint16 iA16;
8496   mng_uint16 iFGr16, iFGg16, iFGb16;
8497   mng_uint16 iBGr16, iBGg16, iBGb16;
8498   mng_uint8  iA8;
8499 
8500 #ifdef MNG_SUPPORT_TRACE
8501   MNG_TRACE (pData, MNG_FN_DISPLAY_BGR555, MNG_LC_START);
8502 #endif
8503                                        /* viewable row ? */
8504   if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
8505   {                                    /* address destination row */
8506     pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
8507                                                    pData->iRow + pData->iDestt -
8508                                                    pData->iSourcet);
8509                                        /* adjust destination row starting-point */
8510     pScanline = pScanline + (pData->iCol * 2) + (pData->iDestl * 2);
8511     pDataline = pData->pRGBArow;       /* address source row */
8512 
8513     if (pData->bIsRGBA16)              /* adjust source row starting-point */
8514       pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 3);
8515     else
8516       pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
8517 
8518     if (pData->bIsOpaque)              /* forget about transparency ? */
8519     {
8520       if (pData->bIsRGBA16)            /* 16-bit input row ? */
8521       {
8522         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
8523              iX += pData->iColinc)
8524         {                              /* scale down by dropping the LSB */
8525           *(pScanline+1) = (mng_uint8)( ((*(pDataline  ) & 0xF8) >> 1 ) |  (*(pDataline+2)         >> 6 ) );
8526           *pScanline     = (mng_uint8)( ( *(pDataline+4)         >> 3 ) | ((*(pDataline+2) & 0xF8) << 2 ) );
8527 
8528           pScanline += (pData->iColinc * 2);
8529           pDataline += 8;
8530         }
8531       }
8532       else
8533       {
8534         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
8535              iX += pData->iColinc)
8536         {                              /* copy the values */
8537           *(pScanline+1) = (mng_uint8)( ((*(pDataline  ) & 0xF8) >> 1 ) |  (*(pDataline+1)         >> 6 ) );
8538           *pScanline     = (mng_uint8)( ( *(pDataline+2)         >> 3 ) | ((*(pDataline+1) & 0xF8) << 2 ) );
8539 
8540           pScanline += (pData->iColinc * 2);
8541           pDataline += 4;
8542         }
8543       }
8544     }
8545     else
8546     {
8547       if (pData->bIsRGBA16)            /* 16-bit input row ? */
8548       {
8549 
8550         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
8551              iX += pData->iColinc)
8552         {
8553           iA16 = mng_get_uint16 (pDataline+6);
8554 
8555           if (iA16)                    /* any opacity at all ? */
8556           {
8557             if (iA16 == 0xFFFF)        /* fully opaque ? */
8558             {                          /* scale down by dropping the LSB */
8559               *(pScanline+1) = (mng_uint8)( ((*(pDataline  ) & 0xF8) >> 1 ) |  (*(pDataline+2)         >> 6 ) );
8560               *pScanline     = (mng_uint8)( ( *(pDataline+4)         >> 3 ) | ((*(pDataline+2) & 0xF8) << 2 ) );
8561             }
8562             else
8563             {                          /* get the proper values */
8564               iFGr16 = mng_get_uint16 (pDataline  );
8565               iFGg16 = mng_get_uint16 (pDataline+2);
8566               iFGb16 = mng_get_uint16 (pDataline+4);
8567 
8568 			                           /* scale background up */
8569               iBGb16 = (mng_uint8)( (*(pScanline+1) & 0xF8) << 1 );
8570               iBGg16 = (mng_uint8)( (*(pScanline+1)         << 6 )  |  ( ((*pScanline) & 0xE0) >> 2 ) );
8571               iBGr16 = (mng_uint8)(  *(pScanline  )         << 3 );
8572 
8573               iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
8574               iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
8575               iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
8576                                        /* now compose */
8577               MNG_COMPOSE16(iFGr16, iFGr16, iA16, iBGr16);
8578               MNG_COMPOSE16(iFGg16, iFGg16, iA16, iBGg16);
8579               MNG_COMPOSE16(iFGb16, iFGb16, iA16, iBGb16);
8580                                        /* and return the composed values */
8581               *(pScanline+1) = (mng_uint8)( (mng_uint8)(((iFGr16 >> 8) & 0xF8) >> 1 ) | (   (mng_uint8)(iFGg16 >> 8)         >> 6 ) );
8582               *pScanline     = (mng_uint8)( (mng_uint8) ((iFGb16 >>11)         >> 3 ) | ( ( (mng_uint8)(iFGg16 >> 8) & 0xF8) << 2 ) );
8583             }
8584           }
8585 
8586           pScanline += (pData->iColinc * 2);
8587           pDataline += 8;
8588         }
8589       }
8590       else
8591       {
8592         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
8593              iX += pData->iColinc)
8594         {
8595           iA8 = *(pDataline+3);        /* get alpha value */
8596 
8597           if (iA8)                     /* any opacity at all ? */
8598           {
8599             if (iA8 == 0xFF)           /* fully opaque ? */
8600             {                          /* then simply copy the values */
8601               *(pScanline+1) = (mng_uint8)( ((*(pDataline  ) & 0xF8) >> 1 ) |  (*(pDataline+1)         >> 6 ) );
8602               *pScanline     = (mng_uint8)( ( *(pDataline+2)         >> 3 ) | ((*(pDataline+1) & 0xF8) << 2 ) );
8603             }
8604             else
8605             {                          /* do alpha composing */
8606               mng_uint8 iRed, iGreen, iBlue;
8607 
8608               iRed   = (mng_uint8)( (*(pScanline+1) & 0xF8) << 1 );
8609               iGreen = (mng_uint8)( (*(pScanline+1)         << 6 )  |  ( ((*pScanline) & 0xE0) >> 2 ) );
8610               iBlue  = (mng_uint8)(  *(pScanline  )         << 3 );
8611 
8612               MNG_COMPOSE8 (iRed,     *(pDataline+0), iA8, iRed    );
8613               MNG_COMPOSE8 (iGreen,   *(pDataline+1), iA8, iGreen  );
8614               MNG_COMPOSE8 (iBlue,    *(pDataline+2), iA8, iBlue   );
8615 
8616               *(pScanline+1) = (mng_uint8)( ( (iRed & 0xF8) >> 1 )  |  (  iGreen         >> 6 ) );
8617               *pScanline     = (mng_uint8)(   (iBlue        >> 3 )  |  ( (iGreen & 0xF8) << 2 ) );
8618             }
8619           }
8620 
8621           pScanline += (pData->iColinc * 2);
8622           pDataline += 4;
8623         }
8624       }
8625     }
8626   }
8627 
8628   check_update_region (pData);
8629 
8630 #ifdef MNG_SUPPORT_TRACE
8631   MNG_TRACE (pData, MNG_FN_DISPLAY_BGR555, MNG_LC_END);
8632 #endif
8633 
8634   return MNG_NOERROR;
8635 }
8636 #else /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
mng_display_bgr555(mng_datap pData)8637 mng_retcode mng_display_bgr555 (mng_datap pData)
8638 {
8639   mng_uint8p pScanline;
8640   mng_uint8p pDataline;
8641   mng_int32  iX;
8642   mng_uint16 iA16;
8643   mng_uint16 iFGr16, iFGg16, iFGb16;
8644   mng_uint16 iBGr16, iBGg16, iBGb16;
8645   mng_uint8  iA8;
8646   mng_uint8  iBps;
8647 
8648 #ifdef MNG_SUPPORT_TRACE
8649   MNG_TRACE (pData, MNG_FN_DISPLAY_BGR555, MNG_LC_START);
8650 #endif
8651 
8652   iBps=(mng_uint8)(pData->bIsRGBA16 ? 2:1);
8653                                        /* viewable row ? */
8654   if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
8655   {                                    /* address destination row */
8656     pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
8657                                                    pData->iRow + pData->iDestt -
8658                                                    pData->iSourcet);
8659                                        /* adjust destination row starting-point */
8660     pScanline = pScanline + (pData->iCol * 2) + (pData->iDestl * 2);
8661     pDataline = pData->pRGBArow;       /* address source row */
8662 
8663     /* adjust source row starting-point */
8664     pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << (iBps+1));
8665 
8666     if (pData->bIsOpaque)              /* forget about transparency ? */
8667     {
8668         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
8669              iX += pData->iColinc)
8670         {                              /* scale down by dropping the LSB */
8671           *(pScanline+1) = (mng_uint8)( ((*(pDataline       ) & 0xF8) >> 1 ) |  (*(pDataline+iBps)         >> 6 ) );
8672           *pScanline     = (mng_uint8)( ( *(pDataline+2*iBps)         >> 3 ) | ((*(pDataline+iBps) & 0xF8) << 2 ) );
8673 
8674           pScanline += (pData->iColinc * 2);
8675           pDataline += 4*iBps;
8676         }
8677     }
8678     else
8679     {
8680       if (pData->bIsRGBA16)            /* 16-bit input row ? */
8681       {
8682 
8683         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
8684              iX += pData->iColinc)
8685         {
8686           iA16 = mng_get_uint16 (pDataline+6);
8687 
8688           if (iA16)                    /* any opacity at all ? */
8689           {
8690             if (iA16 == 0xFFFF)        /* fully opaque ? */
8691             {                          /* scale down by dropping the LSB */
8692               *(pScanline+1) = (mng_uint8)( ((*(pDataline  ) & 0xF8) >> 1 ) |  (*(pDataline+2)         >> 6 ) );
8693               *pScanline     = (mng_uint8)( ( *(pDataline+4)         >> 3 ) | ((*(pDataline+2) & 0xF8) << 2 ) );
8694             }
8695             else
8696             {                          /* get the proper values */
8697               iFGr16 = mng_get_uint16 (pDataline  );
8698               iFGg16 = mng_get_uint16 (pDataline+2);
8699               iFGb16 = mng_get_uint16 (pDataline+4);
8700 
8701 			                           /* scale background up */
8702               iBGb16 = (mng_uint8)( (*(pScanline+1) & 0xF8) << 1 );
8703               iBGg16 = (mng_uint8)( (*(pScanline+1)         << 6 )  |  ( ((*pScanline) & 0xE0) >> 2 ) );
8704               iBGr16 = (mng_uint8)(  *(pScanline  )         << 3 );
8705 
8706               iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
8707               iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
8708               iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
8709                                        /* now compose */
8710               MNG_COMPOSE16(iFGr16, iFGr16, iA16, iBGr16);
8711               MNG_COMPOSE16(iFGg16, iFGg16, iA16, iBGg16);
8712               MNG_COMPOSE16(iFGb16, iFGb16, iA16, iBGb16);
8713                                        /* and return the composed values */
8714               *(pScanline+1) = (mng_uint8)( (mng_uint8)(((iFGr16 >> 8) & 0xF8) >> 1 ) | (   (mng_uint8)(iFGg16 >> 8)         >> 6 ) );
8715               *pScanline     = (mng_uint8)( (mng_uint8) ((iFGb16 >>11)         >> 3 ) | ( ( (mng_uint8)(iFGg16 >> 8) & 0xF8) << 2 ) );
8716             }
8717           }
8718 
8719           pScanline += (pData->iColinc * 2);
8720           pDataline += 8;
8721         }
8722       }
8723       else
8724       {
8725         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
8726              iX += pData->iColinc)
8727         {
8728           iA8 = *(pDataline+3);        /* get alpha value */
8729 
8730           if (iA8)                     /* any opacity at all ? */
8731           {
8732             if (iA8 == 0xFF)           /* fully opaque ? */
8733             {                          /* then simply copy the values */
8734               *(pScanline+1) = (mng_uint8)( ((*(pDataline  ) & 0xF8) >> 1 ) |  (*(pDataline+1)         >> 6 ) );
8735               *pScanline     = (mng_uint8)( ( *(pDataline+2)         >> 3 ) | ((*(pDataline+1) & 0xF8) << 2 ) );
8736             }
8737             else
8738             {                          /* do alpha composing */
8739               mng_uint8 iRed, iGreen, iBlue;
8740 
8741               iRed   = (mng_uint8)( (*(pScanline+1) & 0xF8) << 1 );
8742               iGreen = (mng_uint8)( (*(pScanline+1)         << 6 )  |  ( ((*pScanline) & 0xE0) >> 2 ) );
8743               iBlue  = (mng_uint8)(  *(pScanline  )         << 3 );
8744 
8745               MNG_COMPOSE8 (iRed,     *(pDataline+0), iA8, iRed    );
8746               MNG_COMPOSE8 (iGreen,   *(pDataline+1), iA8, iGreen  );
8747               MNG_COMPOSE8 (iBlue,    *(pDataline+2), iA8, iBlue   );
8748 
8749               *(pScanline+1) = (mng_uint8)( ( (iRed & 0xF8) >> 1 )  |  (  iGreen         >> 6 ) );
8750               *pScanline     = (mng_uint8)(   (iBlue        >> 3 )  |  ( (iGreen & 0xF8) << 2 ) );
8751             }
8752           }
8753 
8754           pScanline += (pData->iColinc * 2);
8755           pDataline += 4;
8756         }
8757       }
8758     }
8759   }
8760 
8761   check_update_region (pData);
8762 
8763 #ifdef MNG_SUPPORT_TRACE
8764   MNG_TRACE (pData, MNG_FN_DISPLAY_BGR555, MNG_LC_END);
8765 #endif
8766 
8767   return MNG_NOERROR;
8768 }
8769 #endif /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
8770 #else /* MNG_NO_16BIT_SUPPORT */
mng_display_bgr555(mng_datap pData)8771 mng_retcode mng_display_bgr555 (mng_datap pData)
8772 {
8773   mng_uint8p pScanline;
8774   mng_uint8p pDataline;
8775   mng_int32  iX;
8776   mng_uint8  iA8;
8777 
8778 #ifdef MNG_SUPPORT_TRACE
8779   MNG_TRACE (pData, MNG_FN_DISPLAY_BGR555, MNG_LC_START);
8780 #endif
8781                                        /* viewable row ? */
8782   if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
8783   {                                    /* address destination row */
8784     pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
8785                                                    pData->iRow + pData->iDestt -
8786                                                    pData->iSourcet);
8787                                        /* adjust destination row starting-point */
8788     pScanline = pScanline + (pData->iCol * 2) + (pData->iDestl * 2);
8789     pDataline = pData->pRGBArow;       /* address source row */
8790 
8791       pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
8792 
8793     if (pData->bIsOpaque)              /* forget about transparency ? */
8794     {
8795       {
8796         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
8797              iX += pData->iColinc)
8798         {                              /* copy the values */
8799           *(pScanline+1) = (mng_uint8)( ((*(pDataline  ) & 0xF8) >> 1 ) |  (*(pDataline+1)         >> 6 ) );
8800           *pScanline     = (mng_uint8)( ( *(pDataline+2)         >> 3 ) | ((*(pDataline+1) & 0xF8) << 2 ) );
8801 
8802           pScanline += (pData->iColinc * 2);
8803           pDataline += 4;
8804         }
8805       }
8806     }
8807     else
8808     {
8809       {
8810         for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
8811              iX += pData->iColinc)
8812         {
8813           iA8 = *(pDataline+3);        /* get alpha value */
8814 
8815           if (iA8)                     /* any opacity at all ? */
8816           {
8817             if (iA8 == 0xFF)           /* fully opaque ? */
8818             {                          /* then simply copy the values */
8819               *(pScanline+1) = (mng_uint8)( ((*(pDataline  ) & 0xF8) >> 1 ) |  (*(pDataline+1)         >> 6 ) );
8820               *pScanline     = (mng_uint8)( ( *(pDataline+2)         >> 3 ) | ((*(pDataline+1) & 0xF8) << 2 ) );
8821             }
8822             else
8823             {                          /* do alpha composing */
8824               mng_uint8 iRed, iGreen, iBlue;
8825 
8826               iRed   = (mng_uint8)( (*(pScanline+1) & 0xF8) << 1 );
8827               iGreen = (mng_uint8)( (*(pScanline+1)         << 6 )  |  ( ((*pScanline) & 0xE0) >> 2 ) );
8828               iBlue  = (mng_uint8)(  *(pScanline  )         << 3 );
8829 
8830               MNG_COMPOSE8 (iRed,     *(pDataline+0), iA8, iRed    );
8831               MNG_COMPOSE8 (iGreen,   *(pDataline+1), iA8, iGreen  );
8832               MNG_COMPOSE8 (iBlue,    *(pDataline+2), iA8, iBlue   );
8833 
8834               *(pScanline+1) = (mng_uint8)( ( (iRed & 0xF8) >> 1 )  |  (  iGreen         >> 6 ) );
8835               *pScanline     = (mng_uint8)(   (iBlue        >> 3 )  |  ( (iGreen & 0xF8) << 2 ) );
8836             }
8837           }
8838 
8839           pScanline += (pData->iColinc * 2);
8840           pDataline += 4;
8841         }
8842       }
8843     }
8844   }
8845 
8846   check_update_region (pData);
8847 
8848 #ifdef MNG_SUPPORT_TRACE
8849   MNG_TRACE (pData, MNG_FN_DISPLAY_BGR555, MNG_LC_END);
8850 #endif
8851 
8852   return MNG_NOERROR;
8853 }
8854 #endif /* MNG_NO_16BIT_SUPPORT */
8855 #endif /* MNG_SKIPCANVAS_BGR555 */
8856 
8857 
8858 #ifndef MNG_SKIPCHUNK_BACK
8859 /* ************************************************************************** */
8860 /* *                                                                        * */
8861 /* * Background restore routines - restore the background with info from    * */
8862 /* * the BACK and/or bKGD chunk or the app's background canvas              * */
8863 /* *                                                                        * */
8864 /* ************************************************************************** */
8865 
mng_restore_bkgd_backimage(mng_datap pData)8866 mng_retcode mng_restore_bkgd_backimage (mng_datap pData)
8867 {
8868                                        /* save some stuff */
8869   mng_uint8p  pRGBArow    = pData->pRGBArow;
8870   mng_int32   iRow        = pData->iRow;
8871   mng_int32   iRowsamples = pData->iRowsamples;
8872 
8873   mng_retcode iRetcode;                /* work variables */
8874   mng_uint8p  pTemp;
8875   mng_uint8p  pWork       = pRGBArow;
8876   mng_uint32  iX;
8877   mng_int32   iZ;
8878 
8879 #ifdef MNG_SUPPORT_TRACE
8880   MNG_TRACE (pData, MNG_FN_RESTORE_BACKIMAGE, MNG_LC_START);
8881 #endif
8882                                        /* determine row to retrieve */
8883   pData->iRow        = pData->iDestt + iRow + pData->iBackimgoffsy;
8884 
8885   while (pData->iRow >= (mng_int32)pData->iBackimgheight)
8886     pData->iRow -= (mng_int32)pData->iBackimgheight;
8887                                        /* set width to that of background image */
8888   pData->iRowsamples = pData->iBackimgwidth;
8889                                        /* retrieve into alternate buffer ! */
8890   pData->pRGBArow    = pData->pPrevrow;
8891                                        /* get it then */
8892   iRetcode = ((mng_retrieverow)pData->fRetrieverow) (pData);
8893 
8894   if (iRetcode)                        /* on error; bail out */
8895     return iRetcode;
8896                                        /* we got the full row; but now need to
8897                                           paste it into the proper location */
8898   iX = pData->iDestl - pData->iBackimgoffsx;
8899 
8900   while (iX >= pData->iBackimgwidth)
8901     iX -= pData->iBackimgwidth;
8902 
8903 #ifndef MNG_NO_16BIT_SUPPORT
8904   if (pData->bIsRGBA16)                /* 16-bit buffer ? */
8905   {
8906     pTemp = pData->pPrevrow + (iX << 3);
8907 
8908     for (iZ = (pData->iDestr - pData->iDestl); iZ > 0; iZ--)
8909     {
8910       MNG_COPY (pWork, pTemp, 8);
8911 
8912       pWork += 8;
8913       pTemp += 8;
8914       iX++;
8915                                        /* reached end of bkgd-image line ? */
8916       if (iX >= pData->iBackimgwidth)
8917       {
8918         iX    = 0;
8919         pTemp = pData->pPrevrow;
8920       }
8921     }
8922   }
8923   else
8924 #endif
8925   {
8926     pTemp = pData->pPrevrow + (iX << 2);
8927 
8928     for (iZ = (pData->iDestr - pData->iDestl); iZ > 0; iZ--)
8929     {
8930       MNG_COPY (pWork, pTemp, 4);
8931 
8932       pWork += 4;
8933       pTemp += 4;
8934       iX++;
8935                                        /* reached end of bkgd-image line ? */
8936       if (iX >= pData->iBackimgwidth)
8937       {
8938         iX    = 0;
8939         pTemp = pData->pPrevrow;
8940       }
8941     }
8942   }
8943 
8944   pData->pRGBArow    = pRGBArow;       /* restore original values */
8945   pData->iRow        = iRow;
8946   pData->iRowsamples = iRowsamples;
8947 
8948 #ifdef MNG_SUPPORT_TRACE
8949   MNG_TRACE (pData, MNG_FN_RESTORE_BACKIMAGE, MNG_LC_END);
8950 #endif
8951 
8952   return MNG_NOERROR;
8953 }
8954 #endif
8955 
8956 /* ************************************************************************** */
8957 
mng_restore_bkgd_backcolor(mng_datap pData)8958 mng_retcode mng_restore_bkgd_backcolor (mng_datap pData)
8959 {
8960   mng_int32   iX;
8961   mng_uint32p pWork32 = (mng_uint32p)pData->pRGBArow;
8962   mng_uint32  iWrite;
8963 
8964 #ifdef MNG_SUPPORT_TRACE
8965   MNG_TRACE (pData, MNG_FN_RESTORE_BACKCOLOR, MNG_LC_START);
8966 #endif
8967 
8968 #ifdef MNG_BIGENDIAN_SUPPORTED
8969   /* fast way for big endian */
8970   iWrite = (((mng_uint8)(pData->iBACKred   >> 8)) << 24) |
8971 		   (((mng_uint8)(pData->iBACKgreen >> 8)) << 16) |
8972 		   (((mng_uint8)(pData->iBACKblue  >> 8)) <<  8) |
8973            ( 0xFF                                      );
8974 #elif defined(MNG_LITTLEENDIAN_SUPPORTED)
8975   /* fast way for little endian */
8976   iWrite = ( 0xFF                                 << 24) |
8977            (((mng_uint8)(pData->iBACKblue  >> 8)) << 16) |
8978 		   (((mng_uint8)(pData->iBACKgreen >> 8)) <<  8) |
8979 		   (((mng_uint8)(pData->iBACKred   >> 8))      );
8980 #else
8981   /* generic way, works on all platforms */
8982   /* put the data in memory in the correct order */
8983   {
8984     mng_uint8 aBytes[4];
8985     aBytes[0] = (mng_uint8)(pData->iBACKred   >> 8);
8986     aBytes[1] = (mng_uint8)(pData->iBACKgreen >> 8);
8987     aBytes[2] = (mng_uint8)(pData->iBACKblue  >> 8);
8988     aBytes[3] = 0xFF;
8989     /* load that data into a register */
8990     iWrite = *(mng_uint32*) aBytes;
8991   }
8992 #endif
8993                                        /* ok; drop the background-color in there */
8994   for (iX = (pData->iSourcer - pData->iSourcel); iX > 0; iX--)
8995     *pWork32++ = iWrite;
8996 
8997 #ifdef MNG_SUPPORT_TRACE
8998   MNG_TRACE (pData, MNG_FN_RESTORE_BACKCOLOR, MNG_LC_END);
8999 #endif
9000 
9001   return MNG_NOERROR;
9002 }
9003 
9004 /* ************************************************************************** */
9005 
9006 #ifndef MNG_SKIPCHUNK_bKGD
mng_restore_bkgd_bkgd(mng_datap pData)9007 mng_retcode mng_restore_bkgd_bkgd (mng_datap pData)
9008 {
9009   mng_int32      iX;
9010   mng_uint8p     pWork   = pData->pRGBArow;
9011   mng_imagep     pImage  = (mng_imagep)pData->pCurrentobj;
9012   mng_imagedatap pBuf    = pImage->pImgbuf;
9013   mng_uint8      iRed    = 0;
9014   mng_uint8      iGreen  = 0;
9015   mng_uint8      iBlue   = 0;
9016   mng_uint32p    pWork32 = (mng_uint32p)pWork;
9017   mng_uint32     iWrite;
9018 
9019 #ifdef MNG_SUPPORT_TRACE
9020   MNG_TRACE (pData, MNG_FN_RESTORE_BKGD, MNG_LC_START);
9021 #endif
9022 
9023   switch (pBuf->iColortype)
9024   {
9025     case 0 : ;                         /* gray types */
9026     case 4 : {
9027                mng_uint8 iGray;
9028 
9029 #ifndef MNG_NO_16BIT_SUPPORT
9030                if (pBuf->iBitdepth > 8)
9031                  iGray = (mng_uint8)(pBuf->iBKGDgray >> 8);
9032                else
9033 #endif
9034                {
9035 #ifndef MNG_NO_1_2_4BIT_SUPPORT
9036                  /* LBR scaling */
9037                  mng_uint8 multiplier[]={0,255,85,0,17,0,0,0,1};
9038                  iGray = (mng_uint8)(multiplier[pBuf->iBitdepth] * pBuf->iBKGDgray);
9039 #else
9040                  iGray = (mng_uint8)pBuf->iBKGDgray;
9041 #endif
9042                }
9043 
9044                iRed   = iGray;
9045                iGreen = iGray;
9046                iBlue  = iGray;
9047 
9048                break;
9049              }
9050 
9051     case 3 : {                         /* indexed type */
9052                iRed   = pBuf->aPLTEentries [pBuf->iBKGDindex].iRed;
9053                iGreen = pBuf->aPLTEentries [pBuf->iBKGDindex].iGreen;
9054                iBlue  = pBuf->aPLTEentries [pBuf->iBKGDindex].iBlue;
9055 
9056                break;
9057              }
9058 
9059     case 2 : ;                         /* rgb types */
9060     case 6 : {
9061 #ifndef MNG_NO_16BIT_SUPPORT
9062                if (pBuf->iBitdepth > 8)
9063                {
9064                  iRed   = (mng_uint8)(pBuf->iBKGDred   >> 8);
9065                  iGreen = (mng_uint8)(pBuf->iBKGDgreen >> 8);
9066                  iBlue  = (mng_uint8)(pBuf->iBKGDblue  >> 8);
9067                }
9068                else
9069 #endif
9070                {
9071                  iRed   = (mng_uint8)(pBuf->iBKGDred  );
9072                  iGreen = (mng_uint8)(pBuf->iBKGDgreen);
9073                  iBlue  = (mng_uint8)(pBuf->iBKGDblue );
9074                }
9075 
9076                break;
9077              }
9078   }
9079 
9080 #ifdef MNG_BIGENDIAN_SUPPORTED
9081   /* fast way for big endian */
9082   iWrite = (iRed   << 24) |
9083 		   (iGreen << 16) |
9084 		   (iBlue  <<  8);
9085 #elif defined(MNG_LITTLEENDIAN_SUPPORTED)
9086   /* fast way for little endian */
9087   iWrite = (iBlue  << 16) |
9088 		   (iGreen <<  8) |
9089 		   (iRed        );
9090 #else
9091   /* generic way, works on all platforms */
9092   /* put the data in memory in the correct order */
9093   {
9094     mng_uint8 aBytes[4];
9095     aBytes[0] = (mng_uint8)(iRed);
9096     aBytes[1] = (mng_uint8)(iGreen);
9097     aBytes[2] = (mng_uint8)(iBlue);
9098     aBytes[3] = 0x00;
9099     /* load that data into a register */
9100     iWrite = *(mng_uint32*) aBytes;
9101   }
9102 #endif
9103                                        /* ok; drop it in there */
9104   for (iX = (pData->iSourcer - pData->iSourcel); iX > 0; iX--)
9105     *pWork32++ = iWrite;
9106 
9107 #ifdef MNG_SUPPORT_TRACE
9108   MNG_TRACE (pData, MNG_FN_RESTORE_BKGD, MNG_LC_END);
9109 #endif
9110 
9111   return MNG_NOERROR;
9112 }
9113 #endif
9114 
9115 /* ************************************************************************** */
9116 
mng_restore_bkgd_bgcolor(mng_datap pData)9117 mng_retcode mng_restore_bkgd_bgcolor (mng_datap pData)
9118 {
9119   mng_int32   iX;
9120   mng_uint32p pWork32 = (mng_uint32p)pData->pRGBArow;
9121   mng_uint32  iWrite;
9122 
9123 #ifdef MNG_SUPPORT_TRACE
9124   MNG_TRACE (pData, MNG_FN_RESTORE_BGCOLOR, MNG_LC_START);
9125 #endif
9126 
9127 #ifdef MNG_BIGENDIAN_SUPPORTED
9128   /* fast way for big endian */
9129   iWrite = (((mng_uint8)(pData->iBGred   >> 8)) << 24) |
9130 		   (((mng_uint8)(pData->iBGgreen >> 8)) << 16) |
9131 		   (((mng_uint8)(pData->iBGblue  >> 8)) <<  8);
9132 #elif defined(MNG_LITTLEENDIAN_SUPPORTED)
9133   /* fast way for little endian */
9134   iWrite = (((mng_uint8)(pData->iBGblue  >> 8)) << 16) |
9135 		   (((mng_uint8)(pData->iBGgreen >> 8)) <<  8) |
9136 		   (((mng_uint8)(pData->iBGred   >> 8))      );
9137 #else
9138   /* generic way, works on all platforms */
9139   /* put the data in memory in the correct order */
9140   {
9141     mng_uint8 aBytes[4];
9142     aBytes[0] = (mng_uint8)(pData->iBGred   >> 8);
9143     aBytes[1] = (mng_uint8)(pData->iBGgreen >> 8);
9144     aBytes[2] = (mng_uint8)(pData->iBGblue  >> 8);
9145     aBytes[3] = 0x00;
9146     /* load that data into a register */
9147     iWrite = *(mng_uint32*) aBytes;
9148   }
9149 #endif
9150                                        /* ok; drop the background-color in there */
9151   for (iX = (pData->iSourcer - pData->iSourcel); iX > 0; iX--)
9152     *pWork32++ = iWrite;
9153 
9154 #ifdef MNG_SUPPORT_TRACE
9155   MNG_TRACE (pData, MNG_FN_RESTORE_BGCOLOR, MNG_LC_END);
9156 #endif
9157 
9158   return MNG_NOERROR;
9159 }
9160 
9161 /* ************************************************************************** */
9162 
9163 #ifndef MNG_SKIPCANVAS_RGB8
mng_restore_bkgd_rgb8(mng_datap pData)9164 mng_retcode mng_restore_bkgd_rgb8 (mng_datap pData)
9165 {
9166   mng_int32  iX;
9167   mng_uint8p pBkgd;
9168   mng_uint8p pWork = pData->pRGBArow;
9169 
9170 #ifdef MNG_SUPPORT_TRACE
9171   MNG_TRACE (pData, MNG_FN_RESTORE_RGB8, MNG_LC_START);
9172 #endif
9173 
9174   if (pData->fGetbkgdline)             /* can we access the background ? */
9175   {                                    /* point to the right pixel then */
9176     pBkgd = (mng_uint8p)pData->fGetbkgdline ((mng_handle)pData,
9177                                              pData->iRow + pData->iDestt) +
9178             (3 * pData->iDestl);
9179 
9180     for (iX = (pData->iSourcer - pData->iSourcel); iX > 0; iX--)
9181     {
9182       *pWork     = *pBkgd;             /* ok; copy the pixel */
9183       *(pWork+1) = *(pBkgd+1);
9184       *(pWork+2) = *(pBkgd+2);
9185       *(pWork+3) = 0x00;               /* transparant for alpha-canvasses */
9186 
9187       pWork += 4;
9188       pBkgd += 3;
9189     }
9190   }
9191 
9192 #ifdef MNG_SUPPORT_TRACE
9193   MNG_TRACE (pData, MNG_FN_RESTORE_RGB8, MNG_LC_END);
9194 #endif
9195 
9196   return MNG_NOERROR;
9197 }
9198 #endif /* MNG_SKIPCANVAS_RGB8 */
9199 
9200 /* ************************************************************************** */
9201 
9202 #ifndef MNG_SKIPCANVAS_BGR8
mng_restore_bkgd_bgr8(mng_datap pData)9203 mng_retcode mng_restore_bkgd_bgr8 (mng_datap pData)
9204 {
9205   mng_int32  iX;
9206   mng_uint8p pBkgd;
9207   mng_uint8p pWork = pData->pRGBArow;
9208 
9209 #ifdef MNG_SUPPORT_TRACE
9210   MNG_TRACE (pData, MNG_FN_RESTORE_BGR8, MNG_LC_START);
9211 #endif
9212 
9213   if (pData->fGetbkgdline)             /* can we access the background ? */
9214   {                                    /* point to the right pixel then */
9215     pBkgd = (mng_uint8p)pData->fGetbkgdline ((mng_handle)pData,
9216                                              pData->iRow + pData->iDestt) +
9217             (3 * pData->iDestl);
9218 
9219     for (iX = (pData->iSourcer - pData->iSourcel); iX > 0; iX--)
9220     {
9221       *pWork     = *(pBkgd+2);         /* ok; copy the pixel */
9222       *(pWork+1) = *(pBkgd+1);
9223       *(pWork+2) = *pBkgd;
9224       *(pWork+3) = 0x00;               /* transparant for alpha-canvasses */
9225 
9226       pWork += 4;
9227       pBkgd += 3;
9228     }
9229   }
9230 
9231 #ifdef MNG_SUPPORT_TRACE
9232   MNG_TRACE (pData, MNG_FN_RESTORE_BGR8, MNG_LC_END);
9233 #endif
9234 
9235   return MNG_NOERROR;
9236 }
9237 #endif /* MNG_SKIPCANVAS_BGR8 */
9238 
9239 /* ************************************************************************** */
9240 
9241 #ifndef MNG_SKIPCANVAS_BGRX8
mng_restore_bkgd_bgrx8(mng_datap pData)9242 mng_retcode mng_restore_bkgd_bgrx8 (mng_datap pData)
9243 {
9244   mng_int32  iX;
9245   mng_uint8p pBkgd;
9246   mng_uint8p pWork = pData->pRGBArow;
9247 
9248 #ifdef MNG_SUPPORT_TRACE
9249   MNG_TRACE (pData, MNG_FN_RESTORE_BGRX8, MNG_LC_START);
9250 #endif
9251 
9252   if (pData->fGetbkgdline)             /* can we access the background ? */
9253   {                                    /* point to the right pixel then */
9254     pBkgd = (mng_uint8p)pData->fGetbkgdline ((mng_handle)pData,
9255                                              pData->iRow + pData->iDestt) +
9256             (3 * pData->iDestl);
9257 
9258     for (iX = (pData->iSourcer - pData->iSourcel); iX > 0; iX--)
9259     {
9260       *pWork     = *(pBkgd+2);         /* ok; copy the pixel */
9261       *(pWork+1) = *(pBkgd+1);
9262       *(pWork+2) = *pBkgd;
9263       *(pWork+3) = 0x00;               /* transparant for alpha-canvasses */
9264 
9265       pWork += 4;
9266       pBkgd += 4;
9267     }
9268   }
9269 
9270 #ifdef MNG_SUPPORT_TRACE
9271   MNG_TRACE (pData, MNG_FN_RESTORE_BGRX8, MNG_LC_END);
9272 #endif
9273 
9274   return MNG_NOERROR;
9275 }
9276 #endif /* MNG_SKIPCANVAS_BGRX8 */
9277 
9278 /* ************************************************************************** */
9279 
9280 #ifndef MNG_SKIPCANVAS_BGR565
mng_restore_bkgd_bgr565(mng_datap pData)9281 mng_retcode mng_restore_bkgd_bgr565 (mng_datap pData)
9282 {
9283   mng_int32  iX;
9284   mng_uint8p pBkgd;
9285   mng_uint8p pWork = pData->pRGBArow;
9286 
9287 #ifdef MNG_SUPPORT_TRACE
9288   MNG_TRACE (pData, MNG_FN_RESTORE_BGR565, MNG_LC_START);
9289 #endif
9290 
9291   if (pData->fGetbkgdline)             /* can we access the background ? */
9292   {                                    /* point to the right pixel then */
9293     pBkgd = (mng_uint8p)pData->fGetbkgdline ((mng_handle)pData,
9294                                              pData->iRow + pData->iDestt) +
9295             (3 * pData->iDestl);
9296 
9297     for (iX = (pData->iSourcer - pData->iSourcel); iX > 0; iX--)
9298     {
9299       *pWork     = (mng_uint8)(  *(pBkgd+1) & 0xF8);             /* ok; copy the pixel */
9300       *(pWork+1) = (mng_uint8)( (*(pBkgd+1) << 5 )  |  ( ((*pBkgd)&0xE0)>>3 ) );
9301       *(pWork+2) = (mng_uint8)(  *(pBkgd) << 3 );
9302       *(pWork+3) = 0x00;               /* transparant for alpha-canvasses */
9303 
9304       pWork += 4;
9305       pBkgd += 2;
9306     }
9307   }
9308 
9309 #ifdef MNG_SUPPORT_TRACE
9310   MNG_TRACE (pData, MNG_FN_RESTORE_BGR565, MNG_LC_END);
9311 #endif
9312 
9313   return MNG_NOERROR;
9314 }
9315 #endif /* MNG_SKIPCANVAS_BGR565 */
9316 
9317 /* ************************************************************************** */
9318 
9319 #ifndef MNG_SKIPCANVAS_RGB565
mng_restore_bkgd_rgb565(mng_datap pData)9320 mng_retcode mng_restore_bkgd_rgb565 (mng_datap pData)
9321 {
9322   mng_int32  iX;
9323   mng_uint8p pBkgd;
9324   mng_uint8p pWork = pData->pRGBArow;
9325 
9326 #ifdef MNG_SUPPORT_TRACE
9327   MNG_TRACE (pData, MNG_FN_RESTORE_RGB565, MNG_LC_START);
9328 #endif
9329 
9330   if (pData->fGetbkgdline)             /* can we access the background ? */
9331   {                                    /* point to the right pixel then */
9332     pBkgd = (mng_uint8p)pData->fGetbkgdline ((mng_handle)pData,
9333                                              pData->iRow + pData->iDestt) +
9334             (3 * pData->iDestl);
9335 
9336     for (iX = (pData->iSourcer - pData->iSourcel); iX > 0; iX--)
9337     {
9338       *pWork     = (mng_uint8)(  *(pBkgd)&0xF8);             /* ok; copy the pixel */
9339       *(pWork+1) = (mng_uint8)( (*(pBkgd+1) << 5)  |  ( ((*pBkgd)&0xE0)>>3 ) );
9340       *(pWork+2) = (mng_uint8)(  *(pBkgd+1) << 3);
9341       *(pWork+3) = 0x00;               /* transparant for alpha-canvasses */
9342 
9343       pWork += 4;
9344       pBkgd += 2;
9345     }
9346   }
9347 
9348 #ifdef MNG_SUPPORT_TRACE
9349   MNG_TRACE (pData, MNG_FN_RESTORE_RGB565, MNG_LC_END);
9350 #endif
9351 
9352   return MNG_NOERROR;
9353 }
9354 #endif /* MNG_SKIPCANVAS_RBB565 */
9355 
9356 
9357 /* ************************************************************************** */
9358 /* *                                                                        * */
9359 /* * Row retrieval routines - retrieve processed & uncompressed row-data    * */
9360 /* * from the current "object"                                              * */
9361 /* *                                                                        * */
9362 /* ************************************************************************** */
9363 
9364 /* TODO: a serious optimization is to retrieve only those pixels that will
9365          actually be displayed; this would require changes in
9366          the "display_image" routine (in mng_display.c) &
9367          all the "retrieve_xxx" routines below &
9368          the "display_xxx" routines above !!!!!
9369          NOTE that "correct_xxx" routines would not require modification */
9370 
mng_retrieve_g8(mng_datap pData)9371 mng_retcode mng_retrieve_g8 (mng_datap pData)
9372 {
9373   mng_imagedatap pBuf = ((mng_imagep)pData->pRetrieveobj)->pImgbuf;
9374   mng_uint8p     pWorkrow;
9375   mng_uint8p     pRGBArow;
9376   mng_int32      iX;
9377   mng_uint8      iG;
9378 
9379 #ifdef MNG_SUPPORT_TRACE
9380   MNG_TRACE (pData, MNG_FN_RETRIEVE_G8, MNG_LC_START);
9381 #endif
9382 
9383   pRGBArow = pData->pRGBArow;          /* temporary work pointers */
9384   pWorkrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize);
9385 
9386   if (pBuf->bHasTRNS)                  /* tRNS in buffer ? */
9387   {
9388 #ifdef MNG_DECREMENT_LOOPS
9389     for (iX = pData->iRowsamples; iX > 0; iX--)
9390 #else
9391     for (iX = 0; iX < pData->iRowsamples; iX++)
9392 #endif
9393     {
9394       iG = *pWorkrow;                  /* get the gray-value */
9395                                        /* is it transparent ? */
9396       if ((mng_uint16)iG == pBuf->iTRNSgray)
9397       {
9398         *pRGBArow     = 0x00;          /* nuttin to display */
9399         *(pRGBArow+1) = 0x00;
9400         *(pRGBArow+2) = 0x00;
9401         *(pRGBArow+3) = 0x00;
9402       }
9403       else
9404       {
9405 #ifndef MNG_NO_1_2_4BIT_SUPPORT
9406         mng_uint8 multiplier[]={0,255,85,0,17,0,0,0,1};
9407         iG = (mng_uint8)(iG * multiplier[pBuf->iBitdepth]);
9408 #endif
9409 
9410         *pRGBArow     = iG;            /* put in intermediate row */
9411         *(pRGBArow+1) = iG;
9412         *(pRGBArow+2) = iG;
9413         *(pRGBArow+3) = 0xFF;
9414       }
9415 
9416       pWorkrow++;                      /* next pixel */
9417       pRGBArow += 4;
9418     }
9419   }
9420   else
9421   {
9422 #ifdef MNG_DECREMENT_LOOPS
9423     for (iX = pData->iRowsamples; iX > 0; iX--)
9424 #else
9425     for (iX = 0; iX < pData->iRowsamples; iX++)
9426 #endif
9427     {
9428 #ifndef MNG_NO_1_2_4BIT_SUPPORT
9429       mng_uint8 multiplier[]={0,255,85,0,17,0,0,0,1};   /* LBR scaling */
9430       iG = (mng_uint8)(multiplier[pBuf->iBitdepth] * *pWorkrow);
9431 #else
9432       iG = *pWorkrow;                  /* get the gray-value */
9433 #endif
9434 
9435       *pRGBArow     = iG;              /* put in intermediate row */
9436       *(pRGBArow+1) = iG;
9437       *(pRGBArow+2) = iG;
9438       *(pRGBArow+3) = 0xFF;
9439 
9440       pWorkrow++;                      /* next pixel */
9441       pRGBArow += 4;
9442     }
9443   }
9444 
9445 #ifdef MNG_SUPPORT_TRACE
9446   MNG_TRACE (pData, MNG_FN_RETRIEVE_G8, MNG_LC_END);
9447 #endif
9448 
9449   return MNG_NOERROR;
9450 }
9451 
9452 /* ************************************************************************** */
9453 
9454 #ifndef MNG_NO_16BIT_SUPPORT
mng_retrieve_g16(mng_datap pData)9455 mng_retcode mng_retrieve_g16 (mng_datap pData)
9456 {
9457   mng_imagedatap pBuf = ((mng_imagep)pData->pRetrieveobj)->pImgbuf;
9458   mng_uint8p     pWorkrow;
9459   mng_uint8p     pRGBArow;
9460   mng_int32      iX;
9461   mng_uint16     iG;
9462 
9463 #ifdef MNG_SUPPORT_TRACE
9464   MNG_TRACE (pData, MNG_FN_RETRIEVE_G16, MNG_LC_START);
9465 #endif
9466                                        /* temporary work pointers */
9467   pRGBArow = pData->pRGBArow;
9468   pWorkrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize);
9469 
9470   if (pBuf->bHasTRNS)                  /* tRNS in buffer ? */
9471   {
9472 #ifdef MNG_DECREMENT_LOOPS
9473     for (iX = pData->iRowsamples; iX > 0; iX--)
9474 #else
9475     for (iX = 0; iX < pData->iRowsamples; iX++)
9476 #endif
9477     {
9478       iG = mng_get_uint16 (pWorkrow);  /* get the gray-value */
9479                                        /* is it transparent ? */
9480       if (iG == pBuf->iTRNSgray)
9481       {                                /* nuttin to display */
9482         mng_put_uint16 (pRGBArow,   0x0000);
9483         mng_put_uint16 (pRGBArow+2, 0x0000);
9484         mng_put_uint16 (pRGBArow+4, 0x0000);
9485         mng_put_uint16 (pRGBArow+6, 0x0000);
9486       }
9487       else
9488       {                                /* put in intermediate row */
9489         mng_put_uint16 (pRGBArow,   iG);
9490         mng_put_uint16 (pRGBArow+2, iG);
9491         mng_put_uint16 (pRGBArow+4, iG);
9492         mng_put_uint16 (pRGBArow+6, 0xFFFF);
9493       }
9494 
9495       pWorkrow += 2;                   /* next pixel */
9496       pRGBArow += 8;
9497     }
9498   }
9499   else
9500   {
9501 #ifdef MNG_DECREMENT_LOOPS
9502     for (iX = pData->iRowsamples; iX > 0; iX--)
9503 #else
9504     for (iX = 0; iX < pData->iRowsamples; iX++)
9505 #endif
9506     {
9507       iG = mng_get_uint16 (pWorkrow);  /* get the gray-value */
9508 
9509       mng_put_uint16 (pRGBArow,   iG); /* and put in intermediate row */
9510       mng_put_uint16 (pRGBArow+2, iG);
9511       mng_put_uint16 (pRGBArow+4, iG);
9512       mng_put_uint16 (pRGBArow+6, 0xFFFF);
9513 
9514       pWorkrow += 2;                  /* next pixel */
9515       pRGBArow += 8;
9516     }
9517   }
9518 
9519 #ifdef MNG_SUPPORT_TRACE
9520   MNG_TRACE (pData, MNG_FN_RETRIEVE_G16, MNG_LC_END);
9521 #endif
9522 
9523   return MNG_NOERROR;
9524 }
9525 #endif
9526 
9527 /* ************************************************************************** */
9528 
mng_retrieve_rgb8(mng_datap pData)9529 mng_retcode mng_retrieve_rgb8 (mng_datap pData)
9530 {
9531   mng_imagedatap pBuf = ((mng_imagep)pData->pRetrieveobj)->pImgbuf;
9532   mng_uint8p     pWorkrow;
9533   mng_uint8p     pRGBArow;
9534   mng_int32      iX;
9535   mng_uint8      iR, iG, iB;
9536 
9537 #ifdef MNG_SUPPORT_TRACE
9538   MNG_TRACE (pData, MNG_FN_RETRIEVE_RGB8, MNG_LC_START);
9539 #endif
9540 
9541   pRGBArow = pData->pRGBArow;          /* temporary work pointers */
9542   pWorkrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize);
9543 
9544   if (pBuf->bHasTRNS)                  /* tRNS in buffer ? */
9545   {
9546 #ifdef MNG_DECREMENT_LOOPS
9547     for (iX = pData->iRowsamples; iX > 0; iX--)
9548 #else
9549     for (iX = 0; iX < pData->iRowsamples; iX++)
9550 #endif
9551     {
9552       iR = *pWorkrow;                  /* get the rgb-values */
9553       iG = *(pWorkrow+1);
9554       iB = *(pWorkrow+2);
9555                                        /* is it transparent ? */
9556       if (((mng_uint16)iR == pBuf->iTRNSred  ) &&
9557           ((mng_uint16)iG == pBuf->iTRNSgreen) &&
9558           ((mng_uint16)iB == pBuf->iTRNSblue )    )
9559       {
9560         *pRGBArow     = 0x00;          /* nothing to display */
9561         *(pRGBArow+1) = 0x00;
9562         *(pRGBArow+2) = 0x00;
9563         *(pRGBArow+3) = 0x00;
9564       }
9565       else
9566       {
9567         *pRGBArow     = iR;            /* put in intermediate row */
9568         *(pRGBArow+1) = iG;
9569         *(pRGBArow+2) = iB;
9570         *(pRGBArow+3) = 0xFF;
9571       }
9572 
9573       pWorkrow += 3;                   /* next pixel */
9574       pRGBArow += 4;
9575     }
9576   }
9577   else
9578   {
9579 #ifdef MNG_DECREMENT_LOOPS
9580     for (iX = pData->iRowsamples; iX > 0; iX--)
9581 #else
9582     for (iX = 0; iX < pData->iRowsamples; iX++)
9583 #endif
9584     {
9585       *pRGBArow     = *pWorkrow;       /* just copy the pixel */
9586       *(pRGBArow+1) = *(pWorkrow+1);
9587       *(pRGBArow+2) = *(pWorkrow+2);
9588       *(pRGBArow+3) = 0xFF;
9589 
9590       pWorkrow += 3;                   /* next pixel */
9591       pRGBArow += 4;
9592     }
9593   }
9594 
9595 #ifdef MNG_SUPPORT_TRACE
9596   MNG_TRACE (pData, MNG_FN_RETRIEVE_RGB8, MNG_LC_END);
9597 #endif
9598 
9599   return MNG_NOERROR;
9600 }
9601 
9602 /* ************************************************************************** */
9603 
9604 #ifndef MNG_NO_16BIT_SUPPORT
mng_retrieve_rgb16(mng_datap pData)9605 mng_retcode mng_retrieve_rgb16 (mng_datap pData)
9606 {
9607   mng_imagedatap pBuf = ((mng_imagep)pData->pRetrieveobj)->pImgbuf;
9608   mng_uint8p     pWorkrow;
9609   mng_uint8p     pRGBArow;
9610   mng_int32      iX;
9611   mng_uint16     iR, iG, iB;
9612 
9613 #ifdef MNG_SUPPORT_TRACE
9614   MNG_TRACE (pData, MNG_FN_RETRIEVE_RGB16, MNG_LC_START);
9615 #endif
9616                                        /* temporary work pointers */
9617   pRGBArow = pData->pRGBArow;
9618   pWorkrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize);
9619 
9620   if (pBuf->bHasTRNS)                  /* tRNS in buffer ? */
9621   {
9622 #ifdef MNG_DECREMENT_LOOPS
9623     for (iX = pData->iRowsamples; iX > 0; iX--)
9624 #else
9625     for (iX = 0; iX < pData->iRowsamples; iX++)
9626 #endif
9627     {
9628       iR = mng_get_uint16 (pWorkrow);  /* get the rgb-values */
9629       iG = mng_get_uint16 (pWorkrow+2);
9630       iB = mng_get_uint16 (pWorkrow+4);
9631                                        /* is it transparent ? */
9632       if ((iR == pBuf->iTRNSred  ) &&
9633           (iG == pBuf->iTRNSgreen) &&
9634           (iB == pBuf->iTRNSblue )    )
9635       {                                /* nothing to display */
9636         mng_put_uint16 (pRGBArow,   0x0000);
9637         mng_put_uint16 (pRGBArow+2, 0x0000);
9638         mng_put_uint16 (pRGBArow+4, 0x0000);
9639         mng_put_uint16 (pRGBArow+6, 0x0000);
9640       }
9641       else
9642       {                                /* put in intermediate row */
9643         mng_put_uint16 (pRGBArow,   iR);
9644         mng_put_uint16 (pRGBArow+2, iG);
9645         mng_put_uint16 (pRGBArow+4, iB);
9646         mng_put_uint16 (pRGBArow+6, 0xFFFF);
9647       }
9648 
9649       pWorkrow += 6;                   /* next pixel */
9650       pRGBArow += 8;
9651     }
9652   }
9653   else
9654   {
9655 #ifdef MNG_DECREMENT_LOOPS
9656     for (iX = pData->iRowsamples; iX > 0; iX--)
9657 #else
9658     for (iX = 0; iX < pData->iRowsamples; iX++)
9659 #endif
9660     {                                  /* just copy the pixel */
9661       mng_put_uint16 (pRGBArow,   mng_get_uint16 (pWorkrow  ));
9662       mng_put_uint16 (pRGBArow+2, mng_get_uint16 (pWorkrow+2));
9663       mng_put_uint16 (pRGBArow+4, mng_get_uint16 (pWorkrow+4));
9664       mng_put_uint16 (pRGBArow+6, 0xFFFF);
9665 
9666       pWorkrow += 6;                   /* next pixel */
9667       pRGBArow += 8;
9668     }
9669   }
9670 
9671 #ifdef MNG_SUPPORT_TRACE
9672   MNG_TRACE (pData, MNG_FN_RETRIEVE_RGB16, MNG_LC_END);
9673 #endif
9674 
9675   return MNG_NOERROR;
9676 }
9677 #endif
9678 
9679 /* ************************************************************************** */
9680 
mng_retrieve_idx8(mng_datap pData)9681 mng_retcode mng_retrieve_idx8 (mng_datap pData)
9682 {
9683   mng_imagedatap pBuf = ((mng_imagep)pData->pRetrieveobj)->pImgbuf;
9684   mng_uint8p     pWorkrow;
9685   mng_uint8p     pRGBArow;
9686   mng_int32      iX;
9687   mng_uint8      iQ;
9688 
9689 #ifdef MNG_SUPPORT_TRACE
9690   MNG_TRACE (pData, MNG_FN_RETRIEVE_IDX8, MNG_LC_START);
9691 #endif
9692 
9693   pRGBArow = pData->pRGBArow;          /* temporary work pointers */
9694   pWorkrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize);
9695 
9696   if (pBuf->bHasTRNS)                  /* tRNS in buffer ? */
9697   {
9698 #ifdef MNG_DECREMENT_LOOPS
9699     for (iX = pData->iRowsamples; iX > 0; iX--)
9700 #else
9701     for (iX = 0; iX < pData->iRowsamples; iX++)
9702 #endif
9703     {
9704       iQ = *pWorkrow;                  /* get the index */
9705                                        /* is it valid ? */
9706       if ((mng_uint32)iQ < pBuf->iPLTEcount)
9707       {                                /* put in intermediate row */
9708         *pRGBArow     = pBuf->aPLTEentries [iQ].iRed;
9709         *(pRGBArow+1) = pBuf->aPLTEentries [iQ].iGreen;
9710         *(pRGBArow+2) = pBuf->aPLTEentries [iQ].iBlue;
9711                                        /* transparency for this index ? */
9712         if ((mng_uint32)iQ < pBuf->iTRNScount)
9713           *(pRGBArow+3) = pBuf->aTRNSentries [iQ];
9714         else
9715           *(pRGBArow+3) = 0xFF;
9716       }
9717       else
9718         MNG_ERROR (pData, MNG_PLTEINDEXERROR);
9719 
9720       pWorkrow++;                      /* next pixel */
9721       pRGBArow += 4;
9722     }
9723   }
9724   else
9725   {
9726 #ifdef MNG_DECREMENT_LOOPS
9727     for (iX = pData->iRowsamples; iX > 0; iX--)
9728 #else
9729     for (iX = 0; iX < pData->iRowsamples; iX++)
9730 #endif
9731     {
9732       iQ = *pWorkrow;                  /* get the index */
9733                                        /* is it valid ? */
9734       if ((mng_uint32)iQ < pBuf->iPLTEcount)
9735       {                                /* put in intermediate row */
9736         *pRGBArow     = pBuf->aPLTEentries [iQ].iRed;
9737         *(pRGBArow+1) = pBuf->aPLTEentries [iQ].iGreen;
9738         *(pRGBArow+2) = pBuf->aPLTEentries [iQ].iBlue;
9739         *(pRGBArow+3) = 0xFF;
9740       }
9741       else
9742         MNG_ERROR (pData, MNG_PLTEINDEXERROR);
9743 
9744       pWorkrow++;                      /* next pixel */
9745       pRGBArow += 4;
9746     }
9747   }
9748 
9749 #ifdef MNG_SUPPORT_TRACE
9750   MNG_TRACE (pData, MNG_FN_RETRIEVE_IDX8, MNG_LC_END);
9751 #endif
9752 
9753   return MNG_NOERROR;
9754 }
9755 
9756 /* ************************************************************************** */
9757 
mng_retrieve_ga8(mng_datap pData)9758 mng_retcode mng_retrieve_ga8 (mng_datap pData)
9759 {
9760   mng_imagedatap pBuf = ((mng_imagep)pData->pRetrieveobj)->pImgbuf;
9761   mng_uint8p     pWorkrow;
9762   mng_uint8p     pRGBArow;
9763   mng_int32      iX;
9764   mng_uint8      iG;
9765 
9766 #ifdef MNG_SUPPORT_TRACE
9767   MNG_TRACE (pData, MNG_FN_RETRIEVE_GA8, MNG_LC_START);
9768 #endif
9769 
9770   pRGBArow = pData->pRGBArow;          /* temporary work pointers */
9771   pWorkrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize);
9772 
9773 #ifdef MNG_DECREMENT_LOOPS
9774   for (iX = pData->iRowsamples; iX > 0; iX--)
9775 #else
9776   for (iX = 0; iX < pData->iRowsamples; iX++)
9777 #endif
9778   {
9779     iG = *pWorkrow;                    /* get the gray-value */
9780     *pRGBArow     = iG;                /* put in intermediate row */
9781     *(pRGBArow+1) = iG;
9782     *(pRGBArow+2) = iG;
9783     *(pRGBArow+3) = *(pWorkrow+1);
9784 
9785     pWorkrow += 2;                     /* next pixel */
9786     pRGBArow += 4;
9787   }
9788 
9789 #ifdef MNG_SUPPORT_TRACE
9790   MNG_TRACE (pData, MNG_FN_RETRIEVE_GA8, MNG_LC_END);
9791 #endif
9792 
9793   return MNG_NOERROR;
9794 }
9795 
9796 /* ************************************************************************** */
9797 
9798 #ifndef MNG_NO_16BIT_SUPPORT
mng_retrieve_ga16(mng_datap pData)9799 mng_retcode mng_retrieve_ga16 (mng_datap pData)
9800 {
9801   mng_imagedatap pBuf = ((mng_imagep)pData->pRetrieveobj)->pImgbuf;
9802   mng_uint8p     pWorkrow;
9803   mng_uint8p     pRGBArow;
9804   mng_int32      iX;
9805   mng_uint16     iG;
9806 
9807 #ifdef MNG_SUPPORT_TRACE
9808   MNG_TRACE (pData, MNG_FN_RETRIEVE_GA16, MNG_LC_START);
9809 #endif
9810                                        /* temporary work pointers */
9811   pRGBArow = pData->pRGBArow;
9812   pWorkrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize);
9813 
9814 #ifdef MNG_DECREMENT_LOOPS
9815   for (iX = pData->iRowsamples; iX > 0; iX--)
9816 #else
9817   for (iX = 0; iX < pData->iRowsamples; iX++)
9818 #endif
9819   {
9820     iG = mng_get_uint16 (pWorkrow);    /* get the gray-value */
9821 
9822     mng_put_uint16 (pRGBArow,   iG);   /* and put in intermediate row */
9823     mng_put_uint16 (pRGBArow+2, iG);
9824     mng_put_uint16 (pRGBArow+4, iG);
9825     mng_put_uint16 (pRGBArow+6, mng_get_uint16 (pWorkrow+2));
9826 
9827     pWorkrow += 4;                     /* next pixel */
9828     pRGBArow += 8;
9829   }
9830 
9831 #ifdef MNG_SUPPORT_TRACE
9832   MNG_TRACE (pData, MNG_FN_RETRIEVE_GA16, MNG_LC_END);
9833 #endif
9834 
9835   return MNG_NOERROR;
9836 }
9837 #endif
9838 
9839 /* ************************************************************************** */
9840 
mng_retrieve_rgba8(mng_datap pData)9841 mng_retcode mng_retrieve_rgba8 (mng_datap pData)
9842 {
9843   mng_imagedatap pBuf = ((mng_imagep)pData->pRetrieveobj)->pImgbuf;
9844   mng_uint8p     pWorkrow;
9845   mng_uint8p     pRGBArow;
9846 
9847 #ifdef MNG_SUPPORT_TRACE
9848   MNG_TRACE (pData, MNG_FN_RETRIEVE_RGBA8, MNG_LC_START);
9849 #endif
9850 
9851   pRGBArow = pData->pRGBArow;          /* temporary work pointers */
9852   pWorkrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize);
9853                                        /* can't be easier than this ! */
9854   MNG_COPY (pRGBArow, pWorkrow, pBuf->iRowsize);
9855 
9856 #ifdef MNG_SUPPORT_TRACE
9857   MNG_TRACE (pData, MNG_FN_RETRIEVE_RGBA8, MNG_LC_END);
9858 #endif
9859 
9860   return MNG_NOERROR;
9861 }
9862 
9863 /* ************************************************************************** */
9864 
9865 #ifndef MNG_NO_16BIT_SUPPORT
mng_retrieve_rgba16(mng_datap pData)9866 mng_retcode mng_retrieve_rgba16 (mng_datap pData)
9867 {
9868   mng_imagedatap pBuf = ((mng_imagep)pData->pRetrieveobj)->pImgbuf;
9869   mng_uint8p     pWorkrow;
9870   mng_uint8p     pRGBArow;
9871 
9872 #ifdef MNG_SUPPORT_TRACE
9873   MNG_TRACE (pData, MNG_FN_RETRIEVE_RGBA16, MNG_LC_START);
9874 #endif
9875                                        /* temporary work pointers */
9876   pRGBArow = pData->pRGBArow;
9877   pWorkrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize);
9878                                        /* can't be easier than this ! */
9879   MNG_COPY (pRGBArow, pWorkrow, pBuf->iRowsize);
9880 
9881 #ifdef MNG_SUPPORT_TRACE
9882   MNG_TRACE (pData, MNG_FN_RETRIEVE_RGBA16, MNG_LC_END);
9883 #endif
9884 
9885   return MNG_NOERROR;
9886 }
9887 #endif
9888 
9889 /* ************************************************************************** */
9890 /* *                                                                        * */
9891 /* * Row storage routines - store processed & uncompressed row-data         * */
9892 /* * into the current "object"                                              * */
9893 /* *                                                                        * */
9894 /* ************************************************************************** */
9895 
9896 #ifndef MNG_NO_1_2_4BIT_SUPPORT
mng_store_g1(mng_datap pData)9897 mng_retcode mng_store_g1 (mng_datap pData)
9898 {
9899   mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
9900   mng_uint8p     pWorkrow;
9901   mng_uint8p     pOutrow;
9902   mng_int32      iX;
9903   mng_uint8      iB;
9904   mng_uint8      iM;
9905 
9906 #ifdef MNG_SUPPORT_TRACE
9907   MNG_TRACE (pData, MNG_FN_STORE_G1, MNG_LC_START);
9908 #endif
9909                                        /* temporary work pointers */
9910   pWorkrow = pData->pWorkrow + pData->iPixelofs;
9911   pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
9912                               (pData->iCol * pBuf->iSamplesize);
9913   iM       = 0;                        /* start at pixel 0 */
9914   iB       = 0;
9915 
9916 #ifdef MNG_DECREMENT_LOOPS
9917   for (iX = pData->iRowsamples; iX > 0; iX--)
9918 #else
9919   for (iX = 0; iX < pData->iRowsamples; iX++)
9920 #endif
9921   {
9922     if (!iM)                           /* mask underflow ? */
9923     {
9924       iB = *pWorkrow;                  /* get next input-byte */
9925       pWorkrow++;
9926       iM = 0x80;
9927     }
9928 
9929     if (iB & iM)                       /* is it white ? */
9930       *pOutrow = 0x01;                 /* white */
9931     else
9932       *pOutrow = 0x00;                 /* black */
9933 
9934     pOutrow += pData->iColinc;         /* next pixel */
9935     iM >>=  1;
9936   }
9937 
9938 #ifdef MNG_SUPPORT_TRACE
9939   MNG_TRACE (pData, MNG_FN_STORE_G1, MNG_LC_END);
9940 #endif
9941 
9942   return MNG_NOERROR;
9943 }
9944 
9945 /* ************************************************************************** */
9946 
mng_store_g2(mng_datap pData)9947 mng_retcode mng_store_g2 (mng_datap pData)
9948 {
9949   mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
9950   mng_uint8p     pWorkrow;
9951   mng_uint8p     pOutrow;
9952   mng_int32      iX;
9953   mng_uint8      iB;
9954   mng_uint8      iM;
9955   mng_uint32     iS;
9956   mng_uint8      iQ;
9957 
9958 #ifdef MNG_SUPPORT_TRACE
9959   MNG_TRACE (pData, MNG_FN_STORE_G2, MNG_LC_START);
9960 #endif
9961                                        /* temporary work pointers */
9962   pWorkrow = pData->pWorkrow + pData->iPixelofs;
9963   pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
9964                               (pData->iCol * pBuf->iSamplesize);
9965   iM       = 0;                        /* start at pixel 0 */
9966   iB       = 0;
9967   iS       = 0;
9968 
9969 #ifdef MNG_DECREMENT_LOOPS
9970   for (iX = pData->iRowsamples; iX > 0; iX--)
9971 #else
9972   for (iX = 0; iX < pData->iRowsamples; iX++)
9973 #endif
9974   {
9975     if (!iM)                           /* mask underflow ? */
9976     {
9977       iB = *pWorkrow;                  /* get next input-byte */
9978       pWorkrow++;
9979       iM = 0xC0;
9980       iS = 6;
9981     }
9982 
9983     iQ = (mng_uint8)((iB & iM) >> iS); /* get the gray level */
9984     *pOutrow = iQ;                     /* put in object buffer */
9985 
9986     pOutrow += pData->iColinc;         /* next pixel */
9987     iM >>=  2;
9988     iS -= 2;
9989   }
9990 
9991 #ifdef MNG_SUPPORT_TRACE
9992   MNG_TRACE (pData, MNG_FN_STORE_G2, MNG_LC_END);
9993 #endif
9994 
9995   return MNG_NOERROR;
9996 }
9997 
9998 /* ************************************************************************** */
9999 
mng_store_g4(mng_datap pData)10000 mng_retcode mng_store_g4 (mng_datap pData)
10001 {
10002   mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
10003   mng_uint8p     pWorkrow;
10004   mng_uint8p     pOutrow;
10005   mng_int32      iX;
10006   mng_uint8      iB;
10007   mng_uint8      iM;
10008   mng_uint32     iS;
10009   mng_uint8      iQ;
10010 
10011 #ifdef MNG_SUPPORT_TRACE
10012   MNG_TRACE (pData, MNG_FN_STORE_G4, MNG_LC_START);
10013 #endif
10014                                        /* temporary work pointers */
10015   pWorkrow = pData->pWorkrow + pData->iPixelofs;
10016   pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
10017                               (pData->iCol * pBuf->iSamplesize);
10018   iM       = 0;                        /* start at pixel 0 */
10019   iB       = 0;
10020   iS       = 0;
10021 
10022 #ifdef MNG_DECREMENT_LOOPS
10023   for (iX = pData->iRowsamples; iX > 0; iX--)
10024 #else
10025   for (iX = 0; iX < pData->iRowsamples; iX++)
10026 #endif
10027   {
10028     if (!iM)                           /* mask underflow ? */
10029     {
10030       iB = *pWorkrow;                  /* get next input-byte */
10031       pWorkrow++;
10032       iM = 0xF0;
10033       iS = 4;
10034     }
10035 
10036     iQ = (mng_uint8)((iB & iM) >> iS); /* get the gray level */
10037     *pOutrow = iQ;                     /* put in object buffer */
10038 
10039     pOutrow += pData->iColinc;         /* next pixel */
10040     iM >>=  4;
10041     iS -= 4;
10042   }
10043 
10044 #ifdef MNG_SUPPORT_TRACE
10045   MNG_TRACE (pData, MNG_FN_STORE_G4, MNG_LC_END);
10046 #endif
10047 
10048   return MNG_NOERROR;
10049 }
10050 #endif
10051 
10052 /* ************************************************************************** */
10053 
mng_store_g8(mng_datap pData)10054 mng_retcode mng_store_g8 (mng_datap pData)
10055 {
10056   mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
10057   mng_uint8p     pWorkrow;
10058   mng_uint8p     pOutrow;
10059   mng_int32      iX;
10060 
10061 #ifdef MNG_SUPPORT_TRACE
10062   MNG_TRACE (pData, MNG_FN_STORE_G8, MNG_LC_START);
10063 #endif
10064                                        /* temporary work pointers */
10065   pWorkrow = pData->pWorkrow + pData->iPixelofs;
10066   pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
10067                               (pData->iCol * pBuf->iSamplesize);
10068 
10069 #ifdef MNG_DECREMENT_LOOPS
10070   for (iX = pData->iRowsamples; iX > 0; iX--)
10071 #else
10072   for (iX = 0; iX < pData->iRowsamples; iX++)
10073 #endif
10074   {
10075     *pOutrow = *pWorkrow;              /* put in object buffer */
10076 
10077     pOutrow += pData->iColinc;         /* next pixel */
10078     pWorkrow++;
10079   }
10080 
10081 #ifdef MNG_SUPPORT_TRACE
10082   MNG_TRACE (pData, MNG_FN_STORE_G8, MNG_LC_END);
10083 #endif
10084 
10085   return MNG_NOERROR;
10086 }
10087 
10088 /* ************************************************************************** */
10089 
10090 #ifndef MNG_NO_16BIT_SUPPORT
mng_store_g16(mng_datap pData)10091 mng_retcode mng_store_g16 (mng_datap pData)
10092 {
10093   mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
10094   mng_uint8p     pWorkrow;
10095   mng_uint8p     pOutrow;
10096   mng_int32      iX;
10097 
10098 #ifdef MNG_SUPPORT_TRACE
10099   MNG_TRACE (pData, MNG_FN_STORE_G16, MNG_LC_START);
10100 #endif
10101                                        /* temporary work pointers */
10102   pWorkrow = pData->pWorkrow + pData->iPixelofs;
10103   pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
10104                               (pData->iCol * pBuf->iSamplesize);
10105 
10106 #ifdef MNG_DECREMENT_LOOPS
10107   for (iX = pData->iRowsamples; iX > 0; iX--)
10108 #else
10109   for (iX = 0; iX < pData->iRowsamples; iX++)
10110 #endif
10111   {                                    /* copy into object buffer */
10112     mng_put_uint16 (pOutrow, mng_get_uint16 (pWorkrow));
10113 
10114     pOutrow  += (pData->iColinc << 1); /* next pixel */
10115     pWorkrow += 2;
10116   }
10117 
10118 #ifdef MNG_SUPPORT_TRACE
10119   MNG_TRACE (pData, MNG_FN_STORE_G16, MNG_LC_END);
10120 #endif
10121 
10122   return MNG_NOERROR;
10123 }
10124 #endif
10125 
10126 /* ************************************************************************** */
10127 
mng_store_rgb8(mng_datap pData)10128 mng_retcode mng_store_rgb8 (mng_datap pData)
10129 {
10130   mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
10131   mng_uint8p     pWorkrow;
10132   mng_uint8p     pOutrow;
10133   mng_int32      iX;
10134 
10135 #ifdef MNG_SUPPORT_TRACE
10136   MNG_TRACE (pData, MNG_FN_STORE_RGB8, MNG_LC_START);
10137 #endif
10138                                        /* temporary work pointers */
10139   pWorkrow = pData->pWorkrow + pData->iPixelofs;
10140   pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
10141                               (pData->iCol * pBuf->iSamplesize);
10142 
10143 #ifdef MNG_DECREMENT_LOOPS
10144   for (iX = pData->iRowsamples; iX > 0; iX--)
10145 #else
10146   for (iX = 0; iX < pData->iRowsamples; iX++)
10147 #endif
10148   {
10149     *pOutrow     = *pWorkrow;          /* copy the RGB bytes */
10150     *(pOutrow+1) = *(pWorkrow+1);
10151     *(pOutrow+2) = *(pWorkrow+2);
10152 
10153     pWorkrow += 3;                     /* next pixel */
10154     pOutrow  += (pData->iColinc * 3);
10155   }
10156 
10157 #ifdef MNG_SUPPORT_TRACE
10158   MNG_TRACE (pData, MNG_FN_STORE_RGB8, MNG_LC_END);
10159 #endif
10160 
10161   return MNG_NOERROR;
10162 }
10163 
10164 /* ************************************************************************** */
10165 
10166 #ifndef MNG_NO_16BIT_SUPPORT
mng_store_rgb16(mng_datap pData)10167 mng_retcode mng_store_rgb16 (mng_datap pData)
10168 {
10169   mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
10170   mng_uint8p     pWorkrow;
10171   mng_uint8p     pOutrow;
10172   mng_int32      iX;
10173 
10174 #ifdef MNG_SUPPORT_TRACE
10175   MNG_TRACE (pData, MNG_FN_STORE_RGB16, MNG_LC_START);
10176 #endif
10177                                        /* temporary work pointers */
10178   pWorkrow = pData->pWorkrow + pData->iPixelofs;
10179   pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
10180                               (pData->iCol * pBuf->iSamplesize);
10181 
10182 #ifdef MNG_DECREMENT_LOOPS
10183   for (iX = pData->iRowsamples; iX > 0; iX--)
10184 #else
10185   for (iX = 0; iX < pData->iRowsamples; iX++)
10186 #endif
10187   {
10188     MNG_COPY (pOutrow, pWorkrow, 6);   /* copy the RGB bytes */
10189 
10190     pWorkrow += 6;                     /* next pixel */
10191     pOutrow  += (pData->iColinc * 6);
10192   }
10193 
10194 #ifdef MNG_SUPPORT_TRACE
10195   MNG_TRACE (pData, MNG_FN_STORE_RGB16, MNG_LC_END);
10196 #endif
10197 
10198   return MNG_NOERROR;
10199 }
10200 #endif
10201 
10202 /* ************************************************************************** */
10203 
10204 #ifndef MNG_NO_1_2_4BIT_SUPPORT
mng_store_idx1(mng_datap pData)10205 mng_retcode mng_store_idx1 (mng_datap pData)
10206 {
10207   mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
10208   mng_uint8p     pWorkrow;
10209   mng_uint8p     pOutrow;
10210   mng_int32      iX;
10211   mng_uint8      iB;
10212   mng_uint8      iM;
10213 
10214 #ifdef MNG_SUPPORT_TRACE
10215   MNG_TRACE (pData, MNG_FN_STORE_IDX1, MNG_LC_START);
10216 #endif
10217                                        /* temporary work pointers */
10218   pWorkrow = pData->pWorkrow + pData->iPixelofs;
10219   pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
10220                               (pData->iCol * pBuf->iSamplesize);
10221   iM       = 0;                        /* start at pixel 0 */
10222   iB       = 0;
10223 
10224 #ifdef MNG_DECREMENT_LOOPS
10225   for (iX = pData->iRowsamples; iX > 0; iX--)
10226 #else
10227   for (iX = 0; iX < pData->iRowsamples; iX++)
10228 #endif
10229   {
10230     if (!iM)                           /* mask underflow ? */
10231     {
10232       iB = *pWorkrow;                  /* get next input-byte */
10233       pWorkrow++;
10234       iM = 0x80;
10235     }
10236 
10237     if (iB & iM)                       /* store the index */
10238       *pOutrow = 0x01;
10239     else
10240       *pOutrow = 0x00;
10241 
10242     pOutrow += pData->iColinc;         /* next pixel */
10243     iM >>=  1;
10244   }
10245 
10246 #ifdef MNG_SUPPORT_TRACE
10247   MNG_TRACE (pData, MNG_FN_STORE_IDX1, MNG_LC_END);
10248 #endif
10249 
10250   return MNG_NOERROR;
10251 }
10252 
10253 /* ************************************************************************** */
10254 
mng_store_idx2(mng_datap pData)10255 mng_retcode mng_store_idx2 (mng_datap pData)
10256 {
10257   mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
10258   mng_uint8p     pWorkrow;
10259   mng_uint8p     pOutrow;
10260   mng_int32      iX;
10261   mng_uint8      iB;
10262   mng_uint8      iM;
10263   mng_uint32     iS;
10264 
10265 #ifdef MNG_SUPPORT_TRACE
10266   MNG_TRACE (pData, MNG_FN_STORE_IDX2, MNG_LC_START);
10267 #endif
10268                                        /* temporary work pointers */
10269   pWorkrow = pData->pWorkrow + pData->iPixelofs;
10270   pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
10271                               (pData->iCol * pBuf->iSamplesize);
10272   iM       = 0;                        /* start at pixel 0 */
10273   iB       = 0;
10274   iS       = 0;
10275 
10276 #ifdef MNG_DECREMENT_LOOPS
10277   for (iX = pData->iRowsamples; iX > 0; iX--)
10278 #else
10279   for (iX = 0; iX < pData->iRowsamples; iX++)
10280 #endif
10281   {
10282     if (!iM)                           /* mask underflow ? */
10283     {
10284       iB = *pWorkrow;                  /* get next input-byte */
10285       pWorkrow++;
10286       iM = 0xC0;
10287       iS = 6;
10288     }
10289                                        /* store the index */
10290     *pOutrow = (mng_uint8)((iB & iM) >> iS);
10291 
10292     pOutrow += pData->iColinc;         /* next pixel */
10293     iM >>=  2;
10294     iS -= 2;
10295   }
10296 
10297 #ifdef MNG_SUPPORT_TRACE
10298   MNG_TRACE (pData, MNG_FN_STORE_IDX2, MNG_LC_END);
10299 #endif
10300 
10301   return MNG_NOERROR;
10302 }
10303 
10304 /* ************************************************************************** */
10305 
mng_store_idx4(mng_datap pData)10306 mng_retcode mng_store_idx4 (mng_datap pData)
10307 {
10308   mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
10309   mng_uint8p     pWorkrow;
10310   mng_uint8p     pOutrow;
10311   mng_int32      iX;
10312   mng_uint8      iB;
10313   mng_uint8      iM;
10314   mng_uint32     iS;
10315 
10316 #ifdef MNG_SUPPORT_TRACE
10317   MNG_TRACE (pData, MNG_FN_STORE_IDX4, MNG_LC_START);
10318 #endif
10319                                        /* temporary work pointers */
10320   pWorkrow = pData->pWorkrow + pData->iPixelofs;
10321   pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
10322                               (pData->iCol * pBuf->iSamplesize);
10323   iM       = 0;                        /* start at pixel 0 */
10324   iB       = 0;
10325   iS       = 0;
10326 
10327 #ifdef MNG_DECREMENT_LOOPS
10328   for (iX = pData->iRowsamples; iX > 0; iX--)
10329 #else
10330   for (iX = 0; iX < pData->iRowsamples; iX++)
10331 #endif
10332   {
10333     if (!iM)                           /* mask underflow ? */
10334     {
10335       iB = *pWorkrow;                  /* get next input-byte */
10336       pWorkrow++;
10337       iM = 0xF0;
10338       iS = 4;
10339     }
10340                                        /* store the index */
10341     *pOutrow = (mng_uint8)((iB & iM) >> iS);
10342 
10343     pOutrow += pData->iColinc;         /* next pixel */
10344     iM >>=  4;
10345     iS -= 4;
10346   }
10347 
10348 #ifdef MNG_SUPPORT_TRACE
10349   MNG_TRACE (pData, MNG_FN_STORE_IDX4, MNG_LC_END);
10350 #endif
10351 
10352   return MNG_NOERROR;
10353 }
10354 #endif
10355 
10356 /* ************************************************************************** */
10357 
mng_store_idx8(mng_datap pData)10358 mng_retcode mng_store_idx8 (mng_datap pData)
10359 {
10360   mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
10361   mng_uint8p     pWorkrow;
10362   mng_uint8p     pOutrow;
10363   mng_int32      iX;
10364 
10365 #ifdef MNG_SUPPORT_TRACE
10366   MNG_TRACE (pData, MNG_FN_STORE_IDX8, MNG_LC_START);
10367 #endif
10368                                        /* temporary work pointers */
10369   pWorkrow = pData->pWorkrow + pData->iPixelofs;
10370   pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
10371                               (pData->iCol * pBuf->iSamplesize);
10372 
10373 #ifdef MNG_DECREMENT_LOOPS
10374   for (iX = pData->iRowsamples; iX > 0; iX--)
10375 #else
10376   for (iX = 0; iX < pData->iRowsamples; iX++)
10377 #endif
10378   {
10379     *pOutrow = *pWorkrow;              /* put in object buffer */
10380 
10381     pOutrow += pData->iColinc;         /* next pixel */
10382     pWorkrow++;
10383   }
10384 
10385 #ifdef MNG_SUPPORT_TRACE
10386   MNG_TRACE (pData, MNG_FN_STORE_IDX8, MNG_LC_END);
10387 #endif
10388 
10389   return MNG_NOERROR;
10390 }
10391 
10392 /* ************************************************************************** */
10393 
mng_store_ga8(mng_datap pData)10394 mng_retcode mng_store_ga8 (mng_datap pData)
10395 {
10396   mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
10397   mng_uint8p     pWorkrow;
10398   mng_uint8p     pOutrow;
10399   mng_int32      iX;
10400 
10401 #ifdef MNG_SUPPORT_TRACE
10402   MNG_TRACE (pData, MNG_FN_STORE_GA8, MNG_LC_START);
10403 #endif
10404                                        /* temporary work pointers */
10405   pWorkrow = pData->pWorkrow + pData->iPixelofs;
10406   pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
10407                               (pData->iCol * pBuf->iSamplesize);
10408 
10409 #ifdef MNG_DECREMENT_LOOPS
10410   for (iX = pData->iRowsamples; iX > 0; iX--)
10411 #else
10412   for (iX = 0; iX < pData->iRowsamples; iX++)
10413 #endif
10414   {
10415     *pOutrow     = *pWorkrow;          /* copy the GA bytes */
10416     *(pOutrow+1) = *(pWorkrow+1);
10417 
10418     pWorkrow += 2;                     /* next pixel */
10419     pOutrow  += (pData->iColinc << 1);
10420   }
10421 
10422 #ifdef MNG_SUPPORT_TRACE
10423   MNG_TRACE (pData, MNG_FN_STORE_GA8, MNG_LC_END);
10424 #endif
10425 
10426   return MNG_NOERROR;
10427 }
10428 
10429 /* ************************************************************************** */
10430 
10431 #ifndef MNG_NO_16BIT_SUPPORT
mng_store_ga16(mng_datap pData)10432 mng_retcode mng_store_ga16 (mng_datap pData)
10433 {
10434   mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
10435   mng_uint8p     pWorkrow;
10436   mng_uint8p     pOutrow;
10437   mng_int32      iX;
10438 
10439 #ifdef MNG_SUPPORT_TRACE
10440   MNG_TRACE (pData, MNG_FN_STORE_GA16, MNG_LC_START);
10441 #endif
10442                                        /* temporary work pointers */
10443   pWorkrow = pData->pWorkrow + pData->iPixelofs;
10444   pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
10445                               (pData->iCol * pBuf->iSamplesize);
10446 
10447 #ifdef MNG_DECREMENT_LOOPS
10448   for (iX = pData->iRowsamples; iX > 0; iX--)
10449 #else
10450   for (iX = 0; iX < pData->iRowsamples; iX++)
10451 #endif
10452   {
10453     MNG_COPY (pOutrow, pWorkrow, 4);   /* copy the GA bytes */
10454 
10455     pWorkrow += 4;                     /* next pixel */
10456     pOutrow  += (pData->iColinc << 2);
10457   }
10458 
10459 #ifdef MNG_SUPPORT_TRACE
10460   MNG_TRACE (pData, MNG_FN_STORE_GA16, MNG_LC_END);
10461 #endif
10462 
10463   return MNG_NOERROR;
10464 }
10465 #endif
10466 
10467 /* ************************************************************************** */
10468 
mng_store_rgba8(mng_datap pData)10469 mng_retcode mng_store_rgba8 (mng_datap pData)
10470 {
10471   mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
10472   mng_uint8p     pWorkrow;
10473   mng_uint8p     pOutrow;
10474   mng_int32      iX;
10475 
10476 #ifdef MNG_SUPPORT_TRACE
10477   MNG_TRACE (pData, MNG_FN_STORE_RGBA8, MNG_LC_START);
10478 #endif
10479                                        /* temporary work pointers */
10480   pWorkrow = pData->pWorkrow + pData->iPixelofs;
10481   pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
10482                               (pData->iCol * pBuf->iSamplesize);
10483 
10484 #ifdef MNG_DECREMENT_LOOPS
10485   for (iX = pData->iRowsamples; iX > 0; iX--)
10486 #else
10487   for (iX = 0; iX < pData->iRowsamples; iX++)
10488 #endif
10489   {
10490     *pOutrow     = *pWorkrow;          /* copy the RGBA bytes */
10491     *(pOutrow+1) = *(pWorkrow+1);
10492     *(pOutrow+2) = *(pWorkrow+2);
10493     *(pOutrow+3) = *(pWorkrow+3);
10494 
10495     pWorkrow += 4;                     /* next pixel */
10496     pOutrow  += (pData->iColinc << 2);
10497   }
10498 
10499 #ifdef MNG_SUPPORT_TRACE
10500   MNG_TRACE (pData, MNG_FN_STORE_RGBA8, MNG_LC_END);
10501 #endif
10502 
10503   return MNG_NOERROR;
10504 }
10505 
10506 /* ************************************************************************** */
10507 
10508 #ifndef MNG_NO_16BIT_SUPPORT
mng_store_rgba16(mng_datap pData)10509 mng_retcode mng_store_rgba16 (mng_datap pData)
10510 {
10511   mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
10512   mng_uint8p     pWorkrow;
10513   mng_uint8p     pOutrow;
10514   mng_int32      iX;
10515 
10516 #ifdef MNG_SUPPORT_TRACE
10517   MNG_TRACE (pData, MNG_FN_STORE_RGBA16, MNG_LC_START);
10518 #endif
10519                                        /* temporary work pointers */
10520   pWorkrow = pData->pWorkrow + pData->iPixelofs;
10521   pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
10522                               (pData->iCol * pBuf->iSamplesize);
10523 
10524 #ifdef MNG_DECREMENT_LOOPS
10525   for (iX = pData->iRowsamples; iX > 0; iX--)
10526 #else
10527   for (iX = 0; iX < pData->iRowsamples; iX++)
10528 #endif
10529   {
10530     MNG_COPY (pOutrow, pWorkrow, 8);   /* copy the RGBA bytes */
10531 
10532     pWorkrow += 8;                     /* next pixel */
10533     pOutrow  += (pData->iColinc << 3);
10534   }
10535 
10536 #ifdef MNG_SUPPORT_TRACE
10537   MNG_TRACE (pData, MNG_FN_STORE_RGBA16, MNG_LC_END);
10538 #endif
10539 
10540   return MNG_NOERROR;
10541 }
10542 #endif
10543 
10544 /* ************************************************************************** */
10545 /* *                                                                        * */
10546 /* * Row storage routines (JPEG) - store processed & uncompressed row-data  * */
10547 /* * into the current "object"                                              * */
10548 /* *                                                                        * */
10549 /* ************************************************************************** */
10550 
10551 #ifdef MNG_INCLUDE_JNG
10552 
10553 /* ************************************************************************** */
10554 
mng_store_jpeg_g8(mng_datap pData)10555 mng_retcode mng_store_jpeg_g8 (mng_datap pData)
10556 {
10557   mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
10558   mng_uint8p     pWorkrow;
10559   mng_uint8p     pOutrow;
10560 
10561 #ifdef MNG_SUPPORT_TRACE
10562   MNG_TRACE (pData, MNG_FN_STORE_JPEG_G8, MNG_LC_START);
10563 #endif
10564 
10565   pWorkrow = pData->pJPEGrow;          /* temporary work pointers */
10566   pOutrow  = pBuf->pImgdata + (pData->iJPEGrow * pBuf->iRowsize);
10567                                        /* easy as pie ... */
10568   MNG_COPY (pOutrow, pWorkrow, pData->iRowsamples);
10569 
10570 #ifdef MNG_SUPPORT_TRACE
10571   MNG_TRACE (pData, MNG_FN_STORE_JPEG_G8, MNG_LC_END);
10572 #endif
10573 
10574   return mng_next_jpeg_row (pData);    /* we've got one more row of gray-samples */
10575 }
10576 
10577 /* ************************************************************************** */
10578 
mng_store_jpeg_rgb8(mng_datap pData)10579 mng_retcode mng_store_jpeg_rgb8 (mng_datap pData)
10580 {
10581   mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
10582   mng_uint8p     pWorkrow;
10583   mng_uint8p     pOutrow;
10584 #if RGB_PIXELSIZE != 3
10585   mng_int32      iX;
10586 #endif
10587 
10588 #ifdef MNG_SUPPORT_TRACE
10589   MNG_TRACE (pData, MNG_FN_STORE_JPEG_RGB8, MNG_LC_START);
10590 #endif
10591 
10592   pWorkrow = pData->pJPEGrow;          /* temporary work pointers */
10593   pOutrow  = pBuf->pImgdata + (pData->iJPEGrow * pBuf->iRowsize);
10594 
10595 #if RGB_PIXELSIZE == 3
10596                                        /* easy as pie ... */
10597   MNG_COPY (pOutrow, pWorkrow, pData->iRowsamples * 3);
10598 #else
10599 #ifdef MNG_DECREMENT_LOOPS
10600   for (iX = pData->iRowsamples; iX > 0; iX--)
10601 #else
10602   for (iX = 0; iX < pData->iRowsamples; iX++)
10603 #endif
10604   {
10605     *pOutrow     = *pWorkrow;          /* copy pixel into object buffer */
10606     *(pOutrow+1) = *(pWorkrow+1);
10607     *(pOutrow+2) = *(pWorkrow+2);
10608 
10609     pOutrow  += 3;                     /* next pixel */
10610     pWorkrow += RGB_PIXELSIZE;
10611   }
10612 #endif
10613 
10614 #ifdef MNG_SUPPORT_TRACE
10615   MNG_TRACE (pData, MNG_FN_STORE_JPEG_RGB8, MNG_LC_END);
10616 #endif
10617 
10618   return mng_next_jpeg_row (pData);    /* we've got one more row of rgb-samples */
10619 }
10620 
10621 /* ************************************************************************** */
10622 
mng_store_jpeg_ga8(mng_datap pData)10623 mng_retcode mng_store_jpeg_ga8 (mng_datap pData)
10624 {
10625   mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
10626   mng_uint8p     pWorkrow;
10627   mng_uint8p     pOutrow;
10628   mng_int32      iX;
10629 
10630 #ifdef MNG_SUPPORT_TRACE
10631   MNG_TRACE (pData, MNG_FN_STORE_JPEG_GA8, MNG_LC_START);
10632 #endif
10633 
10634   pWorkrow = pData->pJPEGrow;          /* temporary work pointers */
10635   pOutrow  = pBuf->pImgdata + (pData->iJPEGrow * pBuf->iRowsize);
10636 
10637 #ifdef MNG_DECREMENT_LOOPS
10638   for (iX = pData->iRowsamples; iX > 0; iX--)
10639 #else
10640   for (iX = 0; iX < pData->iRowsamples; iX++)
10641 #endif
10642   {
10643     *pOutrow = *pWorkrow;              /* copy into object buffer */
10644 
10645     pOutrow += 2;                      /* next pixel */
10646     pWorkrow++;
10647   }
10648 
10649 #ifdef MNG_SUPPORT_TRACE
10650   MNG_TRACE (pData, MNG_FN_STORE_JPEG_GA8, MNG_LC_END);
10651 #endif
10652 
10653   return mng_next_jpeg_row (pData);    /* we've got one more row of gray-samples */
10654 }
10655 
10656 /* ************************************************************************** */
10657 
mng_store_jpeg_rgba8(mng_datap pData)10658 mng_retcode mng_store_jpeg_rgba8 (mng_datap pData)
10659 {
10660   mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
10661   mng_uint8p     pWorkrow;
10662   mng_uint8p     pOutrow;
10663   mng_int32      iX;
10664 
10665 #ifdef MNG_SUPPORT_TRACE
10666   MNG_TRACE (pData, MNG_FN_STORE_JPEG_RGBA8, MNG_LC_START);
10667 #endif
10668 
10669   pWorkrow = pData->pJPEGrow;          /* temporary work pointers */
10670   pOutrow  = pBuf->pImgdata + (pData->iJPEGrow * pBuf->iRowsize);
10671 
10672 #ifdef MNG_DECREMENT_LOOPS
10673   for (iX = pData->iRowsamples; iX > 0; iX--)
10674 #else
10675   for (iX = 0; iX < pData->iRowsamples; iX++)
10676 #endif
10677   {
10678     *pOutrow     = *pWorkrow;          /* copy pixel into object buffer */
10679     *(pOutrow+1) = *(pWorkrow+1);
10680     *(pOutrow+2) = *(pWorkrow+2);
10681 
10682     pOutrow  += 4;                     /* next pixel */
10683     pWorkrow += RGB_PIXELSIZE;
10684   }
10685 
10686 #ifdef MNG_SUPPORT_TRACE
10687   MNG_TRACE (pData, MNG_FN_STORE_JPEG_RGBA8, MNG_LC_END);
10688 #endif
10689 
10690   return mng_next_jpeg_row (pData);    /* we've got one more row of rgb-samples */
10691 }
10692 
10693 /* ************************************************************************** */
10694 
mng_store_jpeg_g8_alpha(mng_datap pData)10695 mng_retcode mng_store_jpeg_g8_alpha (mng_datap pData)
10696 {
10697   mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
10698   mng_uint8p     pWorkrow;
10699   mng_uint8p     pOutrow;
10700   mng_int32      iX;
10701 
10702 #ifdef MNG_SUPPORT_TRACE
10703   MNG_TRACE (pData, MNG_FN_STORE_JPEG_G8_ALPHA, MNG_LC_START);
10704 #endif
10705                                        /* temporary work pointers */
10706   pWorkrow = pData->pJPEGrow2;
10707   pOutrow  = pBuf->pImgdata + (pData->iJPEGalpharow * pBuf->iRowsize) + 1;
10708 
10709 #ifdef MNG_DECREMENT_LOOPS
10710   for (iX = pData->iRowsamples; iX > 0; iX--)
10711 #else
10712   for (iX = 0; iX < pData->iRowsamples; iX++)
10713 #endif
10714   {
10715     *pOutrow = *pWorkrow;              /* put in object buffer */
10716 
10717     pOutrow += 2;                      /* next pixel */
10718     pWorkrow++;
10719   }
10720 
10721 #ifdef MNG_SUPPORT_TRACE
10722   MNG_TRACE (pData, MNG_FN_STORE_JPEG_G8_ALPHA, MNG_LC_END);
10723 #endif
10724                                        /* we've got one more row of alpha-samples */
10725   return mng_next_jpeg_alpharow (pData);
10726 }
10727 
10728 /* ************************************************************************** */
10729 
mng_store_jpeg_rgb8_alpha(mng_datap pData)10730 mng_retcode mng_store_jpeg_rgb8_alpha (mng_datap pData)
10731 {
10732   mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
10733   mng_uint8p     pWorkrow;
10734   mng_uint8p     pOutrow;
10735   mng_int32      iX;
10736 
10737 #ifdef MNG_SUPPORT_TRACE
10738   MNG_TRACE (pData, MNG_FN_STORE_JPEG_RGB8_ALPHA, MNG_LC_START);
10739 #endif
10740                                        /* temporary work pointers */
10741   pWorkrow = pData->pJPEGrow2;
10742   pOutrow  = pBuf->pImgdata + (pData->iJPEGalpharow * pBuf->iRowsize) + 3;
10743 
10744 #ifdef MNG_DECREMENT_LOOPS
10745   for (iX = pData->iRowsamples; iX > 0; iX--)
10746 #else
10747   for (iX = 0; iX < pData->iRowsamples; iX++)
10748 #endif
10749   {
10750     *pOutrow = *pWorkrow;              /* put in object buffer */
10751 
10752     pOutrow += 4;                      /* next pixel */
10753     pWorkrow++;
10754   }
10755 
10756 #ifdef MNG_SUPPORT_TRACE
10757   MNG_TRACE (pData, MNG_FN_STORE_JPEG_RGB8_ALPHA, MNG_LC_END);
10758 #endif
10759                                        /* we've got one more row of alpha-samples */
10760   return mng_next_jpeg_alpharow (pData);
10761 }
10762 
10763 /* ************************************************************************** */
10764 
10765 #ifndef MNG_NO_1_2_4BIT_SUPPORT
mng_store_jpeg_g8_a1(mng_datap pData)10766 mng_retcode mng_store_jpeg_g8_a1 (mng_datap pData)
10767 {
10768   mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
10769   mng_uint8p     pWorkrow;
10770   mng_uint8p     pOutrow;
10771   mng_int32      iX;
10772   mng_uint8      iB;
10773   mng_uint8      iM;
10774 
10775 #ifdef MNG_SUPPORT_TRACE
10776   MNG_TRACE (pData, MNG_FN_STORE_JPEG_G8_A1, MNG_LC_START);
10777 #endif
10778                                        /* temporary work pointers */
10779   pWorkrow = pData->pWorkrow + pData->iPixelofs;
10780   pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
10781                               (pData->iCol * pBuf->iSamplesize) + 1;
10782   iM       = 0;                        /* start at pixel 0 */
10783   iB       = 0;
10784 
10785 #ifdef MNG_DECREMENT_LOOPS
10786   for (iX = pData->iRowsamples; iX > 0; iX--)
10787 #else
10788   for (iX = 0; iX < pData->iRowsamples; iX++)
10789 #endif
10790   {
10791     if (!iM)                           /* mask underflow ? */
10792     {
10793       iB = *pWorkrow;                  /* get next input-byte */
10794       pWorkrow++;
10795       iM = 0x80;
10796     }
10797 
10798     if (iB & iM)                       /* is it opaque ? */
10799       *pOutrow = 0xFF;                 /* opaque */
10800     else
10801       *pOutrow = 0x00;                 /* transparent */
10802 
10803     pOutrow += 2;                      /* next pixel */
10804     iM >>=  1;
10805   }
10806 
10807 #ifdef MNG_SUPPORT_TRACE
10808   MNG_TRACE (pData, MNG_FN_STORE_JPEG_G8_A1, MNG_LC_END);
10809 #endif
10810                                        /* we've got one more row of alpha-samples */
10811   return mng_next_jpeg_alpharow (pData);
10812 }
10813 
10814 /* ************************************************************************** */
10815 
mng_store_jpeg_g8_a2(mng_datap pData)10816 mng_retcode mng_store_jpeg_g8_a2 (mng_datap pData)
10817 {
10818   mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
10819   mng_uint8p     pWorkrow;
10820   mng_uint8p     pOutrow;
10821   mng_int32      iX;
10822   mng_uint8      iB;
10823   mng_uint8      iM;
10824   mng_uint32     iS;
10825 
10826 #ifdef MNG_SUPPORT_TRACE
10827   MNG_TRACE (pData, MNG_FN_STORE_JPEG_G8_A2, MNG_LC_START);
10828 #endif
10829                                        /* temporary work pointers */
10830   pWorkrow = pData->pWorkrow + pData->iPixelofs;
10831   pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
10832                               (pData->iCol * pBuf->iSamplesize) + 1;
10833   iM       = 0;                        /* start at pixel 0 */
10834   iB       = 0;
10835   iS       = 0;
10836 
10837 #ifdef MNG_DECREMENT_LOOPS
10838   for (iX = pData->iRowsamples; iX > 0; iX--)
10839 #else
10840   for (iX = 0; iX < pData->iRowsamples; iX++)
10841 #endif
10842   {
10843     if (!iM)                           /* mask underflow ? */
10844     {
10845       iB = *pWorkrow;                  /* get next input-byte */
10846       pWorkrow++;
10847       iM = 0xC0;
10848       iS = 6;
10849     }
10850 
10851 #ifdef MNG_OPTIMIZE_FOOTPRINT_SWITCH
10852     {
10853       const mng_uint8  alpha_level[4] = { 0x00, 0x55, 0xAA, 0xFF};
10854         *pOutrow = alpha_level[((iB & iM) >> iS)] ;
10855     }
10856 #else
10857     switch ((iB & iM) >> iS)           /* determine the alpha level */
10858     {
10859       case 0x03 : { *pOutrow = 0xFF; break; }
10860       case 0x02 : { *pOutrow = 0xAA; break; }
10861       case 0x01 : { *pOutrow = 0x55; break; }
10862       default   : { *pOutrow = 0x00; }
10863     }
10864 #endif
10865 
10866     pOutrow += 2;                      /* next pixel */
10867     iM >>=  2;
10868     iS -= 2;
10869   }
10870 
10871 #ifdef MNG_SUPPORT_TRACE
10872   MNG_TRACE (pData, MNG_FN_STORE_JPEG_G8_A2, MNG_LC_END);
10873 #endif
10874                                        /* we've got one more row of alpha-samples */
10875   return mng_next_jpeg_alpharow (pData);
10876 }
10877 
10878 /* ************************************************************************** */
10879 
mng_store_jpeg_g8_a4(mng_datap pData)10880 mng_retcode mng_store_jpeg_g8_a4 (mng_datap pData)
10881 {
10882   mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
10883   mng_uint8p     pWorkrow;
10884   mng_uint8p     pOutrow;
10885   mng_int32      iX;
10886   mng_uint8      iB;
10887   mng_uint8      iM;
10888   mng_uint32     iS;
10889   mng_uint8      iQ;
10890 
10891 #ifdef MNG_SUPPORT_TRACE
10892   MNG_TRACE (pData, MNG_FN_STORE_JPEG_G8_A4, MNG_LC_START);
10893 #endif
10894                                        /* temporary work pointers */
10895   pWorkrow = pData->pWorkrow + pData->iPixelofs;
10896   pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
10897                               (pData->iCol * pBuf->iSamplesize) + 1;
10898   iM       = 0;                        /* start at pixel 0 */
10899   iB       = 0;
10900   iS       = 0;
10901 
10902 #ifdef MNG_DECREMENT_LOOPS
10903   for (iX = pData->iRowsamples; iX > 0; iX--)
10904 #else
10905   for (iX = 0; iX < pData->iRowsamples; iX++)
10906 #endif
10907   {
10908     if (!iM)                           /* mask underflow ? */
10909     {
10910       iB = *pWorkrow;                  /* get next input-byte */
10911       pWorkrow++;
10912       iM = 0xF0;
10913       iS = 4;
10914     }
10915                                        /* get the alpha level */
10916     iQ = (mng_uint8)((iB & iM) >> iS);
10917     iQ = (mng_uint8)(iQ + (iQ << 4));  /* expand to 8-bit by replication */
10918 
10919     *pOutrow = iQ;                     /* put in object buffer */
10920 
10921     pOutrow += 2;                      /* next pixel */
10922     iM >>=  4;
10923     iS -= 4;
10924   }
10925 
10926 #ifdef MNG_SUPPORT_TRACE
10927   MNG_TRACE (pData, MNG_FN_STORE_JPEG_G8_A4, MNG_LC_END);
10928 #endif
10929                                        /* we've got one more row of alpha-samples */
10930   return mng_next_jpeg_alpharow (pData);
10931 }
10932 #endif
10933 
10934 /* ************************************************************************** */
10935 
mng_store_jpeg_g8_a8(mng_datap pData)10936 mng_retcode mng_store_jpeg_g8_a8 (mng_datap pData)
10937 {
10938   mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
10939   mng_uint8p     pWorkrow;
10940   mng_uint8p     pOutrow;
10941   mng_int32      iX;
10942 
10943 #ifdef MNG_SUPPORT_TRACE
10944   MNG_TRACE (pData, MNG_FN_STORE_JPEG_G8_A8, MNG_LC_START);
10945 #endif
10946                                        /* temporary work pointers */
10947   pWorkrow = pData->pWorkrow + pData->iPixelofs;
10948   pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
10949                               (pData->iCol * pBuf->iSamplesize) + 1;
10950 
10951 #ifdef MNG_DECREMENT_LOOPS
10952   for (iX = pData->iRowsamples; iX > 0; iX--)
10953 #else
10954   for (iX = 0; iX < pData->iRowsamples; iX++)
10955 #endif
10956   {
10957     *pOutrow = *pWorkrow;              /* put in object buffer */
10958 
10959     pOutrow += 2;                      /* next pixel */
10960     pWorkrow++;
10961   }
10962 
10963 #ifdef MNG_SUPPORT_TRACE
10964   MNG_TRACE (pData, MNG_FN_STORE_JPEG_G8_A8, MNG_LC_END);
10965 #endif
10966                                        /* we've got one more row of alpha-samples */
10967   return mng_next_jpeg_alpharow (pData);
10968 }
10969 
10970 /* ************************************************************************** */
10971 
10972 #ifndef MNG_NO_16BIT_SUPPORT
mng_store_jpeg_g8_a16(mng_datap pData)10973 mng_retcode mng_store_jpeg_g8_a16 (mng_datap pData)
10974 {
10975   mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
10976   mng_uint8p     pWorkrow;
10977   mng_uint8p     pOutrow;
10978   mng_int32      iX;
10979 
10980 #ifdef MNG_SUPPORT_TRACE
10981   MNG_TRACE (pData, MNG_FN_STORE_JPEG_G8_A16, MNG_LC_START);
10982 #endif
10983                                        /* temporary work pointers */
10984   pWorkrow = pData->pWorkrow + pData->iPixelofs;
10985   pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
10986                               (pData->iCol * pBuf->iSamplesize) + 1;
10987 
10988 #ifdef MNG_DECREMENT_LOOPS
10989   for (iX = pData->iRowsamples; iX > 0; iX--)
10990 #else
10991   for (iX = 0; iX < pData->iRowsamples; iX++)
10992 #endif
10993   {
10994     *pOutrow = *pWorkrow;              /* only high-order byte! */
10995 
10996     pOutrow  += 2;                     /* next pixel */
10997     pWorkrow += 2;
10998   }
10999 
11000 #ifdef MNG_SUPPORT_TRACE
11001   MNG_TRACE (pData, MNG_FN_STORE_JPEG_G8_A16, MNG_LC_END);
11002 #endif
11003                                        /* we've got one more row of alpha-samples */
11004   return mng_next_jpeg_alpharow (pData);
11005 }
11006 #endif
11007 
11008 /* ************************************************************************** */
11009 
11010 #ifndef MNG_NO_1_2_4BIT_SUPPORT
mng_store_jpeg_rgb8_a1(mng_datap pData)11011 mng_retcode mng_store_jpeg_rgb8_a1 (mng_datap pData)
11012 {
11013   mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
11014   mng_uint8p     pWorkrow;
11015   mng_uint8p     pOutrow;
11016   mng_int32      iX;
11017   mng_uint8      iB;
11018   mng_uint8      iM;
11019 
11020 #ifdef MNG_SUPPORT_TRACE
11021   MNG_TRACE (pData, MNG_FN_STORE_JPEG_RGB8_A1, MNG_LC_START);
11022 #endif
11023                                        /* temporary work pointers */
11024   pWorkrow = pData->pWorkrow + pData->iPixelofs;
11025   pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
11026                               (pData->iCol * pBuf->iSamplesize) + 3;
11027   iM       = 0;                        /* start at pixel 0 */
11028   iB       = 0;
11029 
11030 #ifdef MNG_DECREMENT_LOOPS
11031   for (iX = pData->iRowsamples; iX > 0; iX--)
11032 #else
11033   for (iX = 0; iX < pData->iRowsamples; iX++)
11034 #endif
11035   {
11036     if (!iM)                           /* mask underflow ? */
11037     {
11038       iB = *pWorkrow;                  /* get next input-byte */
11039       pWorkrow++;
11040       iM = 0x80;
11041     }
11042 
11043     if (iB & iM)                       /* is it opaque ? */
11044       *pOutrow = 0xFF;                 /* opaque */
11045     else
11046       *pOutrow = 0x00;                 /* transparent */
11047 
11048     pOutrow += 4;                      /* next pixel */
11049     iM >>=  1;
11050   }
11051 
11052 #ifdef MNG_SUPPORT_TRACE
11053   MNG_TRACE (pData, MNG_FN_STORE_JPEG_RGB8_A1, MNG_LC_END);
11054 #endif
11055                                        /* we've got one more row of alpha-samples */
11056   return mng_next_jpeg_alpharow (pData);
11057 }
11058 
11059 /* ************************************************************************** */
11060 
mng_store_jpeg_rgb8_a2(mng_datap pData)11061 mng_retcode mng_store_jpeg_rgb8_a2 (mng_datap pData)
11062 {
11063   mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
11064   mng_uint8p     pWorkrow;
11065   mng_uint8p     pOutrow;
11066   mng_int32      iX;
11067   mng_uint8      iB;
11068   mng_uint8      iM;
11069   mng_uint32     iS;
11070 
11071 #ifdef MNG_SUPPORT_TRACE
11072   MNG_TRACE (pData, MNG_FN_STORE_JPEG_RGB8_A2, MNG_LC_START);
11073 #endif
11074                                        /* temporary work pointers */
11075   pWorkrow = pData->pWorkrow + pData->iPixelofs;
11076   pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
11077                               (pData->iCol * pBuf->iSamplesize) + 3;
11078   iM       = 0;                        /* start at pixel 0 */
11079   iB       = 0;
11080   iS       = 0;
11081 
11082 #ifdef MNG_DECREMENT_LOOPS
11083   for (iX = pData->iRowsamples; iX > 0; iX--)
11084 #else
11085   for (iX = 0; iX < pData->iRowsamples; iX++)
11086 #endif
11087   {
11088     if (!iM)                           /* mask underflow ? */
11089     {
11090       iB = *pWorkrow;                  /* get next input-byte */
11091       pWorkrow++;
11092       iM = 0xC0;
11093       iS = 6;
11094     }
11095 
11096 #ifdef MNG_OPTIMIZE_FOOTPRINT_SWITCH
11097     {
11098       const mng_uint8  alpha_level[4] = { 0x00, 0x55, 0xAA, 0xFF};
11099       *pOutrow = alpha_level[((iB & iM) >> iS)] ;
11100     }
11101 #else
11102     switch ((iB & iM) >> iS)           /* determine the alpha level */
11103     {
11104       case 0x03 : { *pOutrow = 0xFF; break; }
11105       case 0x02 : { *pOutrow = 0xAA; break; }
11106       case 0x01 : { *pOutrow = 0x55; break; }
11107       default   : { *pOutrow = 0x00; }
11108     }
11109 #endif
11110 
11111     pOutrow += 4;                      /* next pixel */
11112     iM >>=  2;
11113     iS -= 2;
11114   }
11115 
11116 #ifdef MNG_SUPPORT_TRACE
11117   MNG_TRACE (pData, MNG_FN_STORE_JPEG_RGB8_A2, MNG_LC_END);
11118 #endif
11119                                        /* we've got one more row of alpha-samples */
11120   return mng_next_jpeg_alpharow (pData);
11121 }
11122 
11123 /* ************************************************************************** */
11124 
mng_store_jpeg_rgb8_a4(mng_datap pData)11125 mng_retcode mng_store_jpeg_rgb8_a4 (mng_datap pData)
11126 {
11127   mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
11128   mng_uint8p     pWorkrow;
11129   mng_uint8p     pOutrow;
11130   mng_int32      iX;
11131   mng_uint8      iB;
11132   mng_uint8      iM;
11133   mng_uint32     iS;
11134   mng_uint8      iQ;
11135 
11136 #ifdef MNG_SUPPORT_TRACE
11137   MNG_TRACE (pData, MNG_FN_STORE_JPEG_RGB8_A4, MNG_LC_START);
11138 #endif
11139                                        /* temporary work pointers */
11140   pWorkrow = pData->pWorkrow + pData->iPixelofs;
11141   pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
11142                               (pData->iCol * pBuf->iSamplesize) + 3;
11143   iM       = 0;                        /* start at pixel 0 */
11144   iB       = 0;
11145   iS       = 0;
11146 
11147 #ifdef MNG_DECREMENT_LOOPS
11148   for (iX = pData->iRowsamples; iX > 0; iX--)
11149 #else
11150   for (iX = 0; iX < pData->iRowsamples; iX++)
11151 #endif
11152   {
11153     if (!iM)                           /* mask underflow ? */
11154     {
11155       iB = *pWorkrow;                  /* get next input-byte */
11156       pWorkrow++;
11157       iM = 0xF0;
11158       iS = 4;
11159     }
11160                                        /* get the alpha level */
11161     iQ = (mng_uint8)((iB & iM) >> iS);
11162     iQ = (mng_uint8)(iQ + (iQ << 4));  /* expand to 8-bit by replication */
11163 
11164     *pOutrow = iQ;                     /* put in object buffer */
11165 
11166     pOutrow += 4;                      /* next pixel */
11167     iM >>=  4;
11168     iS -= 4;
11169   }
11170 
11171 #ifdef MNG_SUPPORT_TRACE
11172   MNG_TRACE (pData, MNG_FN_STORE_JPEG_RGB8_A4, MNG_LC_END);
11173 #endif
11174                                        /* we've got one more row of alpha-samples */
11175   return mng_next_jpeg_alpharow (pData);
11176 }
11177 #endif
11178 
11179 /* ************************************************************************** */
11180 
mng_store_jpeg_rgb8_a8(mng_datap pData)11181 mng_retcode mng_store_jpeg_rgb8_a8 (mng_datap pData)
11182 {
11183   mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
11184   mng_uint8p     pWorkrow;
11185   mng_uint8p     pOutrow;
11186   mng_int32      iX;
11187 
11188 #ifdef MNG_SUPPORT_TRACE
11189   MNG_TRACE (pData, MNG_FN_STORE_JPEG_RGB8_A8, MNG_LC_START);
11190 #endif
11191                                        /* temporary work pointers */
11192   pWorkrow = pData->pWorkrow + pData->iPixelofs;
11193   pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
11194                               (pData->iCol * pBuf->iSamplesize) + 3;
11195 
11196 #ifdef MNG_DECREMENT_LOOPS
11197   for (iX = pData->iRowsamples; iX > 0; iX--)
11198 #else
11199   for (iX = 0; iX < pData->iRowsamples; iX++)
11200 #endif
11201   {
11202     *pOutrow = *pWorkrow;              /* put in buffer */
11203 
11204     pOutrow += 4;                      /* next pixel */
11205     pWorkrow++;
11206   }
11207 
11208 #ifdef MNG_SUPPORT_TRACE
11209   MNG_TRACE (pData, MNG_FN_STORE_JPEG_RGB8_A8, MNG_LC_END);
11210 #endif
11211                                        /* we've got one more row of alpha-samples */
11212   return mng_next_jpeg_alpharow (pData);
11213 }
11214 
11215 /* ************************************************************************** */
11216 
11217 #ifndef MNG_NO_16BIT_SUPPORT
mng_store_jpeg_rgb8_a16(mng_datap pData)11218 mng_retcode mng_store_jpeg_rgb8_a16 (mng_datap pData)
11219 {
11220   mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
11221   mng_uint8p     pWorkrow;
11222   mng_uint8p     pOutrow;
11223   mng_int32      iX;
11224 
11225 #ifdef MNG_SUPPORT_TRACE
11226   MNG_TRACE (pData, MNG_FN_STORE_JPEG_RGB8_A16, MNG_LC_START);
11227 #endif
11228                                        /* temporary work pointers */
11229   pWorkrow = pData->pWorkrow + pData->iPixelofs;
11230   pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
11231                               (pData->iCol * pBuf->iSamplesize) + 3;
11232 
11233 #ifdef MNG_DECREMENT_LOOPS
11234   for (iX = pData->iRowsamples; iX > 0; iX--)
11235 #else
11236   for (iX = 0; iX < pData->iRowsamples; iX++)
11237 #endif
11238   {
11239     *pOutrow = *pWorkrow;              /* only high-order byte */
11240 
11241     pOutrow  += 4;                     /* next pixel */
11242     pWorkrow += 2;
11243   }
11244 
11245 #ifdef MNG_SUPPORT_TRACE
11246   MNG_TRACE (pData, MNG_FN_STORE_JPEG_RGB8_A16, MNG_LC_END);
11247 #endif
11248                                        /* we've got one more row of alpha-samples */
11249   return mng_next_jpeg_alpharow (pData);
11250 }
11251 #endif
11252 
11253 /* ************************************************************************** */
11254 
11255 #ifdef MNG_SUPPORT_JPEG12
mng_store_jpeg_g12_a1(mng_datap pData)11256 mng_retcode mng_store_jpeg_g12_a1 (mng_datap pData)
11257 {
11258   mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
11259   mng_uint8p     pWorkrow;
11260   mng_uint8p     pOutrow;
11261   mng_int32      iX;
11262   mng_uint8      iB;
11263   mng_uint8      iM;
11264 
11265 #ifdef MNG_SUPPORT_TRACE
11266   MNG_TRACE (pData, MNG_FN_STORE_JPEG_G12_A1, MNG_LC_START);
11267 #endif
11268                                        /* temporary work pointers */
11269   pWorkrow = pData->pWorkrow + pData->iPixelofs;
11270   pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
11271                               (pData->iCol * pBuf->iSamplesize) + 2;
11272   iM       = 0;                        /* start at pixel 0 */
11273   iB       = 0;
11274 
11275 #ifdef MNG_DECREMENT_LOOPS
11276   for (iX = pData->iRowsamples; iX > 0; iX--)
11277 #else
11278   for (iX = 0; iX < pData->iRowsamples; iX++)
11279 #endif
11280   {
11281     if (!iM)                           /* mask underflow ? */
11282     {
11283       iB = *pWorkrow;                  /* get next input-byte */
11284       pWorkrow++;
11285       iM = 0x80;
11286     }
11287 
11288     if (iB & iM)                       /* opaque ? */
11289       mng_put_uint16 (pOutrow, 0xFFFF);/* opaque */
11290     else
11291       mng_put_uint16 (pOutrow, 0x0000);/* transparent */
11292 
11293     pOutrow += 4;                      /* next pixel */
11294     iM >>=  1;
11295   }
11296 
11297 #ifdef MNG_SUPPORT_TRACE
11298   MNG_TRACE (pData, MNG_FN_STORE_JPEG_G12_A1, MNG_LC_END);
11299 #endif
11300                                        /* we've got one more row of alpha-samples */
11301   return mng_next_jpeg_alpharow (pData);
11302 }
11303 #endif /* MNG_SUPPORT_JPEG12 */
11304 
11305 /* ************************************************************************** */
11306 
11307 #ifdef MNG_SUPPORT_JPEG12
mng_store_jpeg_g12_a2(mng_datap pData)11308 mng_retcode mng_store_jpeg_g12_a2 (mng_datap pData)
11309 {
11310   mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
11311   mng_uint8p     pWorkrow;
11312   mng_uint8p     pOutrow;
11313   mng_int32      iX;
11314   mng_uint8      iB;
11315   mng_uint8      iM;
11316   mng_uint32     iS;
11317 
11318 #ifdef MNG_SUPPORT_TRACE
11319   MNG_TRACE (pData, MNG_FN_STORE_JPEG_G12_A2, MNG_LC_START);
11320 #endif
11321                                        /* temporary work pointers */
11322   pWorkrow = pData->pWorkrow + pData->iPixelofs;
11323   pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
11324                               (pData->iCol * pBuf->iSamplesize) + 2;
11325   iM       = 0;                        /* start at pixel 0 */
11326   iB       = 0;
11327   iS       = 0;
11328 
11329 #ifdef MNG_DECREMENT_LOOPS
11330   for (iX = pData->iRowsamples; iX > 0; iX--)
11331 #else
11332   for (iX = 0; iX < pData->iRowsamples; iX++)
11333 #endif
11334   {
11335     if (!iM)                           /* mask underflow ? */
11336     {
11337       iB = *pWorkrow;                  /* get next input-byte */
11338       pWorkrow++;
11339       iM = 0xC0;
11340       iS = 6;
11341     }
11342 
11343 #ifdef MNG_OPTIMIZE_FOOTPRINT_SWITCH
11344     {
11345       const mng_uint16  gray_level[4] = { 0x0000, 0x5555, 0xAAAA, 0xFFFF};
11346       mng_put_uint16 (pOutrow, gray_level[((iB & iM) >> iS)]) ;
11347     }
11348 #else
11349     switch ((iB & iM) >> iS)           /* determine the gray level */
11350     {
11351       case 0x03 : { mng_put_uint16 (pOutrow, 0xFFFF); break; }
11352       case 0x02 : { mng_put_uint16 (pOutrow, 0xAAAA); break; }
11353       case 0x01 : { mng_put_uint16 (pOutrow, 0x5555); break; }
11354       default   : { mng_put_uint16 (pOutrow, 0x0000); }
11355     }
11356 #endif
11357 
11358     pOutrow += 4;                      /* next pixel */
11359     iM >>=  2;
11360     iS -= 2;
11361   }
11362 
11363 #ifdef MNG_SUPPORT_TRACE
11364   MNG_TRACE (pData, MNG_FN_STORE_JPEG_G12_A2, MNG_LC_END);
11365 #endif
11366                                        /* we've got one more row of alpha-samples */
11367   return mng_next_jpeg_alpharow (pData);
11368 }
11369 #endif /* MNG_SUPPORT_JPEG12 */
11370 
11371 /* ************************************************************************** */
11372 
11373 #ifdef MNG_SUPPORT_JPEG12
mng_store_jpeg_g12_a4(mng_datap pData)11374 mng_retcode mng_store_jpeg_g12_a4 (mng_datap pData)
11375 {
11376   mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
11377   mng_uint8p     pWorkrow;
11378   mng_uint8p     pOutrow;
11379   mng_int32      iX;
11380   mng_uint8      iB;
11381   mng_uint8      iM;
11382   mng_uint32     iS;
11383   mng_uint16     iQ;
11384 
11385 #ifdef MNG_SUPPORT_TRACE
11386   MNG_TRACE (pData, MNG_FN_STORE_JPEG_G12_A4, MNG_LC_START);
11387 #endif
11388                                        /* temporary work pointers */
11389   pWorkrow = pData->pWorkrow + pData->iPixelofs;
11390   pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
11391                               (pData->iCol * pBuf->iSamplesize) + 2;
11392   iM       = 0;                        /* start at pixel 0 */
11393   iB       = 0;
11394   iS       = 0;
11395 
11396 #ifdef MNG_DECREMENT_LOOPS
11397   for (iX = pData->iRowsamples; iX > 0; iX--)
11398 #else
11399   for (iX = 0; iX < pData->iRowsamples; iX++)
11400 #endif
11401   {
11402     if (!iM)                           /* mask underflow ? */
11403     {
11404       iB = *pWorkrow;                  /* get next input-byte */
11405       pWorkrow++;
11406       iM = 0xF0;
11407       iS = 4;
11408     }
11409                                        /* get the gray level */
11410     iQ = (mng_uint16)((iB & iM) >> iS);
11411     iQ = (mng_uint16)(iQ + (iQ << 4)); /* expand to 16-bit by replication */
11412     iQ = (mng_uint16)(iQ + (iQ << 8));
11413                                        /* put in object buffer */
11414     mng_put_uint16 (pOutrow, iQ);
11415 
11416     pOutrow += 4;                      /* next pixel */
11417     iM >>=  4;
11418     iS -= 4;
11419   }
11420 
11421 #ifdef MNG_SUPPORT_TRACE
11422   MNG_TRACE (pData, MNG_FN_STORE_JPEG_G12_A4, MNG_LC_END);
11423 #endif
11424                                        /* we've got one more row of alpha-samples */
11425   return mng_next_jpeg_alpharow (pData);
11426 }
11427 #endif /* MNG_SUPPORT_JPEG12 */
11428 
11429 /* ************************************************************************** */
11430 
11431 #ifdef MNG_SUPPORT_JPEG12
mng_store_jpeg_g12_a8(mng_datap pData)11432 mng_retcode mng_store_jpeg_g12_a8 (mng_datap pData)
11433 {
11434   mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
11435   mng_uint8p     pWorkrow;
11436   mng_uint8p     pOutrow;
11437   mng_int32      iX;
11438   mng_uint16     iW;
11439 
11440 #ifdef MNG_SUPPORT_TRACE
11441   MNG_TRACE (pData, MNG_FN_STORE_JPEG_G12_A8, MNG_LC_START);
11442 #endif
11443                                        /* temporary work pointers */
11444   pWorkrow = pData->pWorkrow + pData->iPixelofs;
11445   pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
11446                               (pData->iCol * pBuf->iSamplesize) + 2;
11447 
11448 #ifdef MNG_DECREMENT_LOOPS
11449   for (iX = pData->iRowsamples; iX > 0; iX--)
11450 #else
11451   for (iX = 0; iX < pData->iRowsamples; iX++)
11452 #endif
11453   {
11454     iW = (mng_uint16)(*pWorkrow);      /* get input byte */
11455     iW = (mng_uint16)(iW + (iW << 8)); /* expand to 16-bit by replication */
11456 
11457     mng_put_uint16 (pOutrow, iW);      /* put in object buffer */
11458 
11459     pOutrow += 4;                      /* next pixel */
11460     pWorkrow++;
11461   }
11462 
11463 #ifdef MNG_SUPPORT_TRACE
11464   MNG_TRACE (pData, MNG_FN_STORE_JPEG_G12_A8, MNG_LC_END);
11465 #endif
11466                                        /* we've got one more row of alpha-samples */
11467   return mng_next_jpeg_alpharow (pData);
11468 }
11469 #endif /* MNG_SUPPORT_JPEG12 */
11470 
11471 /* ************************************************************************** */
11472 
11473 #ifdef MNG_SUPPORT_JPEG12
11474 #ifndef MNG_NO_16BIT_SUPPORT
mng_store_jpeg_g12_a16(mng_datap pData)11475 mng_retcode mng_store_jpeg_g12_a16 (mng_datap pData)
11476 {
11477   mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
11478   mng_uint8p     pWorkrow;
11479   mng_uint8p     pOutrow;
11480   mng_int32      iX;
11481 
11482 #ifdef MNG_SUPPORT_TRACE
11483   MNG_TRACE (pData, MNG_FN_STORE_JPEG_G12_A16, MNG_LC_START);
11484 #endif
11485                                        /* temporary work pointers */
11486   pWorkrow = pData->pWorkrow + pData->iPixelofs;
11487   pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
11488                               (pData->iCol * pBuf->iSamplesize) + 2;
11489 
11490 #ifdef MNG_DECREMENT_LOOPS
11491   for (iX = pData->iRowsamples; iX > 0; iX--)
11492 #else
11493   for (iX = 0; iX < pData->iRowsamples; iX++)
11494 #endif
11495   {                                    /* copy it */
11496     mng_put_uint16 (pOutrow, mng_get_uint16 (pWorkrow));
11497 
11498     pOutrow  += 4;                     /* next pixel */
11499     pWorkrow += 2;
11500   }
11501 
11502 #ifdef MNG_SUPPORT_TRACE
11503   MNG_TRACE (pData, MNG_FN_STORE_JPEG_G12_A16, MNG_LC_END);
11504 #endif
11505                                        /* we've got one more row of alpha-samples */
11506   return mng_next_jpeg_alpharow (pData);
11507 }
11508 #endif
11509 #endif /* MNG_SUPPORT_JPEG12 */
11510 
11511 /* ************************************************************************** */
11512 
11513 #endif /* MNG_INCLUDE_JNG */
11514 
11515 #ifndef MNG_NO_DELTA_PNG
11516 /* ************************************************************************** */
11517 /* *                                                                        * */
11518 /* * Delta-image row routines - apply the processed & uncompressed row-data * */
11519 /* * onto the target "object"                                               * */
11520 /* *                                                                        * */
11521 /* ************************************************************************** */
11522 
11523 #ifndef MNG_NO_1_2_4BIT_SUPPORT
mng_delta_g1(mng_datap pData)11524 mng_retcode mng_delta_g1 (mng_datap pData)
11525 {
11526   mng_imagedatap pBuf = ((mng_imagep)pData->pDeltaImage)->pImgbuf;
11527   mng_uint8p     pWorkrow;
11528   mng_uint8p     pOutrow;
11529   mng_int32      iX;
11530   mng_uint8      iB;
11531   mng_uint8      iM;
11532 
11533 #ifdef MNG_SUPPORT_TRACE
11534   MNG_TRACE (pData, MNG_FN_DELTA_G1, MNG_LC_START);
11535 #endif
11536                                        /* temporary work pointers */
11537   pWorkrow = pData->pWorkrow + pData->iPixelofs;
11538   pOutrow  = pBuf->pImgdata + (pData->iRow         * pBuf->iRowsize   ) +
11539                               (pData->iDeltaBlocky * pBuf->iRowsize   ) +
11540                               (pData->iCol         * pBuf->iSamplesize) +
11541                               (pData->iDeltaBlockx * pBuf->iSamplesize);
11542   iM       = 0;                        /* start at pixel 0 */
11543   iB       = 0;
11544                                        /* pixel replace ? */
11545   if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)
11546   {
11547 #ifdef MNG_DECREMENT_LOOPS
11548     for (iX = pData->iRowsamples; iX > 0; iX--)
11549 #else
11550     for (iX = 0; iX < pData->iRowsamples; iX++)
11551 #endif
11552     {
11553       if (!iM)                         /* mask underflow ? */
11554       {
11555         iB = *pWorkrow;                /* get next input-byte */
11556         pWorkrow++;
11557         iM = 0x80;
11558       }
11559 
11560       if (iB & iM)                     /* is it white ? */
11561         *pOutrow = 0xFF;               /* white */
11562       else
11563         *pOutrow = 0x00;               /* black */
11564 
11565       pOutrow += pData->iColinc;       /* next pixel */
11566       iM >>=  1;
11567     }
11568   }
11569   else
11570   {                                    /* pixel add ! */
11571 #ifdef MNG_DECREMENT_LOOPS
11572     for (iX = pData->iRowsamples; iX > 0; iX--)
11573 #else
11574     for (iX = 0; iX < pData->iRowsamples; iX++)
11575 #endif
11576     {
11577       if (!iM)                         /* mask underflow ? */
11578       {
11579         iB = *pWorkrow;                /* get next input-byte */
11580         pWorkrow++;
11581         iM = 0x80;
11582       }
11583 
11584       if (iB & iM)                     /* invert if it is white ? */
11585         *pOutrow = (mng_uint8)(*pOutrow ^ 0xFF);
11586 
11587       pOutrow += pData->iColinc;       /* next pixel */
11588       iM >>=  1;
11589     }
11590   }
11591 
11592 #ifdef MNG_SUPPORT_TRACE
11593   MNG_TRACE (pData, MNG_FN_DELTA_G1, MNG_LC_END);
11594 #endif
11595 
11596   return mng_store_g1 (pData);
11597 }
11598 
11599 /* ************************************************************************** */
11600 
mng_delta_g2(mng_datap pData)11601 mng_retcode mng_delta_g2 (mng_datap pData)
11602 {
11603   mng_imagedatap pBuf = ((mng_imagep)pData->pDeltaImage)->pImgbuf;
11604   mng_uint8p     pWorkrow;
11605   mng_uint8p     pOutrow;
11606   mng_int32      iX;
11607   mng_uint8      iB;
11608   mng_uint8      iM;
11609   mng_uint32     iS;
11610 #ifdef MNG_OPTIMIZE_FOOTPRINT_SWITCH
11611   const mng_uint8  level[4] = { 0x00, 0x55, 0xAA, 0xFF};
11612 #endif
11613 
11614 #ifdef MNG_SUPPORT_TRACE
11615   MNG_TRACE (pData, MNG_FN_DELTA_G2, MNG_LC_START);
11616 #endif
11617                                        /* temporary work pointers */
11618   pWorkrow = pData->pWorkrow + pData->iPixelofs;
11619   pOutrow  = pBuf->pImgdata + (pData->iRow         * pBuf->iRowsize   ) +
11620                               (pData->iDeltaBlocky * pBuf->iRowsize   ) +
11621                               (pData->iCol         * pBuf->iSamplesize) +
11622                               (pData->iDeltaBlockx * pBuf->iSamplesize);
11623   iM       = 0;                        /* start at pixel 0 */
11624   iB       = 0;
11625   iS       = 0;
11626                                        /* pixel replace ? */
11627   if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)
11628   {
11629 #ifdef MNG_DECREMENT_LOOPS
11630     for (iX = pData->iRowsamples; iX > 0; iX--)
11631 #else
11632     for (iX = 0; iX < pData->iRowsamples; iX++)
11633 #endif
11634     {
11635       if (!iM)                         /* mask underflow ? */
11636       {
11637         iB = *pWorkrow;                /* get next input-byte */
11638         pWorkrow++;
11639         iM = 0xC0;
11640         iS = 6;
11641       }
11642 
11643 #ifdef MNG_OPTIMIZE_FOOTPRINT_SWITCH
11644     *pOutrow = level[((iB & iM) >> iS)] ;
11645 #else
11646     switch ((iB & iM) >> iS)           /* determine the alpha level */
11647     {
11648       case 0x03 : { *pOutrow = 0xFF; break; }
11649       case 0x02 : { *pOutrow = 0xAA; break; }
11650       case 0x01 : { *pOutrow = 0x55; break; }
11651       default   : { *pOutrow = 0x00; }
11652     }
11653 #endif
11654 
11655       pOutrow += pData->iColinc;       /* next pixel */
11656       iM >>=  2;
11657       iS -= 2;
11658     }
11659   }
11660   else
11661   {                                    /* pixel add ! */
11662 #ifdef MNG_DECREMENT_LOOPS
11663     for (iX = pData->iRowsamples; iX > 0; iX--)
11664 #else
11665     for (iX = 0; iX < pData->iRowsamples; iX++)
11666 #endif
11667     {
11668       if (!iM)                         /* mask underflow ? */
11669       {
11670         iB = *pWorkrow;                /* get next input-byte */
11671         pWorkrow++;
11672         iM = 0xC0;
11673         iS = 6;
11674       }
11675 
11676 #ifdef MNG_OPTIMIZE_FOOTPRINT_SWITCH
11677       *pOutrow = level[((*pOutrow >> 6) + ((iB & iM) >> iS)) & 0x03] ;
11678 #else
11679       switch (((*pOutrow >> 6) + ((iB & iM) >> iS)) & 0x03)
11680       {
11681         case 0x03 : { *pOutrow = 0xFF; break; }
11682         case 0x02 : { *pOutrow = 0xAA; break; }
11683         case 0x01 : { *pOutrow = 0x55; break; }
11684         default   : { *pOutrow = 0x00; }
11685       }
11686 #endif
11687 
11688       pOutrow += pData->iColinc;       /* next pixel */
11689       iM >>=  2;
11690       iS -= 2;
11691     }
11692   }
11693 
11694 #ifdef MNG_SUPPORT_TRACE
11695   MNG_TRACE (pData, MNG_FN_DELTA_G2, MNG_LC_END);
11696 #endif
11697 
11698   return mng_store_g2 (pData);
11699 }
11700 
11701 /* ************************************************************************** */
11702 
mng_delta_g4(mng_datap pData)11703 mng_retcode mng_delta_g4 (mng_datap pData)
11704 {
11705   mng_imagedatap pBuf = ((mng_imagep)pData->pDeltaImage)->pImgbuf;
11706   mng_uint8p     pWorkrow;
11707   mng_uint8p     pOutrow;
11708   mng_int32      iX;
11709   mng_uint8      iB;
11710   mng_uint8      iM;
11711   mng_uint32     iS;
11712   mng_uint8      iQ;
11713 
11714 #ifdef MNG_SUPPORT_TRACE
11715   MNG_TRACE (pData, MNG_FN_DELTA_G4, MNG_LC_START);
11716 #endif
11717                                        /* temporary work pointers */
11718   pWorkrow = pData->pWorkrow + pData->iPixelofs;
11719   pOutrow  = pBuf->pImgdata + (pData->iRow         * pBuf->iRowsize   ) +
11720                               (pData->iDeltaBlocky * pBuf->iRowsize   ) +
11721                               (pData->iCol         * pBuf->iSamplesize) +
11722                               (pData->iDeltaBlockx * pBuf->iSamplesize);
11723   iM       = 0;                        /* start at pixel 0 */
11724   iB       = 0;
11725   iS       = 0;
11726                                        /* pixel replace ? */
11727   if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)
11728   {
11729 #ifdef MNG_DECREMENT_LOOPS
11730     for (iX = pData->iRowsamples; iX > 0; iX--)
11731 #else
11732     for (iX = 0; iX < pData->iRowsamples; iX++)
11733 #endif
11734     {
11735       if (!iM)                         /* mask underflow ? */
11736       {
11737         iB = *pWorkrow;                /* get next input-byte */
11738         pWorkrow++;
11739         iM = 0xF0;
11740         iS = 4;
11741       }
11742                                        /* get the gray level */
11743       iQ = (mng_uint8)((iB & iM) >> iS);
11744                                        /* expand to 8-bit by replication */
11745       iQ = (mng_uint8)(iQ + (iQ << 4));
11746 
11747       *pOutrow = iQ;                   /* put in object buffer */
11748 
11749       pOutrow += pData->iColinc;       /* next pixel */
11750       iM >>=  4;
11751       iS -= 4;
11752     }
11753   }
11754   else
11755   {                                    /* pixel add ! */
11756 #ifdef MNG_DECREMENT_LOOPS
11757     for (iX = pData->iRowsamples; iX > 0; iX--)
11758 #else
11759     for (iX = 0; iX < pData->iRowsamples; iX++)
11760 #endif
11761     {
11762       if (!iM)                         /* mask underflow ? */
11763       {
11764         iB = *pWorkrow;                /* get next input-byte */
11765         pWorkrow++;
11766         iM = 0xF0;
11767         iS = 4;
11768       }
11769                                        /* get the gray level */
11770       iQ = (mng_uint8)(((*pOutrow >> 4) + ((iB & iM) >> iS)) & 0x0F);
11771                                        /* expand to 8-bit by replication */
11772       iQ = (mng_uint8)(iQ + (iQ << 4));
11773 
11774       *pOutrow = iQ;                   /* put in object buffer */
11775 
11776       pOutrow += pData->iColinc;       /* next pixel */
11777       iM >>=  4;
11778       iS -= 4;
11779     }
11780   }
11781 
11782 #ifdef MNG_SUPPORT_TRACE
11783   MNG_TRACE (pData, MNG_FN_DELTA_G4, MNG_LC_END);
11784 #endif
11785 
11786   return mng_store_g4 (pData);
11787 }
11788 #endif /* MNG_NO_1_2_4BIT_SUPPORT */
11789 
11790 /* ************************************************************************** */
11791 
mng_delta_g8(mng_datap pData)11792 mng_retcode mng_delta_g8 (mng_datap pData)
11793 {
11794   mng_imagedatap pBuf = ((mng_imagep)pData->pDeltaImage)->pImgbuf;
11795   mng_uint8p     pWorkrow;
11796   mng_uint8p     pOutrow;
11797   mng_int32      iX;
11798 
11799 #ifdef MNG_SUPPORT_TRACE
11800   MNG_TRACE (pData, MNG_FN_DELTA_G8, MNG_LC_START);
11801 #endif
11802                                        /* temporary work pointers */
11803   pWorkrow = pData->pWorkrow + pData->iPixelofs;
11804   pOutrow  = pBuf->pImgdata + (pData->iRow         * pBuf->iRowsize   ) +
11805                               (pData->iDeltaBlocky * pBuf->iRowsize   ) +
11806                               (pData->iCol         * pBuf->iSamplesize) +
11807                               (pData->iDeltaBlockx * pBuf->iSamplesize);
11808                                        /* pixel replace ? */
11809   if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)
11810   {
11811 #ifdef MNG_DECREMENT_LOOPS
11812     for (iX = pData->iRowsamples; iX > 0; iX--)
11813 #else
11814     for (iX = 0; iX < pData->iRowsamples; iX++)
11815 #endif
11816     {
11817       *pOutrow = *pWorkrow;            /* put in object buffer */
11818 
11819       pOutrow += pData->iColinc;       /* next pixel */
11820       pWorkrow++;
11821     }
11822   }
11823   else
11824   {                                    /* pixel add ! */
11825 #ifdef MNG_DECREMENT_LOOPS
11826     for (iX = pData->iRowsamples; iX > 0; iX--)
11827 #else
11828     for (iX = 0; iX < pData->iRowsamples; iX++)
11829 #endif
11830     {                                  /* add to object buffer */
11831       *pOutrow = (mng_uint8)(*pOutrow + *pWorkrow);
11832 
11833       pOutrow += pData->iColinc;       /* next pixel */
11834       pWorkrow++;
11835     }
11836   }
11837 
11838 #ifdef MNG_SUPPORT_TRACE
11839   MNG_TRACE (pData, MNG_FN_DELTA_G8, MNG_LC_END);
11840 #endif
11841 
11842   return mng_store_g8 (pData);
11843 }
11844 
11845 /* ************************************************************************** */
11846 
11847 #ifndef MNG_NO_16BIT_SUPPORT
mng_delta_g16(mng_datap pData)11848 mng_retcode mng_delta_g16 (mng_datap pData)
11849 {
11850   mng_imagedatap pBuf = ((mng_imagep)pData->pDeltaImage)->pImgbuf;
11851   mng_uint8p     pWorkrow;
11852   mng_uint8p     pOutrow;
11853   mng_int32      iX;
11854 
11855 #ifdef MNG_SUPPORT_TRACE
11856   MNG_TRACE (pData, MNG_FN_DELTA_G16, MNG_LC_START);
11857 #endif
11858                                        /* temporary work pointers */
11859   pWorkrow = pData->pWorkrow + pData->iPixelofs;
11860   pOutrow  = pBuf->pImgdata + (pData->iRow         * pBuf->iRowsize   ) +
11861                               (pData->iDeltaBlocky * pBuf->iRowsize   ) +
11862                               (pData->iCol         * pBuf->iSamplesize) +
11863                               (pData->iDeltaBlockx * pBuf->iSamplesize);
11864                                        /* pixel replace ? */
11865   if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)
11866   {
11867 #ifdef MNG_DECREMENT_LOOPS
11868     for (iX = pData->iRowsamples; iX > 0; iX--)
11869 #else
11870     for (iX = 0; iX < pData->iRowsamples; iX++)
11871 #endif
11872     {
11873       *pOutrow     = *pWorkrow;        /* put in object buffer */
11874       *(pOutrow+1) = *(pWorkrow+1);
11875                                        /* next pixel */
11876       pOutrow  += (pData->iColinc << 1);
11877       pWorkrow += 2;
11878     }
11879   }
11880   else
11881   {                                    /* pixel add ! */
11882 #ifdef MNG_DECREMENT_LOOPS
11883     for (iX = pData->iRowsamples; iX > 0; iX--)
11884 #else
11885     for (iX = 0; iX < pData->iRowsamples; iX++)
11886 #endif
11887     {                                  /* add to object buffer */
11888       mng_put_uint16 (pOutrow, (mng_uint16)(mng_get_uint16 (pOutrow ) +
11889                                             mng_get_uint16 (pWorkrow)   ));
11890                                        /* next pixel */
11891       pOutrow  += (pData->iColinc << 1);
11892       pWorkrow += 2;
11893     }
11894   }
11895 
11896 #ifdef MNG_SUPPORT_TRACE
11897   MNG_TRACE (pData, MNG_FN_DELTA_G16, MNG_LC_END);
11898 #endif
11899 
11900   return mng_store_g16 (pData);
11901 }
11902 #endif
11903 
11904 /* ************************************************************************** */
11905 
mng_delta_rgb8(mng_datap pData)11906 mng_retcode mng_delta_rgb8 (mng_datap pData)
11907 {
11908   mng_imagedatap pBuf = ((mng_imagep)pData->pDeltaImage)->pImgbuf;
11909   mng_uint8p     pWorkrow;
11910   mng_uint8p     pOutrow;
11911   mng_int32      iX;
11912 
11913 #ifdef MNG_SUPPORT_TRACE
11914   MNG_TRACE (pData, MNG_FN_DELTA_RGB8, MNG_LC_START);
11915 #endif
11916                                        /* temporary work pointers */
11917   pWorkrow = pData->pWorkrow + pData->iPixelofs;
11918   pOutrow  = pBuf->pImgdata + (pData->iRow         * pBuf->iRowsize   ) +
11919                               (pData->iDeltaBlocky * pBuf->iRowsize   ) +
11920                               (pData->iCol         * pBuf->iSamplesize) +
11921                               (pData->iDeltaBlockx * pBuf->iSamplesize);
11922                                        /* pixel replace ? */
11923   if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)
11924   {
11925 #ifdef MNG_DECREMENT_LOOPS
11926     for (iX = pData->iRowsamples; iX > 0; iX--)
11927 #else
11928     for (iX = 0; iX < pData->iRowsamples; iX++)
11929 #endif
11930     {
11931       *pOutrow     = *pWorkrow;        /* put in object buffer */
11932       *(pOutrow+1) = *(pWorkrow+1);
11933       *(pOutrow+2) = *(pWorkrow+2);
11934                                        /* next pixel */
11935       pOutrow  += (pData->iColinc * 3);
11936       pWorkrow += 3;
11937     }
11938   }
11939   else
11940   {                                    /* pixel add ! */
11941 #ifdef MNG_DECREMENT_LOOPS
11942     for (iX = pData->iRowsamples; iX > 0; iX--)
11943 #else
11944     for (iX = 0; iX < pData->iRowsamples; iX++)
11945 #endif
11946     {                                  /* add to object buffer */
11947       *pOutrow     = (mng_uint8)(*pOutrow     + *pWorkrow    );
11948       *(pOutrow+1) = (mng_uint8)(*(pOutrow+1) + *(pWorkrow+1));
11949       *(pOutrow+2) = (mng_uint8)(*(pOutrow+2) + *(pWorkrow+2));
11950                                        /* next pixel */
11951       pOutrow  += (pData->iColinc * 3);
11952       pWorkrow += 3;
11953     }
11954   }
11955 
11956 #ifdef MNG_SUPPORT_TRACE
11957   MNG_TRACE (pData, MNG_FN_DELTA_RGB8, MNG_LC_END);
11958 #endif
11959 
11960   return mng_store_rgb8 (pData);
11961 }
11962 
11963 /* ************************************************************************** */
11964 
11965 #ifndef MNG_NO_16BIT_SUPPORT
mng_delta_rgb16(mng_datap pData)11966 mng_retcode mng_delta_rgb16 (mng_datap pData)
11967 {
11968   mng_imagedatap pBuf = ((mng_imagep)pData->pDeltaImage)->pImgbuf;
11969   mng_uint8p     pWorkrow;
11970   mng_uint8p     pOutrow;
11971   mng_int32      iX;
11972 
11973 #ifdef MNG_SUPPORT_TRACE
11974   MNG_TRACE (pData, MNG_FN_DELTA_RGB16, MNG_LC_START);
11975 #endif
11976                                        /* temporary work pointers */
11977   pWorkrow = pData->pWorkrow + pData->iPixelofs;
11978   pOutrow  = pBuf->pImgdata + (pData->iRow         * pBuf->iRowsize   ) +
11979                               (pData->iDeltaBlocky * pBuf->iRowsize   ) +
11980                               (pData->iCol         * pBuf->iSamplesize) +
11981                               (pData->iDeltaBlockx * pBuf->iSamplesize);
11982                                        /* pixel replace ? */
11983   if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)
11984   {
11985 #ifdef MNG_DECREMENT_LOOPS
11986     for (iX = pData->iRowsamples; iX > 0; iX--)
11987 #else
11988     for (iX = 0; iX < pData->iRowsamples; iX++)
11989 #endif
11990     {
11991       *pOutrow     = *pWorkrow;        /* put in object buffer */
11992       *(pOutrow+1) = *(pWorkrow+1);
11993       *(pOutrow+2) = *(pWorkrow+2);
11994       *(pOutrow+3) = *(pWorkrow+3);
11995       *(pOutrow+4) = *(pWorkrow+4);
11996       *(pOutrow+5) = *(pWorkrow+5);
11997                                        /* next pixel */
11998       pOutrow  += (pData->iColinc * 6);
11999       pWorkrow += 6;
12000     }
12001   }
12002   else
12003   {                                    /* pixel add ! */
12004 #ifdef MNG_DECREMENT_LOOPS
12005     for (iX = pData->iRowsamples; iX > 0; iX--)
12006 #else
12007     for (iX = 0; iX < pData->iRowsamples; iX++)
12008 #endif
12009     {                                  /* add to object buffer */
12010       mng_put_uint16 (pOutrow,   (mng_uint16)(mng_get_uint16 (pOutrow   ) +
12011                                               mng_get_uint16 (pWorkrow  )   ));
12012       mng_put_uint16 (pOutrow+2, (mng_uint16)(mng_get_uint16 (pOutrow+2 ) +
12013                                               mng_get_uint16 (pWorkrow+2)   ));
12014       mng_put_uint16 (pOutrow+4, (mng_uint16)(mng_get_uint16 (pOutrow+4 ) +
12015                                               mng_get_uint16 (pWorkrow+4)   ));
12016                                        /* next pixel */
12017       pOutrow  += (pData->iColinc * 6);
12018       pWorkrow += 6;
12019     }
12020   }
12021 
12022 #ifdef MNG_SUPPORT_TRACE
12023   MNG_TRACE (pData, MNG_FN_DELTA_RGB16, MNG_LC_END);
12024 #endif
12025 
12026   return mng_store_rgb16 (pData);
12027 }
12028 #endif
12029 
12030 /* ************************************************************************** */
12031 
12032 #ifndef MNG_NO_1_2_4BIT_SUPPORT
mng_delta_idx1(mng_datap pData)12033 mng_retcode mng_delta_idx1 (mng_datap pData)
12034 {
12035   mng_imagedatap pBuf = ((mng_imagep)pData->pDeltaImage)->pImgbuf;
12036   mng_uint8p     pWorkrow;
12037   mng_uint8p     pOutrow;
12038   mng_int32      iX;
12039   mng_uint8      iB;
12040   mng_uint8      iM;
12041 
12042 #ifdef MNG_SUPPORT_TRACE
12043   MNG_TRACE (pData, MNG_FN_DELTA_IDX1, MNG_LC_START);
12044 #endif
12045                                        /* temporary work pointers */
12046   pWorkrow = pData->pWorkrow + pData->iPixelofs;
12047   pOutrow  = pBuf->pImgdata + (pData->iRow         * pBuf->iRowsize   ) +
12048                               (pData->iDeltaBlocky * pBuf->iRowsize   ) +
12049                               (pData->iCol         * pBuf->iSamplesize) +
12050                               (pData->iDeltaBlockx * pBuf->iSamplesize);
12051   iM       = 0;                        /* start at pixel 0 */
12052   iB       = 0;
12053                                        /* pixel replace ? */
12054   if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)
12055   {
12056 #ifdef MNG_DECREMENT_LOOPS
12057     for (iX = pData->iRowsamples; iX > 0; iX--)
12058 #else
12059     for (iX = 0; iX < pData->iRowsamples; iX++)
12060 #endif
12061     {
12062       if (!iM)                         /* mask underflow ? */
12063       {
12064         iB = *pWorkrow;                /* get next input-byte */
12065         pWorkrow++;
12066         iM = 0x80;
12067       }
12068 
12069       if (iB & iM)                     /* put the right index value */
12070         *pOutrow = 1;
12071       else
12072         *pOutrow = 0;
12073 
12074       pOutrow += pData->iColinc;       /* next pixel */
12075       iM >>=  1;
12076     }
12077   }
12078   else
12079   {                                    /* pixel add ! */
12080 #ifdef MNG_DECREMENT_LOOPS
12081     for (iX = pData->iRowsamples; iX > 0; iX--)
12082 #else
12083     for (iX = 0; iX < pData->iRowsamples; iX++)
12084 #endif
12085     {
12086       if (!iM)                         /* mask underflow ? */
12087       {
12088         iB = *pWorkrow;                /* get next input-byte */
12089         pWorkrow++;
12090         iM = 0x80;
12091       }
12092 
12093       if (iB & iM)                     /* invert if it is non-zero index */
12094         *pOutrow = (mng_uint8)(*pOutrow ^ 0x01);
12095 
12096       pOutrow += pData->iColinc;       /* next pixel */
12097       iM >>=  1;
12098     }
12099   }
12100 
12101 #ifdef MNG_SUPPORT_TRACE
12102   MNG_TRACE (pData, MNG_FN_DELTA_IDX1, MNG_LC_END);
12103 #endif
12104 
12105   return mng_store_idx1 (pData);
12106 }
12107 
12108 /* ************************************************************************** */
12109 
mng_delta_idx2(mng_datap pData)12110 mng_retcode mng_delta_idx2 (mng_datap pData)
12111 {
12112   mng_imagedatap pBuf = ((mng_imagep)pData->pDeltaImage)->pImgbuf;
12113   mng_uint8p     pWorkrow;
12114   mng_uint8p     pOutrow;
12115   mng_int32      iX;
12116   mng_uint8      iB;
12117   mng_uint8      iM;
12118   mng_uint32     iS;
12119 
12120 #ifdef MNG_SUPPORT_TRACE
12121   MNG_TRACE (pData, MNG_FN_DELTA_IDX2, MNG_LC_START);
12122 #endif
12123                                        /* temporary work pointers */
12124   pWorkrow = pData->pWorkrow + pData->iPixelofs;
12125   pOutrow  = pBuf->pImgdata + (pData->iRow         * pBuf->iRowsize   ) +
12126                               (pData->iDeltaBlocky * pBuf->iRowsize   ) +
12127                               (pData->iCol         * pBuf->iSamplesize) +
12128                               (pData->iDeltaBlockx * pBuf->iSamplesize);
12129   iM       = 0;                        /* start at pixel 0 */
12130   iB       = 0;
12131   iS       = 0;
12132                                        /* pixel replace ? */
12133   if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)
12134   {
12135 #ifdef MNG_DECREMENT_LOOPS
12136     for (iX = pData->iRowsamples; iX > 0; iX--)
12137 #else
12138     for (iX = 0; iX < pData->iRowsamples; iX++)
12139 #endif
12140     {
12141       if (!iM)                         /* mask underflow ? */
12142       {
12143         iB = *pWorkrow;                /* get next input-byte */
12144         pWorkrow++;
12145         iM = 0xC0;
12146         iS = 6;
12147       }
12148                                        /* put the index */
12149       *pOutrow = (mng_uint8)((iB & iM) >> iS);
12150 
12151       pOutrow += pData->iColinc;       /* next pixel */
12152       iM >>=  2;
12153       iS -= 2;
12154     }
12155   }
12156   else
12157   {                                    /* pixel add ! */
12158 #ifdef MNG_DECREMENT_LOOPS
12159     for (iX = pData->iRowsamples; iX > 0; iX--)
12160 #else
12161     for (iX = 0; iX < pData->iRowsamples; iX++)
12162 #endif
12163     {
12164       if (!iM)                         /* mask underflow ? */
12165       {
12166         iB = *pWorkrow;                /* get next input-byte */
12167         pWorkrow++;
12168         iM = 0xC0;
12169         iS = 6;
12170       }
12171                                        /* calculate the index */
12172       *pOutrow = (mng_uint8)((*pOutrow + ((iB & iM) >> iS)) & 0x03);
12173 
12174       pOutrow += pData->iColinc;       /* next pixel */
12175       iM >>=  2;
12176       iS -= 2;
12177     }
12178   }
12179 
12180 #ifdef MNG_SUPPORT_TRACE
12181   MNG_TRACE (pData, MNG_FN_DELTA_IDX2, MNG_LC_END);
12182 #endif
12183 
12184   return mng_store_idx2 (pData);
12185 }
12186 
12187 /* ************************************************************************** */
12188 
mng_delta_idx4(mng_datap pData)12189 mng_retcode mng_delta_idx4 (mng_datap pData)
12190 {
12191   mng_imagedatap pBuf = ((mng_imagep)pData->pDeltaImage)->pImgbuf;
12192   mng_uint8p     pWorkrow;
12193   mng_uint8p     pOutrow;
12194   mng_int32      iX;
12195   mng_uint8      iB;
12196   mng_uint8      iM;
12197   mng_uint32     iS;
12198 
12199 #ifdef MNG_SUPPORT_TRACE
12200   MNG_TRACE (pData, MNG_FN_DELTA_IDX4, MNG_LC_START);
12201 #endif
12202                                        /* temporary work pointers */
12203   pWorkrow = pData->pWorkrow + pData->iPixelofs;
12204   pOutrow  = pBuf->pImgdata + (pData->iRow         * pBuf->iRowsize   ) +
12205                               (pData->iDeltaBlocky * pBuf->iRowsize   ) +
12206                               (pData->iCol         * pBuf->iSamplesize) +
12207                               (pData->iDeltaBlockx * pBuf->iSamplesize);
12208   iM       = 0;                        /* start at pixel 0 */
12209   iB       = 0;
12210   iS       = 0;
12211                                        /* pixel replace ? */
12212   if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)
12213   {
12214 #ifdef MNG_DECREMENT_LOOPS
12215     for (iX = pData->iRowsamples; iX > 0; iX--)
12216 #else
12217     for (iX = 0; iX < pData->iRowsamples; iX++)
12218 #endif
12219     {
12220       if (!iM)                         /* mask underflow ? */
12221       {
12222         iB = *pWorkrow;                /* get next input-byte */
12223         pWorkrow++;
12224         iM = 0xF0;
12225         iS = 4;
12226       }
12227                                        /* put the index */
12228       *pOutrow = (mng_uint8)((iB & iM) >> iS);
12229 
12230       pOutrow += pData->iColinc;       /* next pixel */
12231       iM >>=  4;
12232       iS -= 4;
12233     }
12234   }
12235   else
12236   {                                    /* pixel add ! */
12237 #ifdef MNG_DECREMENT_LOOPS
12238     for (iX = pData->iRowsamples; iX > 0; iX--)
12239 #else
12240     for (iX = 0; iX < pData->iRowsamples; iX++)
12241 #endif
12242     {
12243       if (!iM)                         /* mask underflow ? */
12244       {
12245         iB = *pWorkrow;                /* get next input-byte */
12246         pWorkrow++;
12247         iM = 0xF0;
12248         iS = 4;
12249       }
12250                                        /* calculate the index */
12251       *pOutrow = (mng_uint8)((*pOutrow + ((iB & iM) >> iS)) & 0x0F);
12252 
12253       pOutrow += pData->iColinc;       /* next pixel */
12254       iM >>=  4;
12255       iS -= 4;
12256     }
12257   }
12258 
12259 #ifdef MNG_SUPPORT_TRACE
12260   MNG_TRACE (pData, MNG_FN_DELTA_IDX4, MNG_LC_END);
12261 #endif
12262 
12263   return mng_store_idx4 (pData);
12264 }
12265 #endif
12266 
12267 /* ************************************************************************** */
12268 
mng_delta_idx8(mng_datap pData)12269 mng_retcode mng_delta_idx8 (mng_datap pData)
12270 {
12271   mng_imagedatap pBuf = ((mng_imagep)pData->pDeltaImage)->pImgbuf;
12272   mng_uint8p     pWorkrow;
12273   mng_uint8p     pOutrow;
12274   mng_int32      iX;
12275 
12276 #ifdef MNG_SUPPORT_TRACE
12277   MNG_TRACE (pData, MNG_FN_DELTA_IDX8, MNG_LC_START);
12278 #endif
12279                                        /* temporary work pointers */
12280   pWorkrow = pData->pWorkrow + pData->iPixelofs;
12281   pOutrow  = pBuf->pImgdata + (pData->iRow         * pBuf->iRowsize   ) +
12282                               (pData->iDeltaBlocky * pBuf->iRowsize   ) +
12283                               (pData->iCol         * pBuf->iSamplesize) +
12284                               (pData->iDeltaBlockx * pBuf->iSamplesize);
12285                                        /* pixel replace ? */
12286   if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)
12287   {
12288 #ifdef MNG_DECREMENT_LOOPS
12289     for (iX = pData->iRowsamples; iX > 0; iX--)
12290 #else
12291     for (iX = 0; iX < pData->iRowsamples; iX++)
12292 #endif
12293     {
12294       *pOutrow = *pWorkrow;            /* put in object buffer */
12295 
12296       pOutrow += pData->iColinc;       /* next pixel */
12297       pWorkrow++;
12298     }
12299   }
12300   else
12301   {                                    /* pixel add ! */
12302 #ifdef MNG_DECREMENT_LOOPS
12303     for (iX = pData->iRowsamples; iX > 0; iX--)
12304 #else
12305     for (iX = 0; iX < pData->iRowsamples; iX++)
12306 #endif
12307     {                                  /* add to object buffer */
12308       *pOutrow = (mng_uint8)(*pOutrow + *pWorkrow);
12309 
12310       pOutrow += pData->iColinc;       /* next pixel */
12311       pWorkrow++;
12312     }
12313   }
12314 
12315 #ifdef MNG_SUPPORT_TRACE
12316   MNG_TRACE (pData, MNG_FN_DELTA_IDX8, MNG_LC_END);
12317 #endif
12318 
12319   return mng_store_idx8 (pData);
12320 }
12321 
12322 /* ************************************************************************** */
12323 
mng_delta_ga8(mng_datap pData)12324 mng_retcode mng_delta_ga8 (mng_datap pData)
12325 {
12326   mng_imagedatap pBuf = ((mng_imagep)pData->pDeltaImage)->pImgbuf;
12327   mng_uint8p     pWorkrow;
12328   mng_uint8p     pOutrow;
12329   mng_int32      iX;
12330 
12331 #ifdef MNG_SUPPORT_TRACE
12332   MNG_TRACE (pData, MNG_FN_DELTA_GA8, MNG_LC_START);
12333 #endif
12334                                        /* temporary work pointers */
12335   pWorkrow = pData->pWorkrow + pData->iPixelofs;
12336   pOutrow  = pBuf->pImgdata + (pData->iRow         * pBuf->iRowsize   ) +
12337                               (pData->iDeltaBlocky * pBuf->iRowsize   ) +
12338                               (pData->iCol         * pBuf->iSamplesize) +
12339                               (pData->iDeltaBlockx * pBuf->iSamplesize);
12340                                        /* pixel replace ? */
12341   if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)
12342   {
12343 #ifdef MNG_DECREMENT_LOOPS
12344     for (iX = pData->iRowsamples; iX > 0; iX--)
12345 #else
12346     for (iX = 0; iX < pData->iRowsamples; iX++)
12347 #endif
12348     {
12349       *pOutrow     = *pWorkrow;        /* put in object buffer */
12350       *(pOutrow+1) = *(pWorkrow+1);
12351                                        /* next pixel */
12352       pOutrow  += (pData->iColinc << 1);
12353       pWorkrow += 2;
12354     }
12355   }
12356   else
12357   {                                    /* pixel add ! */
12358 #ifdef MNG_DECREMENT_LOOPS
12359     for (iX = pData->iRowsamples; iX > 0; iX--)
12360 #else
12361     for (iX = 0; iX < pData->iRowsamples; iX++)
12362 #endif
12363     {                                  /* add to object buffer */
12364       *pOutrow     = (mng_uint8)(*pOutrow     + *pWorkrow    );
12365       *(pOutrow+1) = (mng_uint8)(*(pOutrow+1) + *(pWorkrow+1));
12366                                        /* next pixel */
12367       pOutrow  += (pData->iColinc << 1);
12368       pWorkrow += 2;
12369     }
12370   }
12371 
12372 #ifdef MNG_SUPPORT_TRACE
12373   MNG_TRACE (pData, MNG_FN_DELTA_GA8, MNG_LC_END);
12374 #endif
12375 
12376   return mng_store_ga8 (pData);
12377 }
12378 
12379 /* ************************************************************************** */
12380 
12381 #ifndef MNG_NO_16BIT_SUPPORT
mng_delta_ga16(mng_datap pData)12382 mng_retcode mng_delta_ga16 (mng_datap pData)
12383 {
12384   mng_imagedatap pBuf = ((mng_imagep)pData->pDeltaImage)->pImgbuf;
12385   mng_uint8p     pWorkrow;
12386   mng_uint8p     pOutrow;
12387   mng_int32      iX;
12388 
12389 #ifdef MNG_SUPPORT_TRACE
12390   MNG_TRACE (pData, MNG_FN_DELTA_GA16, MNG_LC_START);
12391 #endif
12392                                        /* temporary work pointers */
12393   pWorkrow = pData->pWorkrow + pData->iPixelofs;
12394   pOutrow  = pBuf->pImgdata + (pData->iRow         * pBuf->iRowsize   ) +
12395                               (pData->iDeltaBlocky * pBuf->iRowsize   ) +
12396                               (pData->iCol         * pBuf->iSamplesize) +
12397                               (pData->iDeltaBlockx * pBuf->iSamplesize);
12398                                        /* pixel replace ? */
12399   if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)
12400   {
12401 #ifdef MNG_DECREMENT_LOOPS
12402     for (iX = pData->iRowsamples; iX > 0; iX--)
12403 #else
12404     for (iX = 0; iX < pData->iRowsamples; iX++)
12405 #endif
12406     {
12407       *pOutrow     = *pWorkrow;        /* put in object buffer */
12408       *(pOutrow+1) = *(pWorkrow+1);
12409       *(pOutrow+2) = *(pWorkrow+2);
12410       *(pOutrow+3) = *(pWorkrow+3);
12411                                        /* next pixel */
12412       pOutrow  += (pData->iColinc << 2);
12413       pWorkrow += 4;
12414     }
12415   }
12416   else
12417   {                                    /* pixel add ! */
12418 #ifdef MNG_DECREMENT_LOOPS
12419     for (iX = pData->iRowsamples; iX > 0; iX--)
12420 #else
12421     for (iX = 0; iX < pData->iRowsamples; iX++)
12422 #endif
12423     {                                  /* add to object buffer */
12424       mng_put_uint16 (pOutrow,   (mng_uint16)(mng_get_uint16 (pOutrow   ) +
12425                                               mng_get_uint16 (pWorkrow  )   ));
12426       mng_put_uint16 (pOutrow+2, (mng_uint16)(mng_get_uint16 (pOutrow+2 ) +
12427                                               mng_get_uint16 (pWorkrow+2)   ));
12428                                        /* next pixel */
12429       pOutrow  += (pData->iColinc << 2);
12430       pWorkrow += 4;
12431     }
12432   }
12433 
12434 #ifdef MNG_SUPPORT_TRACE
12435   MNG_TRACE (pData, MNG_FN_DELTA_GA16, MNG_LC_END);
12436 #endif
12437 
12438   return mng_store_ga16 (pData);
12439 }
12440 #endif
12441 
12442 /* ************************************************************************** */
12443 
mng_delta_rgba8(mng_datap pData)12444 mng_retcode mng_delta_rgba8 (mng_datap pData)
12445 {
12446   mng_imagedatap pBuf = ((mng_imagep)pData->pDeltaImage)->pImgbuf;
12447   mng_uint8p     pWorkrow;
12448   mng_uint8p     pOutrow;
12449   mng_int32      iX;
12450 
12451 #ifdef MNG_SUPPORT_TRACE
12452   MNG_TRACE (pData, MNG_FN_DELTA_RGBA8, MNG_LC_START);
12453 #endif
12454                                        /* temporary work pointers */
12455   pWorkrow = pData->pWorkrow + pData->iPixelofs;
12456   pOutrow  = pBuf->pImgdata + (pData->iRow         * pBuf->iRowsize   ) +
12457                               (pData->iDeltaBlocky * pBuf->iRowsize   ) +
12458                               (pData->iCol         * pBuf->iSamplesize) +
12459                               (pData->iDeltaBlockx * pBuf->iSamplesize);
12460                                        /* pixel replace ? */
12461   if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)
12462   {
12463 #ifdef MNG_DECREMENT_LOOPS
12464     for (iX = pData->iRowsamples; iX > 0; iX--)
12465 #else
12466     for (iX = 0; iX < pData->iRowsamples; iX++)
12467 #endif
12468     {
12469       *pOutrow     = *pWorkrow;        /* put in object buffer */
12470       *(pOutrow+1) = *(pWorkrow+1);
12471       *(pOutrow+2) = *(pWorkrow+2);
12472       *(pOutrow+3) = *(pWorkrow+3);
12473                                        /* next pixel */
12474       pOutrow  += (pData->iColinc << 2);
12475       pWorkrow += 4;
12476     }
12477   }
12478   else
12479   {                                    /* pixel add ! */
12480 #ifdef MNG_DECREMENT_LOOPS
12481     for (iX = pData->iRowsamples; iX > 0; iX--)
12482 #else
12483     for (iX = 0; iX < pData->iRowsamples; iX++)
12484 #endif
12485     {                                  /* add to object buffer */
12486       *pOutrow     = (mng_uint8)(*pOutrow     + *pWorkrow    );
12487       *(pOutrow+1) = (mng_uint8)(*(pOutrow+1) + *(pWorkrow+1));
12488       *(pOutrow+2) = (mng_uint8)(*(pOutrow+2) + *(pWorkrow+2));
12489       *(pOutrow+3) = (mng_uint8)(*(pOutrow+3) + *(pWorkrow+3));
12490                                        /* next pixel */
12491       pOutrow  += (pData->iColinc << 2);
12492       pWorkrow += 4;
12493     }
12494   }
12495 
12496 #ifdef MNG_SUPPORT_TRACE
12497   MNG_TRACE (pData, MNG_FN_DELTA_RGBA8, MNG_LC_END);
12498 #endif
12499 
12500   return mng_store_rgba8 (pData);
12501 }
12502 
12503 /* ************************************************************************** */
12504 
12505 #ifndef MNG_NO_16BIT_SUPPORT
mng_delta_rgba16(mng_datap pData)12506 mng_retcode mng_delta_rgba16 (mng_datap pData)
12507 {
12508   mng_imagedatap pBuf = ((mng_imagep)pData->pDeltaImage)->pImgbuf;
12509   mng_uint8p     pWorkrow;
12510   mng_uint8p     pOutrow;
12511   mng_int32      iX;
12512 
12513 #ifdef MNG_SUPPORT_TRACE
12514   MNG_TRACE (pData, MNG_FN_DELTA_RGBA16, MNG_LC_START);
12515 #endif
12516                                        /* temporary work pointers */
12517   pWorkrow = pData->pWorkrow + pData->iPixelofs;
12518   pOutrow  = pBuf->pImgdata + (pData->iRow         * pBuf->iRowsize   ) +
12519                               (pData->iDeltaBlocky * pBuf->iRowsize   ) +
12520                               (pData->iCol         * pBuf->iSamplesize) +
12521                               (pData->iDeltaBlockx * pBuf->iSamplesize);
12522                                        /* pixel replace ? */
12523   if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)
12524   {
12525 #ifdef MNG_DECREMENT_LOOPS
12526     for (iX = pData->iRowsamples; iX > 0; iX--)
12527 #else
12528     for (iX = 0; iX < pData->iRowsamples; iX++)
12529 #endif
12530     {
12531       MNG_COPY (pOutrow, pWorkrow, 8); /* put in object buffer */
12532                                        /* next pixel */
12533       pOutrow  += (pData->iColinc << 3);
12534       pWorkrow += 8;
12535     }
12536   }
12537   else
12538   {                                    /* pixel add ! */
12539 #ifdef MNG_DECREMENT_LOOPS
12540     for (iX = pData->iRowsamples; iX > 0; iX--)
12541 #else
12542     for (iX = 0; iX < pData->iRowsamples; iX++)
12543 #endif
12544     {                                  /* add to object buffer */
12545       mng_put_uint16 (pOutrow,   (mng_uint16)(mng_get_uint16 (pOutrow   ) +
12546                                               mng_get_uint16 (pWorkrow  )   ));
12547       mng_put_uint16 (pOutrow+2, (mng_uint16)(mng_get_uint16 (pOutrow+2 ) +
12548                                               mng_get_uint16 (pWorkrow+2)   ));
12549       mng_put_uint16 (pOutrow+4, (mng_uint16)(mng_get_uint16 (pOutrow+4 ) +
12550                                               mng_get_uint16 (pWorkrow+4)   ));
12551       mng_put_uint16 (pOutrow+6, (mng_uint16)(mng_get_uint16 (pOutrow+6 ) +
12552                                               mng_get_uint16 (pWorkrow+6)   ));
12553                                        /* next pixel */
12554       pOutrow  += (pData->iColinc << 3);
12555       pWorkrow += 8;
12556     }
12557   }
12558 
12559 #ifdef MNG_SUPPORT_TRACE
12560   MNG_TRACE (pData, MNG_FN_DELTA_RGBA16, MNG_LC_END);
12561 #endif
12562 
12563   return mng_store_rgba16 (pData);
12564 }
12565 #endif
12566 
12567 /* ************************************************************************** */
12568 /* *                                                                        * */
12569 /* * Delta-image row routines - apply the source row onto the target        * */
12570 /* *                                                                        * */
12571 /* ************************************************************************** */
12572 
12573 #ifndef MNG_NO_1_2_4BIT_SUPPORT
mng_delta_g1_g1(mng_datap pData)12574 mng_retcode mng_delta_g1_g1 (mng_datap pData)
12575 {
12576   mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
12577   mng_uint8p     pWorkrow;
12578   mng_uint8p     pOutrow;
12579   mng_int32      iX;
12580 
12581 #ifdef MNG_SUPPORT_TRACE
12582   MNG_TRACE (pData, MNG_FN_DELTA_G1_G1, MNG_LC_START);
12583 #endif
12584 
12585   pWorkrow = pData->pRGBArow;
12586   pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
12587                               (pData->iCol * pBuf->iSamplesize);
12588 
12589   if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE          ) ||
12590       (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)    )
12591   {
12592     MNG_COPY (pOutrow, pWorkrow, pData->iRowsamples);
12593   }
12594   else
12595   if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD)
12596   {
12597 #ifdef MNG_DECREMENT_LOOPS
12598     for (iX = pData->iRowsamples; iX > 0; iX--)
12599 #else
12600     for (iX = 0; iX < pData->iRowsamples; iX++)
12601 #endif
12602     {
12603       *pOutrow = (mng_uint8)(((mng_uint16)*pOutrow +
12604                               (mng_uint16)*pWorkrow) & 0x01);
12605 
12606       pOutrow++;
12607       pWorkrow++;
12608     }
12609   }
12610 
12611 #ifdef MNG_SUPPORT_TRACE
12612   MNG_TRACE (pData, MNG_FN_DELTA_G1_G1, MNG_LC_END);
12613 #endif
12614 
12615   return MNG_NOERROR;
12616 }
12617 
12618 /* ************************************************************************** */
12619 
mng_delta_g2_g2(mng_datap pData)12620 mng_retcode mng_delta_g2_g2 (mng_datap pData)
12621 {
12622   mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
12623   mng_uint8p     pWorkrow;
12624   mng_uint8p     pOutrow;
12625   mng_int32      iX;
12626 
12627 #ifdef MNG_SUPPORT_TRACE
12628   MNG_TRACE (pData, MNG_FN_DELTA_G2_G2, MNG_LC_START);
12629 #endif
12630 
12631   pWorkrow = pData->pRGBArow;
12632   pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
12633                               (pData->iCol * pBuf->iSamplesize);
12634 
12635   if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE          ) ||
12636       (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)    )
12637   {
12638     MNG_COPY (pOutrow, pWorkrow, pData->iRowsamples);
12639   }
12640   else
12641   if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD)
12642   {
12643 #ifdef MNG_DECREMENT_LOOPS
12644     for (iX = pData->iRowsamples; iX > 0; iX--)
12645 #else
12646     for (iX = 0; iX < pData->iRowsamples; iX++)
12647 #endif
12648     {
12649       *pOutrow = (mng_uint8)(((mng_uint16)*pOutrow +
12650                               (mng_uint16)*pWorkrow) & 0x03);
12651 
12652       pOutrow++;
12653       pWorkrow++;
12654     }
12655   }
12656 
12657 #ifdef MNG_SUPPORT_TRACE
12658   MNG_TRACE (pData, MNG_FN_DELTA_G2_G2, MNG_LC_END);
12659 #endif
12660 
12661   return MNG_NOERROR;
12662 }
12663 
12664 /* ************************************************************************** */
12665 
mng_delta_g4_g4(mng_datap pData)12666 mng_retcode mng_delta_g4_g4 (mng_datap pData)
12667 {
12668   mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
12669   mng_uint8p     pWorkrow;
12670   mng_uint8p     pOutrow;
12671   mng_int32      iX;
12672 
12673 #ifdef MNG_SUPPORT_TRACE
12674   MNG_TRACE (pData, MNG_FN_DELTA_G4_G4, MNG_LC_START);
12675 #endif
12676 
12677   pWorkrow = pData->pRGBArow;
12678   pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
12679                               (pData->iCol * pBuf->iSamplesize);
12680 
12681   if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE          ) ||
12682       (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)    )
12683   {
12684     MNG_COPY (pOutrow, pWorkrow, pData->iRowsamples);
12685   }
12686   else
12687   if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD)
12688   {
12689 #ifdef MNG_DECREMENT_LOOPS
12690     for (iX = pData->iRowsamples; iX > 0; iX--)
12691 #else
12692     for (iX = 0; iX < pData->iRowsamples; iX++)
12693 #endif
12694     {
12695       *pOutrow = (mng_uint8)(((mng_uint16)*pOutrow +
12696                               (mng_uint16)*pWorkrow) & 0x0F);
12697 
12698       pOutrow++;
12699       pWorkrow++;
12700     }
12701   }
12702 
12703 #ifdef MNG_SUPPORT_TRACE
12704   MNG_TRACE (pData, MNG_FN_DELTA_G4_G4, MNG_LC_END);
12705 #endif
12706 
12707   return MNG_NOERROR;
12708 }
12709 #endif
12710 
12711 /* ************************************************************************** */
12712 
mng_delta_g8_g8(mng_datap pData)12713 mng_retcode mng_delta_g8_g8 (mng_datap pData)
12714 {
12715   mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
12716   mng_uint8p     pWorkrow;
12717   mng_uint8p     pOutrow;
12718   mng_int32      iX;
12719 
12720 #ifdef MNG_SUPPORT_TRACE
12721   MNG_TRACE (pData, MNG_FN_DELTA_G8_G8, MNG_LC_START);
12722 #endif
12723 
12724   pWorkrow = pData->pRGBArow;
12725   pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
12726                               (pData->iCol * pBuf->iSamplesize);
12727 
12728   if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE          ) ||
12729       (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)    )
12730   {
12731     MNG_COPY (pOutrow, pWorkrow, pData->iRowsamples);
12732   }
12733   else
12734   if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD)
12735   {
12736 #ifdef MNG_DECREMENT_LOOPS
12737     for (iX = pData->iRowsamples; iX > 0; iX--)
12738 #else
12739     for (iX = 0; iX < pData->iRowsamples; iX++)
12740 #endif
12741     {
12742       *pOutrow = (mng_uint8)(((mng_uint16)*pOutrow +
12743                               (mng_uint16)*pWorkrow) & 0xFF);
12744 
12745       pOutrow++;
12746       pWorkrow++;
12747     }
12748   }
12749 
12750 #ifdef MNG_SUPPORT_TRACE
12751   MNG_TRACE (pData, MNG_FN_DELTA_G8_G8, MNG_LC_END);
12752 #endif
12753 
12754   return MNG_NOERROR;
12755 }
12756 
12757 /* ************************************************************************** */
12758 
12759 #ifndef MNG_NO_16BIT_SUPPORT
mng_delta_g16_g16(mng_datap pData)12760 mng_retcode mng_delta_g16_g16 (mng_datap pData)
12761 {
12762   mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
12763   mng_uint8p     pWorkrow;
12764   mng_uint8p     pOutrow;
12765   mng_int32      iX;
12766 
12767 #ifdef MNG_SUPPORT_TRACE
12768   MNG_TRACE (pData, MNG_FN_DELTA_G16_G16, MNG_LC_START);
12769 #endif
12770 
12771   pWorkrow = pData->pRGBArow;
12772   pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
12773                               (pData->iCol * pBuf->iSamplesize);
12774 
12775   if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE          ) ||
12776       (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)    )
12777   {
12778     MNG_COPY (pOutrow, pWorkrow, (pData->iRowsamples << 1));
12779   }
12780   else
12781   if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD)
12782   {
12783 #ifdef MNG_DECREMENT_LOOPS
12784     for (iX = pData->iRowsamples; iX > 0; iX--)
12785 #else
12786     for (iX = 0; iX < pData->iRowsamples; iX++)
12787 #endif
12788     {
12789       mng_put_uint16 (pOutrow, (mng_uint16)((mng_get_uint16 (pOutrow) +
12790                                              mng_get_uint16 (pWorkrow)) & 0xFFFF));
12791 
12792       pOutrow  += 2;
12793       pWorkrow += 2;
12794     }
12795   }
12796 
12797 #ifdef MNG_SUPPORT_TRACE
12798   MNG_TRACE (pData, MNG_FN_DELTA_G16_G16, MNG_LC_END);
12799 #endif
12800 
12801   return MNG_NOERROR;
12802 }
12803 #endif
12804 #endif /* MNG_NO_DELTA_PNG */
12805 
12806 /* ************************************************************************** */
12807 
mng_delta_rgb8_rgb8(mng_datap pData)12808 mng_retcode mng_delta_rgb8_rgb8 (mng_datap pData)
12809 {
12810   mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
12811   mng_uint8p     pWorkrow;
12812   mng_uint8p     pOutrow;
12813   mng_int32      iX;
12814 
12815 #ifdef MNG_SUPPORT_TRACE
12816   MNG_TRACE (pData, MNG_FN_DELTA_RGB8_RGB8, MNG_LC_START);
12817 #endif
12818 
12819   pWorkrow = pData->pRGBArow;
12820   pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
12821                               (pData->iCol * pBuf->iSamplesize);
12822 
12823   if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE          ) ||
12824       (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)    )
12825   {
12826     MNG_COPY (pOutrow, pWorkrow, pData->iRowsamples * 3);
12827   }
12828   else
12829   if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD)
12830   {
12831 #ifdef MNG_DECREMENT_LOOPS
12832     for (iX = pData->iRowsamples*3; iX > 0; iX--)
12833 #else
12834     for (iX = 0; iX < (pData->iRowsamples * 3); iX++)
12835 #endif
12836     {
12837       *pOutrow = (mng_uint8)(((mng_uint16)*pOutrow +
12838                               (mng_uint16)*pWorkrow) & 0xFF);
12839 
12840       pOutrow++;
12841       pWorkrow++;
12842     }
12843   }
12844 
12845 #ifdef MNG_SUPPORT_TRACE
12846   MNG_TRACE (pData, MNG_FN_DELTA_RGB8_RGB8, MNG_LC_END);
12847 #endif
12848 
12849   return MNG_NOERROR;
12850 }
12851 
12852 /* ************************************************************************** */
12853 
12854 #ifndef MNG_NO_16BIT_SUPPORT
mng_delta_rgb16_rgb16(mng_datap pData)12855 mng_retcode mng_delta_rgb16_rgb16 (mng_datap pData)
12856 {
12857   mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
12858   mng_uint8p     pWorkrow;
12859   mng_uint8p     pOutrow;
12860   mng_int32      iX;
12861 
12862 #ifdef MNG_SUPPORT_TRACE
12863   MNG_TRACE (pData, MNG_FN_DELTA_RGB16_RGB16, MNG_LC_START);
12864 #endif
12865 
12866   pWorkrow = pData->pRGBArow;
12867   pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
12868                               (pData->iCol * pBuf->iSamplesize);
12869 
12870   if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE          ) ||
12871       (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)    )
12872   {
12873     MNG_COPY (pOutrow, pWorkrow, (pData->iRowsamples * 6));
12874   }
12875   else
12876   if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD)
12877   {
12878 #ifdef MNG_DECREMENT_LOOPS
12879     for (iX = pData->iRowsamples; iX > 0; iX--)
12880 #else
12881     for (iX = 0; iX < pData->iRowsamples; iX++)
12882 #endif
12883     {
12884       mng_put_uint16 (pOutrow,   (mng_uint16)((mng_get_uint16 (pOutrow  ) +
12885                                                mng_get_uint16 (pWorkrow  )) & 0xFFFF));
12886       mng_put_uint16 (pOutrow+2, (mng_uint16)((mng_get_uint16 (pOutrow+2) +
12887                                                mng_get_uint16 (pWorkrow+2)) & 0xFFFF));
12888       mng_put_uint16 (pOutrow+4, (mng_uint16)((mng_get_uint16 (pOutrow+4) +
12889                                                mng_get_uint16 (pWorkrow+4)) & 0xFFFF));
12890 
12891       pOutrow  += 6;
12892       pWorkrow += 6;
12893     }
12894   }
12895 
12896 #ifdef MNG_SUPPORT_TRACE
12897   MNG_TRACE (pData, MNG_FN_DELTA_RGB16_RGB16, MNG_LC_END);
12898 #endif
12899 
12900   return MNG_NOERROR;
12901 }
12902 #endif
12903 
12904 /* ************************************************************************** */
12905 
12906 #ifndef MNG_NO_DELTA_PNG
mng_delta_ga8_ga8(mng_datap pData)12907 mng_retcode mng_delta_ga8_ga8 (mng_datap pData)
12908 {
12909   mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
12910   mng_uint8p     pWorkrow;
12911   mng_uint8p     pOutrow;
12912   mng_int32      iX;
12913 
12914 #ifdef MNG_SUPPORT_TRACE
12915   MNG_TRACE (pData, MNG_FN_DELTA_GA8_GA8, MNG_LC_START);
12916 #endif
12917 
12918   pWorkrow = pData->pRGBArow;
12919   pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
12920                               (pData->iCol * pBuf->iSamplesize);
12921 
12922   if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE          ) ||
12923       (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)    )
12924   {
12925     MNG_COPY (pOutrow, pWorkrow, pData->iRowsamples << 1);
12926   }
12927   else
12928   if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD)
12929   {
12930 #ifdef MNG_DECREMENT_LOOPS
12931     for (iX = (pData->iRowsamples<<1); iX > 0; iX--)
12932 #else
12933     for (iX = 0; iX < (pData->iRowsamples << 1); iX++)
12934 #endif
12935     {
12936       *pOutrow = (mng_uint8)(((mng_uint16)*pOutrow +
12937                               (mng_uint16)*pWorkrow) & 0xFF);
12938 
12939       pOutrow++;
12940       pWorkrow++;
12941     }
12942   }
12943 
12944 #ifdef MNG_SUPPORT_TRACE
12945   MNG_TRACE (pData, MNG_FN_DELTA_GA8_GA8, MNG_LC_END);
12946 #endif
12947 
12948   return MNG_NOERROR;
12949 }
12950 
12951 /* ************************************************************************** */
12952 
mng_delta_ga8_g8(mng_datap pData)12953 mng_retcode mng_delta_ga8_g8 (mng_datap pData)
12954 {
12955   mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
12956   mng_uint8p     pWorkrow;
12957   mng_uint8p     pOutrow;
12958   mng_int32      iX;
12959 
12960 #ifdef MNG_SUPPORT_TRACE
12961   MNG_TRACE (pData, MNG_FN_DELTA_GA8_G8, MNG_LC_START);
12962 #endif
12963 
12964   pWorkrow = pData->pRGBArow;
12965   pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
12966                               (pData->iCol * pBuf->iSamplesize);
12967 
12968   if (pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORREPLACE)
12969   {
12970 #ifdef MNG_DECREMENT_LOOPS
12971     for (iX = pData->iRowsamples; iX > 0; iX--)
12972 #else
12973     for (iX = 0; iX < pData->iRowsamples; iX++)
12974 #endif
12975     {
12976       *pOutrow = *pWorkrow;
12977 
12978       pOutrow += 2;
12979       pWorkrow++;
12980     }
12981   }
12982   else
12983   if (pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORADD)
12984   {
12985 #ifdef MNG_DECREMENT_LOOPS
12986     for (iX = pData->iRowsamples; iX > 0; iX--)
12987 #else
12988     for (iX = 0; iX < pData->iRowsamples; iX++)
12989 #endif
12990     {
12991       *pOutrow = (mng_uint8)(((mng_uint16)*pOutrow +
12992                               (mng_uint16)*pWorkrow) & 0xFF);
12993 
12994       pOutrow += 2;
12995       pWorkrow++;
12996     }
12997   }
12998 
12999 #ifdef MNG_SUPPORT_TRACE
13000   MNG_TRACE (pData, MNG_FN_DELTA_GA8_G8, MNG_LC_END);
13001 #endif
13002 
13003   return MNG_NOERROR;
13004 }
13005 
13006 /* ************************************************************************** */
13007 
mng_delta_ga8_a8(mng_datap pData)13008 mng_retcode mng_delta_ga8_a8 (mng_datap pData)
13009 {
13010   mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
13011   mng_uint8p     pWorkrow;
13012   mng_uint8p     pOutrow;
13013   mng_int32      iX;
13014 
13015 #ifdef MNG_SUPPORT_TRACE
13016   MNG_TRACE (pData, MNG_FN_DELTA_GA8_A8, MNG_LC_START);
13017 #endif
13018 
13019   pWorkrow = pData->pRGBArow;
13020   pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
13021                               (pData->iCol * pBuf->iSamplesize) + 1;
13022 
13023   if (pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAREPLACE)
13024   {
13025 #ifdef MNG_DECREMENT_LOOPS
13026     for (iX = pData->iRowsamples; iX > 0; iX--)
13027 #else
13028     for (iX = 0; iX < pData->iRowsamples; iX++)
13029 #endif
13030     {
13031       *pOutrow = *pWorkrow;
13032 
13033       pOutrow += 2;
13034       pWorkrow++;
13035     }
13036   }
13037   else
13038   if (pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAADD)
13039   {
13040 #ifdef MNG_DECREMENT_LOOPS
13041     for (iX = pData->iRowsamples; iX > 0; iX--)
13042 #else
13043     for (iX = 0; iX < pData->iRowsamples; iX++)
13044 #endif
13045     {
13046       *pOutrow = (mng_uint8)(((mng_uint16)*pOutrow +
13047                               (mng_uint16)*pWorkrow) & 0xFF);
13048 
13049       pOutrow += 2;
13050       pWorkrow++;
13051     }
13052   }
13053 
13054 #ifdef MNG_SUPPORT_TRACE
13055   MNG_TRACE (pData, MNG_FN_DELTA_GA8_A8, MNG_LC_END);
13056 #endif
13057 
13058   return MNG_NOERROR;
13059 }
13060 
13061 /* ************************************************************************** */
13062 
13063 #ifndef MNG_NO_16BIT_SUPPORT
mng_delta_ga16_ga16(mng_datap pData)13064 mng_retcode mng_delta_ga16_ga16 (mng_datap pData)
13065 {
13066   mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
13067   mng_uint8p     pWorkrow;
13068   mng_uint8p     pOutrow;
13069   mng_int32      iX;
13070 
13071 #ifdef MNG_SUPPORT_TRACE
13072   MNG_TRACE (pData, MNG_FN_DELTA_GA16_GA16, MNG_LC_START);
13073 #endif
13074 
13075   pWorkrow = pData->pRGBArow;
13076   pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
13077                               (pData->iCol * pBuf->iSamplesize);
13078 
13079   if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE          ) ||
13080       (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)    )
13081   {
13082     MNG_COPY (pOutrow, pWorkrow, (pData->iRowsamples << 2));
13083   }
13084   else
13085   if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD)
13086   {
13087 #ifdef MNG_DECREMENT_LOOPS
13088     for (iX = pData->iRowsamples; iX > 0; iX--)
13089 #else
13090     for (iX = 0; iX < pData->iRowsamples; iX++)
13091 #endif
13092     {
13093       mng_put_uint16 (pOutrow,   (mng_uint16)((mng_get_uint16 (pOutrow  ) +
13094                                                mng_get_uint16 (pWorkrow  )) & 0xFFFF));
13095       mng_put_uint16 (pOutrow+2, (mng_uint16)((mng_get_uint16 (pOutrow+2) +
13096                                                mng_get_uint16 (pWorkrow+2)) & 0xFFFF));
13097 
13098       pOutrow  += 4;
13099       pWorkrow += 4;
13100     }
13101   }
13102 
13103 #ifdef MNG_SUPPORT_TRACE
13104   MNG_TRACE (pData, MNG_FN_DELTA_GA16_GA16, MNG_LC_END);
13105 #endif
13106 
13107   return MNG_NOERROR;
13108 }
13109 #endif
13110 
13111 /* ************************************************************************** */
13112 
13113 #ifndef MNG_NO_16BIT_SUPPORT
mng_delta_ga16_g16(mng_datap pData)13114 mng_retcode mng_delta_ga16_g16 (mng_datap pData)
13115 {
13116   mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
13117   mng_uint8p     pWorkrow;
13118   mng_uint8p     pOutrow;
13119   mng_int32      iX;
13120 
13121 #ifdef MNG_SUPPORT_TRACE
13122   MNG_TRACE (pData, MNG_FN_DELTA_GA16_G16, MNG_LC_START);
13123 #endif
13124 
13125   pWorkrow = pData->pRGBArow;
13126   pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
13127                               (pData->iCol * pBuf->iSamplesize);
13128 
13129   if (pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORREPLACE)
13130   {
13131 #ifdef MNG_DECREMENT_LOOPS
13132     for (iX = pData->iRowsamples; iX > 0; iX--)
13133 #else
13134     for (iX = 0; iX < pData->iRowsamples; iX++)
13135 #endif
13136     {
13137       mng_put_uint16 (pOutrow, mng_get_uint16 (pWorkrow));
13138 
13139       pOutrow  += 4;
13140       pWorkrow += 2;
13141     }
13142   }
13143   else
13144   if (pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORADD)
13145   {
13146 #ifdef MNG_DECREMENT_LOOPS
13147     for (iX = pData->iRowsamples; iX > 0; iX--)
13148 #else
13149     for (iX = 0; iX < pData->iRowsamples; iX++)
13150 #endif
13151     {
13152       mng_put_uint16 (pOutrow, (mng_uint16)((mng_get_uint16 (pOutrow) +
13153                                              mng_get_uint16 (pWorkrow)) & 0xFFFF));
13154 
13155       pOutrow  += 4;
13156       pWorkrow += 2;
13157     }
13158   }
13159 
13160 #ifdef MNG_SUPPORT_TRACE
13161   MNG_TRACE (pData, MNG_FN_DELTA_GA16_G16, MNG_LC_END);
13162 #endif
13163 
13164   return MNG_NOERROR;
13165 }
13166 #endif
13167 
13168 /* ************************************************************************** */
13169 
13170 #ifndef MNG_NO_16BIT_SUPPORT
mng_delta_ga16_a16(mng_datap pData)13171 mng_retcode mng_delta_ga16_a16 (mng_datap pData)
13172 {
13173   mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
13174   mng_uint8p     pWorkrow;
13175   mng_uint8p     pOutrow;
13176   mng_int32      iX;
13177 
13178 #ifdef MNG_SUPPORT_TRACE
13179   MNG_TRACE (pData, MNG_FN_DELTA_GA16_A16, MNG_LC_START);
13180 #endif
13181 
13182   pWorkrow = pData->pRGBArow;
13183   pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
13184                               (pData->iCol * pBuf->iSamplesize);
13185 
13186   if (pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAREPLACE)
13187   {
13188 #ifdef MNG_DECREMENT_LOOPS
13189     for (iX = pData->iRowsamples; iX > 0; iX--)
13190 #else
13191     for (iX = 0; iX < pData->iRowsamples; iX++)
13192 #endif
13193     {
13194       mng_put_uint16 (pOutrow+2, mng_get_uint16 (pWorkrow));
13195 
13196       pOutrow  += 4;
13197       pWorkrow += 2;
13198     }
13199   }
13200   else
13201   if (pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAADD)
13202   {
13203 #ifdef MNG_DECREMENT_LOOPS
13204     for (iX = pData->iRowsamples; iX > 0; iX--)
13205 #else
13206     for (iX = 0; iX < pData->iRowsamples; iX++)
13207 #endif
13208     {
13209       mng_put_uint16 (pOutrow+2, (mng_uint16)((mng_get_uint16 (pOutrow+2) +
13210                                                mng_get_uint16 (pWorkrow)) & 0xFFFF));
13211 
13212       pOutrow  += 4;
13213       pWorkrow += 2;
13214     }
13215   }
13216 
13217 #ifdef MNG_SUPPORT_TRACE
13218   MNG_TRACE (pData, MNG_FN_DELTA_GA16_A16, MNG_LC_END);
13219 #endif
13220 
13221   return MNG_NOERROR;
13222 }
13223 #endif
13224 #endif /* MNG_NO_DELTA_PNG */
13225 
13226 /* ************************************************************************** */
13227 
mng_delta_rgba8_rgba8(mng_datap pData)13228 mng_retcode mng_delta_rgba8_rgba8 (mng_datap pData)
13229 {
13230   mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
13231   mng_uint8p     pWorkrow;
13232   mng_uint8p     pOutrow;
13233   mng_int32      iX;
13234 
13235 #ifdef MNG_SUPPORT_TRACE
13236   MNG_TRACE (pData, MNG_FN_DELTA_RGBA8_RGBA8, MNG_LC_START);
13237 #endif
13238 
13239   pWorkrow = pData->pRGBArow;
13240   pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
13241                               (pData->iCol * pBuf->iSamplesize);
13242 
13243   if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE          ) ||
13244       (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)    )
13245   {
13246     MNG_COPY (pOutrow, pWorkrow, pData->iRowsamples << 2);
13247   }
13248   else
13249   if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD)
13250   {
13251 #ifdef MNG_DECREMENT_LOOPS
13252     for (iX = (pData->iRowsamples << 2); iX > 0; iX--)
13253 #else
13254     for (iX = 0; iX < (pData->iRowsamples << 2); iX++)
13255 #endif
13256     {
13257       *pOutrow = (mng_uint8)(((mng_uint16)*pOutrow +
13258                               (mng_uint16)*pWorkrow) & 0xFF);
13259 
13260       pOutrow++;
13261       pWorkrow++;
13262     }
13263   }
13264 
13265 #ifdef MNG_SUPPORT_TRACE
13266   MNG_TRACE (pData, MNG_FN_DELTA_RGBA8_RGBA8, MNG_LC_END);
13267 #endif
13268 
13269   return MNG_NOERROR;
13270 }
13271 
13272 /* ************************************************************************** */
13273 
13274 #ifndef MNG_NO_DELTA_PNG
mng_delta_rgba8_rgb8(mng_datap pData)13275 mng_retcode mng_delta_rgba8_rgb8 (mng_datap pData)
13276 {
13277   mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
13278   mng_uint8p     pWorkrow;
13279   mng_uint8p     pOutrow;
13280   mng_int32      iX;
13281 
13282 #ifdef MNG_SUPPORT_TRACE
13283   MNG_TRACE (pData, MNG_FN_DELTA_RGBA8_RGB8, MNG_LC_START);
13284 #endif
13285 
13286   pWorkrow = pData->pRGBArow;
13287   pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
13288                               (pData->iCol * pBuf->iSamplesize);
13289 
13290   if (pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORREPLACE)
13291   {
13292 #ifdef MNG_DECREMENT_LOOPS
13293     for (iX = pData->iRowsamples; iX > 0; iX--)
13294 #else
13295     for (iX = 0; iX < pData->iRowsamples; iX++)
13296 #endif
13297     {
13298       *pOutrow     = *pWorkrow;
13299       *(pOutrow+1) = *(pWorkrow+1);
13300       *(pOutrow+2) = *(pWorkrow+2);
13301 
13302       pOutrow  += 4;
13303       pWorkrow += 3;
13304     }
13305   }
13306   else
13307   if (pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORADD)
13308   {
13309 #ifdef MNG_DECREMENT_LOOPS
13310     for (iX = pData->iRowsamples; iX > 0; iX--)
13311 #else
13312     for (iX = 0; iX < pData->iRowsamples; iX++)
13313 #endif
13314     {
13315       *pOutrow     = (mng_uint8)(((mng_uint16)*pOutrow     +
13316                                   (mng_uint16)*pWorkrow    ) & 0xFF);
13317       *(pOutrow+1) = (mng_uint8)(((mng_uint16)*(pOutrow+1) +
13318                                   (mng_uint16)*(pWorkrow+1)) & 0xFF);
13319       *(pOutrow+2) = (mng_uint8)(((mng_uint16)*(pOutrow+2) +
13320                                   (mng_uint16)*(pWorkrow+2)) & 0xFF);
13321 
13322       pOutrow  += 4;
13323       pWorkrow += 3;
13324     }
13325   }
13326 
13327 #ifdef MNG_SUPPORT_TRACE
13328   MNG_TRACE (pData, MNG_FN_DELTA_RGBA8_RGB8, MNG_LC_END);
13329 #endif
13330 
13331   return MNG_NOERROR;
13332 }
13333 
13334 /* ************************************************************************** */
13335 
mng_delta_rgba8_a8(mng_datap pData)13336 mng_retcode mng_delta_rgba8_a8 (mng_datap pData)
13337 {
13338   mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
13339   mng_uint8p     pWorkrow;
13340   mng_uint8p     pOutrow;
13341   mng_int32      iX;
13342 
13343 #ifdef MNG_SUPPORT_TRACE
13344   MNG_TRACE (pData, MNG_FN_DELTA_RGBA8_A8, MNG_LC_START);
13345 #endif
13346 
13347   pWorkrow = pData->pRGBArow;
13348   pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
13349                               (pData->iCol * pBuf->iSamplesize) + 3;
13350 
13351   if (pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAREPLACE)
13352   {
13353 #ifdef MNG_DECREMENT_LOOPS
13354     for (iX = pData->iRowsamples; iX > 0; iX--)
13355 #else
13356     for (iX = 0; iX < pData->iRowsamples; iX++)
13357 #endif
13358     {
13359       *pOutrow = *pWorkrow;
13360 
13361       pOutrow += 4;
13362       pWorkrow++;
13363     }
13364   }
13365   else
13366   if (pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAADD)
13367   {
13368 #ifdef MNG_DECREMENT_LOOPS
13369     for (iX = pData->iRowsamples; iX > 0; iX--)
13370 #else
13371     for (iX = 0; iX < pData->iRowsamples; iX++)
13372 #endif
13373     {
13374       *pOutrow = (mng_uint8)(((mng_uint16)*pOutrow +
13375                               (mng_uint16)*pWorkrow) & 0xFF);
13376 
13377       pOutrow += 4;
13378       pWorkrow++;
13379     }
13380   }
13381 
13382 #ifdef MNG_SUPPORT_TRACE
13383   MNG_TRACE (pData, MNG_FN_DELTA_RGBA8_A8, MNG_LC_END);
13384 #endif
13385 
13386   return MNG_NOERROR;
13387 }
13388 #endif /* MNG_NO_DELTA_PNG */
13389 
13390 /* ************************************************************************** */
13391 
13392 #ifndef MNG_NO_16BIT_SUPPORT
mng_delta_rgba16_rgba16(mng_datap pData)13393 mng_retcode mng_delta_rgba16_rgba16 (mng_datap pData)
13394 {
13395   mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
13396   mng_uint8p     pWorkrow;
13397   mng_uint8p     pOutrow;
13398   mng_int32      iX;
13399 
13400 #ifdef MNG_SUPPORT_TRACE
13401   MNG_TRACE (pData, MNG_FN_DELTA_RGBA16_RGBA16, MNG_LC_START);
13402 #endif
13403 
13404   pWorkrow = pData->pRGBArow;
13405   pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
13406                               (pData->iCol * pBuf->iSamplesize);
13407 
13408   if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE          ) ||
13409       (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)    )
13410   {
13411     MNG_COPY (pOutrow, pWorkrow, (pData->iRowsamples << 3));
13412   }
13413   else
13414   if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD)
13415   {
13416 #ifdef MNG_DECREMENT_LOOPS
13417     for (iX = pData->iRowsamples; iX > 0; iX--)
13418 #else
13419     for (iX = 0; iX < pData->iRowsamples; iX++)
13420 #endif
13421     {
13422       mng_put_uint16 (pOutrow,   (mng_uint16)((mng_get_uint16 (pOutrow  ) +
13423                                                mng_get_uint16 (pWorkrow  )) & 0xFFFF));
13424       mng_put_uint16 (pOutrow+2, (mng_uint16)((mng_get_uint16 (pOutrow+2) +
13425                                                mng_get_uint16 (pWorkrow+2)) & 0xFFFF));
13426       mng_put_uint16 (pOutrow+4, (mng_uint16)((mng_get_uint16 (pOutrow+4) +
13427                                                mng_get_uint16 (pWorkrow+4)) & 0xFFFF));
13428       mng_put_uint16 (pOutrow+6, (mng_uint16)((mng_get_uint16 (pOutrow+6) +
13429                                                mng_get_uint16 (pWorkrow+6)) & 0xFFFF));
13430 
13431       pOutrow  += 8;
13432       pWorkrow += 8;
13433     }
13434   }
13435 
13436 #ifdef MNG_SUPPORT_TRACE
13437   MNG_TRACE (pData, MNG_FN_DELTA_RGBA16_RGBA16, MNG_LC_END);
13438 #endif
13439 
13440   return MNG_NOERROR;
13441 }
13442 #endif
13443 
13444 /* ************************************************************************** */
13445 
13446 #ifndef MNG_NO_DELTA_PNG
13447 #ifndef MNG_NO_16BIT_SUPPORT
mng_delta_rgba16_rgb16(mng_datap pData)13448 mng_retcode mng_delta_rgba16_rgb16 (mng_datap pData)
13449 {
13450   mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
13451   mng_uint8p     pWorkrow;
13452   mng_uint8p     pOutrow;
13453   mng_int32      iX;
13454 
13455 #ifdef MNG_SUPPORT_TRACE
13456   MNG_TRACE (pData, MNG_FN_DELTA_RGBA16_RGB16, MNG_LC_START);
13457 #endif
13458 
13459   pWorkrow = pData->pRGBArow;
13460   pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
13461                               (pData->iCol * pBuf->iSamplesize);
13462 
13463   if (pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORREPLACE)
13464   {
13465 #ifdef MNG_DECREMENT_LOOPS
13466     for (iX = pData->iRowsamples; iX > 0; iX--)
13467 #else
13468     for (iX = 0; iX < pData->iRowsamples; iX++)
13469 #endif
13470     {
13471       mng_put_uint16 (pOutrow,   mng_get_uint16 (pWorkrow  ));
13472       mng_put_uint16 (pOutrow+2, mng_get_uint16 (pWorkrow+2));
13473       mng_put_uint16 (pOutrow+4, mng_get_uint16 (pWorkrow+4));
13474 
13475       pOutrow  += 8;
13476       pWorkrow += 6;
13477     }
13478   }
13479   else
13480   if (pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORADD)
13481   {
13482 #ifdef MNG_DECREMENT_LOOPS
13483     for (iX = pData->iRowsamples; iX > 0; iX--)
13484 #else
13485     for (iX = 0; iX < pData->iRowsamples; iX++)
13486 #endif
13487     {
13488       mng_put_uint16 (pOutrow,   (mng_uint16)((mng_get_uint16 (pOutrow  ) +
13489                                                mng_get_uint16 (pWorkrow  )) & 0xFFFF));
13490       mng_put_uint16 (pOutrow+2, (mng_uint16)((mng_get_uint16 (pOutrow+2) +
13491                                                mng_get_uint16 (pWorkrow+2)) & 0xFFFF));
13492       mng_put_uint16 (pOutrow+4, (mng_uint16)((mng_get_uint16 (pOutrow+4) +
13493                                                mng_get_uint16 (pWorkrow+4)) & 0xFFFF));
13494 
13495       pOutrow  += 8;
13496       pWorkrow += 6;
13497     }
13498   }
13499 
13500 #ifdef MNG_SUPPORT_TRACE
13501   MNG_TRACE (pData, MNG_FN_DELTA_RGBA16_RGB16, MNG_LC_END);
13502 #endif
13503 
13504   return MNG_NOERROR;
13505 }
13506 #endif
13507 
13508 /* ************************************************************************** */
13509 
13510 #ifndef MNG_NO_16BIT_SUPPORT
mng_delta_rgba16_a16(mng_datap pData)13511 mng_retcode mng_delta_rgba16_a16 (mng_datap pData)
13512 {
13513   mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
13514   mng_uint8p     pWorkrow;
13515   mng_uint8p     pOutrow;
13516   mng_int32      iX;
13517 
13518 #ifdef MNG_SUPPORT_TRACE
13519   MNG_TRACE (pData, MNG_FN_DELTA_RGBA16_A16, MNG_LC_START);
13520 #endif
13521 
13522   pWorkrow = pData->pRGBArow;
13523   pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
13524                               (pData->iCol * pBuf->iSamplesize);
13525 
13526   if (pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAREPLACE)
13527   {
13528 #ifdef MNG_DECREMENT_LOOPS
13529     for (iX = pData->iRowsamples; iX > 0; iX--)
13530 #else
13531     for (iX = 0; iX < pData->iRowsamples; iX++)
13532 #endif
13533     {
13534       mng_put_uint16 (pOutrow+6, mng_get_uint16 (pWorkrow));
13535 
13536       pOutrow  += 8;
13537       pWorkrow += 2;
13538     }
13539   }
13540   else
13541   if (pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAADD)
13542   {
13543 #ifdef MNG_DECREMENT_LOOPS
13544     for (iX = pData->iRowsamples; iX > 0; iX--)
13545 #else
13546     for (iX = 0; iX < pData->iRowsamples; iX++)
13547 #endif
13548     {
13549       mng_put_uint16 (pOutrow+6, (mng_uint16)((mng_get_uint16 (pOutrow+6) +
13550                                                mng_get_uint16 (pWorkrow)) & 0xFFFF));
13551 
13552       pOutrow  += 8;
13553       pWorkrow += 2;
13554     }
13555   }
13556 
13557 #ifdef MNG_SUPPORT_TRACE
13558   MNG_TRACE (pData, MNG_FN_DELTA_RGBA16_A16, MNG_LC_END);
13559 #endif
13560 
13561   return MNG_NOERROR;
13562 }
13563 #endif
13564 #endif /* MNG_NO_DELTA_PNG */
13565 
13566 /* ************************************************************************** */
13567 /* *                                                                        * */
13568 /* * Delta-image row routines - scale the delta to bitdepth of target       * */
13569 /* *                                                                        * */
13570 /* ************************************************************************** */
13571 
13572 #ifndef MNG_NO_DELTA_PNG
13573 #ifndef MNG_NO_1_2_4BIT_SUPPORT
mng_scale_g1_g2(mng_datap pData)13574 mng_retcode mng_scale_g1_g2 (mng_datap pData)
13575 {
13576   mng_uint8p pWorkrow = pData->pRGBArow;
13577   mng_int32  iX;
13578 
13579 #ifdef MNG_SUPPORT_TRACE
13580   MNG_TRACE (pData, MNG_FN_SCALE_G1_G2, MNG_LC_START);
13581 #endif
13582 
13583 #ifdef MNG_DECREMENT_LOOPS
13584   for (iX = pData->iRowsamples; iX > 0; iX--)
13585 #else
13586   for (iX = 0; iX < pData->iRowsamples; iX++)
13587 #endif
13588   {
13589     *pWorkrow = (mng_uint8)(*pWorkrow << 1);
13590     pWorkrow++;
13591   }
13592 
13593 #ifdef MNG_SUPPORT_TRACE
13594   MNG_TRACE (pData, MNG_FN_SCALE_G1_G2, MNG_LC_END);
13595 #endif
13596 
13597   return MNG_NOERROR;
13598 }
13599 
13600 /* ************************************************************************** */
13601 
mng_scale_g1_g4(mng_datap pData)13602 mng_retcode mng_scale_g1_g4 (mng_datap pData)
13603 {
13604   mng_uint8p pWorkrow = pData->pRGBArow;
13605   mng_int32  iX;
13606 
13607 #ifdef MNG_SUPPORT_TRACE
13608   MNG_TRACE (pData, MNG_FN_SCALE_G1_G4, MNG_LC_START);
13609 #endif
13610 
13611 #ifdef MNG_DECREMENT_LOOPS
13612   for (iX = pData->iRowsamples; iX > 0; iX--)
13613 #else
13614   for (iX = 0; iX < pData->iRowsamples; iX++)
13615 #endif
13616   {
13617     *pWorkrow = (mng_uint8)(*pWorkrow << 3);
13618     pWorkrow++;
13619   }
13620 
13621 #ifdef MNG_SUPPORT_TRACE
13622   MNG_TRACE (pData, MNG_FN_SCALE_G1_G4, MNG_LC_END);
13623 #endif
13624 
13625   return MNG_NOERROR;
13626 }
13627 
13628 /* ************************************************************************** */
13629 
mng_scale_g1_g8(mng_datap pData)13630 mng_retcode mng_scale_g1_g8 (mng_datap pData)
13631 {
13632   mng_uint8p pWorkrow = pData->pRGBArow;
13633   mng_int32  iX;
13634 
13635 #ifdef MNG_SUPPORT_TRACE
13636   MNG_TRACE (pData, MNG_FN_SCALE_G1_G8, MNG_LC_START);
13637 #endif
13638 
13639 #ifdef MNG_DECREMENT_LOOPS
13640   for (iX = pData->iRowsamples; iX > 0; iX--)
13641 #else
13642   for (iX = 0; iX < pData->iRowsamples; iX++)
13643 #endif
13644   {
13645     *pWorkrow = (mng_uint8)(*pWorkrow << 7);
13646     pWorkrow++;
13647   }
13648 
13649 #ifdef MNG_SUPPORT_TRACE
13650   MNG_TRACE (pData, MNG_FN_SCALE_G1_G8, MNG_LC_END);
13651 #endif
13652 
13653   return MNG_NOERROR;
13654 }
13655 
13656 /* ************************************************************************** */
13657 
13658 #ifndef MNG_NO_16BIT_SUPPORT
mng_scale_g1_g16(mng_datap pData)13659 mng_retcode mng_scale_g1_g16 (mng_datap pData)
13660 {
13661   mng_uint8p pWorkrow = pData->pRGBArow;
13662   mng_uint8p pOutrow  = pData->pRGBArow;
13663   mng_int32  iX;
13664 
13665 #ifdef MNG_SUPPORT_TRACE
13666   MNG_TRACE (pData, MNG_FN_SCALE_G1_G16, MNG_LC_START);
13667 #endif
13668 
13669   pWorkrow = pWorkrow + (pData->iRowsamples - 1);
13670   pOutrow  = pOutrow  + ((pData->iRowsamples - 1) << 1);
13671 /*  pWorkrow = (mng_uint8p)((mng_uint32)pWorkrow + pData->iRowsamples - 1); */
13672 /*  pOutrow  = (mng_uint8p)((mng_uint32)pOutrow  + ((pData->iRowsamples - 1) << 1)); */
13673 
13674 #ifdef MNG_DECREMENT_LOOPS
13675   for (iX = pData->iRowsamples; iX > 0; iX--)
13676 #else
13677   for (iX = 0; iX < pData->iRowsamples; iX++)
13678 #endif
13679   {
13680     *(pOutrow+1) = 0;
13681     *pOutrow     = (mng_uint8)(*pWorkrow << 7);
13682 
13683     pWorkrow--;
13684     pOutrow -= 2;
13685   }
13686 
13687 #ifdef MNG_SUPPORT_TRACE
13688   MNG_TRACE (pData, MNG_FN_SCALE_G1_G16, MNG_LC_END);
13689 #endif
13690 
13691   return MNG_NOERROR;
13692 }
13693 #endif
13694 
13695 /* ************************************************************************** */
13696 
mng_scale_g2_g4(mng_datap pData)13697 mng_retcode mng_scale_g2_g4 (mng_datap pData)
13698 {
13699   mng_uint8p pWorkrow = pData->pRGBArow;
13700   mng_int32  iX;
13701 
13702 #ifdef MNG_SUPPORT_TRACE
13703   MNG_TRACE (pData, MNG_FN_SCALE_G2_G4, MNG_LC_START);
13704 #endif
13705 
13706 #ifdef MNG_DECREMENT_LOOPS
13707   for (iX = pData->iRowsamples; iX > 0; iX--)
13708 #else
13709   for (iX = 0; iX < pData->iRowsamples; iX++)
13710 #endif
13711   {
13712     *pWorkrow = (mng_uint8)(*pWorkrow << 2);
13713     pWorkrow++;
13714   }
13715 
13716 #ifdef MNG_SUPPORT_TRACE
13717   MNG_TRACE (pData, MNG_FN_SCALE_G2_G4, MNG_LC_END);
13718 #endif
13719 
13720   return MNG_NOERROR;
13721 }
13722 
13723 /* ************************************************************************** */
13724 
mng_scale_g2_g8(mng_datap pData)13725 mng_retcode mng_scale_g2_g8 (mng_datap pData)
13726 {
13727   mng_uint8p pWorkrow = pData->pRGBArow;
13728   mng_int32  iX;
13729 
13730 #ifdef MNG_SUPPORT_TRACE
13731   MNG_TRACE (pData, MNG_FN_SCALE_G2_G8, MNG_LC_START);
13732 #endif
13733 
13734 #ifdef MNG_DECREMENT_LOOPS
13735   for (iX = pData->iRowsamples; iX > 0; iX--)
13736 #else
13737   for (iX = 0; iX < pData->iRowsamples; iX++)
13738 #endif
13739   {
13740     *pWorkrow = (mng_uint8)(*pWorkrow << 6);
13741     pWorkrow++;
13742   }
13743 
13744 #ifdef MNG_SUPPORT_TRACE
13745   MNG_TRACE (pData, MNG_FN_SCALE_G2_G8, MNG_LC_END);
13746 #endif
13747 
13748   return MNG_NOERROR;
13749 }
13750 
13751 /* ************************************************************************** */
13752 
13753 #ifndef MNG_NO_16BIT_SUPPORT
mng_scale_g2_g16(mng_datap pData)13754 mng_retcode mng_scale_g2_g16 (mng_datap pData)
13755 {
13756   mng_uint8p pWorkrow = pData->pRGBArow;
13757   mng_uint8p pOutrow  = pData->pRGBArow;
13758   mng_int32  iX;
13759 
13760 #ifdef MNG_SUPPORT_TRACE
13761   MNG_TRACE (pData, MNG_FN_SCALE_G2_G16, MNG_LC_START);
13762 #endif
13763 
13764   pWorkrow = pWorkrow + (pData->iRowsamples - 1);
13765   pOutrow  = pOutrow  + ((pData->iRowsamples - 1) << 1);
13766 /*  pWorkrow = (mng_uint8p)((mng_uint32)pWorkrow + pData->iRowsamples - 1); */
13767 /*  pOutrow  = (mng_uint8p)((mng_uint32)pOutrow  + ((pData->iRowsamples - 1) << 1)); */
13768 
13769 #ifdef MNG_DECREMENT_LOOPS
13770   for (iX = pData->iRowsamples; iX > 0; iX--)
13771 #else
13772   for (iX = 0; iX < pData->iRowsamples; iX++)
13773 #endif
13774   {
13775     *(pOutrow+1) = 0;
13776     *pOutrow     = (mng_uint8)(*pWorkrow << 6);
13777 
13778     pWorkrow--;
13779     pOutrow -= 2;
13780   }
13781 
13782 #ifdef MNG_SUPPORT_TRACE
13783   MNG_TRACE (pData, MNG_FN_SCALE_G2_G16, MNG_LC_END);
13784 #endif
13785 
13786   return MNG_NOERROR;
13787 }
13788 #endif
13789 
13790 /* ************************************************************************** */
13791 
mng_scale_g4_g8(mng_datap pData)13792 mng_retcode mng_scale_g4_g8 (mng_datap pData)
13793 {
13794   mng_uint8p pWorkrow = pData->pRGBArow;
13795   mng_int32  iX;
13796 
13797 #ifdef MNG_SUPPORT_TRACE
13798   MNG_TRACE (pData, MNG_FN_SCALE_G4_G8, MNG_LC_START);
13799 #endif
13800 
13801 #ifdef MNG_DECREMENT_LOOPS
13802   for (iX = pData->iRowsamples; iX > 0; iX--)
13803 #else
13804   for (iX = 0; iX < pData->iRowsamples; iX++)
13805 #endif
13806   {
13807     *pWorkrow = (mng_uint8)(*pWorkrow << 4);
13808     pWorkrow++;
13809   }
13810 
13811 #ifdef MNG_SUPPORT_TRACE
13812   MNG_TRACE (pData, MNG_FN_SCALE_G4_G8, MNG_LC_END);
13813 #endif
13814 
13815   return MNG_NOERROR;
13816 }
13817 
13818 /* ************************************************************************** */
13819 
13820 #ifndef MNG_NO_16BIT_SUPPORT
mng_scale_g4_g16(mng_datap pData)13821 mng_retcode mng_scale_g4_g16 (mng_datap pData)
13822 {
13823   mng_uint8p pWorkrow = pData->pRGBArow;
13824   mng_uint8p pOutrow  = pData->pRGBArow;
13825   mng_int32  iX;
13826 
13827 #ifdef MNG_SUPPORT_TRACE
13828   MNG_TRACE (pData, MNG_FN_SCALE_G4_G16, MNG_LC_START);
13829 #endif
13830 
13831   pWorkrow = pWorkrow + (pData->iRowsamples - 1);
13832   pOutrow  = pOutrow  + ((pData->iRowsamples - 1) << 1);
13833 /*  pWorkrow = (mng_uint8p)((mng_uint32)pWorkrow + pData->iRowsamples - 1); */
13834 /*  pOutrow  = (mng_uint8p)((mng_uint32)pOutrow  + ((pData->iRowsamples - 1) << 1)); */
13835 
13836 #ifdef MNG_DECREMENT_LOOPS
13837   for (iX = pData->iRowsamples; iX > 0; iX--)
13838 #else
13839   for (iX = 0; iX < pData->iRowsamples; iX++)
13840 #endif
13841   {
13842     *(pOutrow+1) = 0;
13843     *pOutrow     = (mng_uint8)(*pWorkrow << 4);
13844 
13845     pWorkrow--;
13846     pOutrow -= 2;
13847   }
13848 
13849 #ifdef MNG_SUPPORT_TRACE
13850   MNG_TRACE (pData, MNG_FN_SCALE_G4_G16, MNG_LC_END);
13851 #endif
13852 
13853   return MNG_NOERROR;
13854 }
13855 #endif
13856 #endif /* MNG_NO_1_2_4BIT_SUPPORT */
13857 
13858 /* ************************************************************************** */
13859 
13860 #ifndef MNG_NO_16BIT_SUPPORT
mng_scale_g8_g16(mng_datap pData)13861 mng_retcode mng_scale_g8_g16 (mng_datap pData)
13862 {
13863   mng_uint8p pWorkrow = pData->pRGBArow;
13864   mng_uint8p pOutrow  = pData->pRGBArow;
13865   mng_int32  iX;
13866 
13867 #ifdef MNG_SUPPORT_TRACE
13868   MNG_TRACE (pData, MNG_FN_SCALE_G8_G16, MNG_LC_START);
13869 #endif
13870 
13871   pWorkrow = pWorkrow + (pData->iRowsamples - 1);
13872   pOutrow  = pOutrow  + ((pData->iRowsamples - 1) << 1);
13873 /*  pWorkrow = (mng_uint8p)((mng_uint32)pWorkrow + pData->iRowsamples - 1); */
13874 /*  pOutrow  = (mng_uint8p)((mng_uint32)pOutrow  + ((pData->iRowsamples - 1) << 1)); */
13875 
13876 #ifdef MNG_DECREMENT_LOOPS
13877   for (iX = pData->iRowsamples; iX > 0; iX--)
13878 #else
13879   for (iX = 0; iX < pData->iRowsamples; iX++)
13880 #endif
13881   {
13882     *(pOutrow+1) = 0;
13883     *pOutrow     = *pWorkrow;
13884 
13885     pWorkrow--;
13886     pOutrow -= 2;
13887   }
13888 
13889 #ifdef MNG_SUPPORT_TRACE
13890   MNG_TRACE (pData, MNG_FN_SCALE_G8_G16, MNG_LC_END);
13891 #endif
13892 
13893   return MNG_NOERROR;
13894 }
13895 #endif
13896 
13897 /* ************************************************************************** */
13898 
13899 #ifndef MNG_NO_16BIT_SUPPORT
mng_scale_ga8_ga16(mng_datap pData)13900 mng_retcode mng_scale_ga8_ga16 (mng_datap pData)
13901 {
13902   mng_uint8p pWorkrow = pData->pRGBArow;
13903   mng_uint8p pOutrow  = pData->pRGBArow;
13904   mng_int32  iX;
13905 
13906 #ifdef MNG_SUPPORT_TRACE
13907   MNG_TRACE (pData, MNG_FN_SCALE_GA8_GA16, MNG_LC_START);
13908 #endif
13909 
13910   pWorkrow = pWorkrow + ((pData->iRowsamples - 1) << 1);
13911   pOutrow  = pOutrow  + ((pData->iRowsamples - 1) << 2);
13912 /*  pWorkrow = (mng_uint8p)((mng_uint32)pWorkrow + ((pData->iRowsamples - 1) << 1)); */
13913 /*  pOutrow  = (mng_uint8p)((mng_uint32)pOutrow  + ((pData->iRowsamples - 1) << 2)); */
13914 
13915 #ifdef MNG_DECREMENT_LOOPS
13916   for (iX = pData->iRowsamples; iX > 0; iX--)
13917 #else
13918   for (iX = 0; iX < pData->iRowsamples; iX++)
13919 #endif
13920   {
13921     *(pOutrow+3) = 0;
13922     *(pOutrow+2) = *(pWorkrow+1);
13923     *(pOutrow+1) = 0;
13924     *pOutrow     = *pWorkrow;
13925 
13926     pWorkrow -= 2;
13927     pOutrow  -= 4;
13928   }
13929 
13930 #ifdef MNG_SUPPORT_TRACE
13931   MNG_TRACE (pData, MNG_FN_SCALE_GA8_GA16, MNG_LC_END);
13932 #endif
13933 
13934   return MNG_NOERROR;
13935 }
13936 #endif
13937 
13938 /* ************************************************************************** */
13939 
13940 #ifndef MNG_NO_16BIT_SUPPORT
mng_scale_rgb8_rgb16(mng_datap pData)13941 mng_retcode mng_scale_rgb8_rgb16 (mng_datap pData)
13942 {
13943   mng_uint8p pWorkrow = pData->pRGBArow;
13944   mng_uint8p pOutrow  = pData->pRGBArow;
13945   mng_int32  iX;
13946 
13947 #ifdef MNG_SUPPORT_TRACE
13948   MNG_TRACE (pData, MNG_FN_SCALE_RGB8_RGB16, MNG_LC_START);
13949 #endif
13950 
13951   pWorkrow = pWorkrow + (3 * (pData->iRowsamples - 1));
13952   pOutrow  = pOutrow  + (6 * (pData->iRowsamples - 1));
13953 /*  pWorkrow = (mng_uint8p)((mng_uint32)pWorkrow + 3 * (pData->iRowsamples - 1)); */
13954 /*  pOutrow  = (mng_uint8p)((mng_uint32)pOutrow  + 6 * (pData->iRowsamples - 1)); */
13955 
13956 #ifdef MNG_DECREMENT_LOOPS
13957   for (iX = pData->iRowsamples; iX > 0; iX--)
13958 #else
13959   for (iX = 0; iX < pData->iRowsamples; iX++)
13960 #endif
13961   {
13962     *(pOutrow+5) = 0;
13963     *(pOutrow+4) = *(pWorkrow+2);
13964     *(pOutrow+3) = 0;
13965     *(pOutrow+2) = *(pWorkrow+1);
13966     *(pOutrow+1) = 0;
13967     *pOutrow     = *pWorkrow;
13968 
13969     pWorkrow -= 3;
13970     pOutrow  -= 6;
13971   }
13972 
13973 #ifdef MNG_SUPPORT_TRACE
13974   MNG_TRACE (pData, MNG_FN_SCALE_RGB8_RGB16, MNG_LC_END);
13975 #endif
13976 
13977   return MNG_NOERROR;
13978 }
13979 #endif
13980 
13981 /* ************************************************************************** */
13982 
13983 #ifndef MNG_NO_16BIT_SUPPORT
mng_scale_rgba8_rgba16(mng_datap pData)13984 mng_retcode mng_scale_rgba8_rgba16 (mng_datap pData)
13985 {
13986   mng_uint8p pWorkrow = pData->pRGBArow;
13987   mng_uint8p pOutrow  = pData->pRGBArow;
13988   mng_int32  iX;
13989 
13990 #ifdef MNG_SUPPORT_TRACE
13991   MNG_TRACE (pData, MNG_FN_SCALE_RGBA8_RGBA16, MNG_LC_START);
13992 #endif
13993 
13994   pWorkrow = pWorkrow + ((pData->iRowsamples - 1) << 2);
13995   pOutrow  = pOutrow  + ((pData->iRowsamples - 1) << 3);
13996 /*  pWorkrow = (mng_uint8p)((mng_uint32)pWorkrow + ((pData->iRowsamples - 1) << 2)); */
13997 /*  pOutrow  = (mng_uint8p)((mng_uint32)pOutrow  + ((pData->iRowsamples - 1) << 3)); */
13998 
13999 #ifdef MNG_DECREMENT_LOOPS
14000   for (iX = pData->iRowsamples; iX > 0; iX--)
14001 #else
14002   for (iX = 0; iX < pData->iRowsamples; iX++)
14003 #endif
14004   {
14005     *(pOutrow+7) = 0;
14006     *(pOutrow+6) = *(pWorkrow+3);
14007     *(pOutrow+5) = 0;
14008     *(pOutrow+4) = *(pWorkrow+2);
14009     *(pOutrow+3) = 0;
14010     *(pOutrow+2) = *(pWorkrow+1);
14011     *(pOutrow+1) = 0;
14012     *pOutrow     = *pWorkrow;
14013 
14014     pWorkrow -= 4;
14015     pOutrow  -= 8;
14016   }
14017 
14018 #ifdef MNG_SUPPORT_TRACE
14019   MNG_TRACE (pData, MNG_FN_SCALE_RGBA8_RGBA16, MNG_LC_END);
14020 #endif
14021 
14022   return MNG_NOERROR;
14023 }
14024 #endif
14025 
14026 /* ************************************************************************** */
14027 
14028 #ifndef MNG_NO_1_2_4BIT_SUPPORT
mng_scale_g2_g1(mng_datap pData)14029 mng_retcode mng_scale_g2_g1 (mng_datap pData)
14030 {
14031   mng_uint8p pWorkrow = pData->pRGBArow;
14032   mng_int32  iX;
14033 
14034 #ifdef MNG_SUPPORT_TRACE
14035   MNG_TRACE (pData, MNG_FN_SCALE_G2_G1, MNG_LC_START);
14036 #endif
14037 
14038 #ifdef MNG_DECREMENT_LOOPS
14039   for (iX = pData->iRowsamples; iX > 0; iX--)
14040 #else
14041   for (iX = 0; iX < pData->iRowsamples; iX++)
14042 #endif
14043   {
14044     *pWorkrow = (mng_uint8)(*pWorkrow >> 1);
14045     pWorkrow++;
14046   }
14047 
14048 #ifdef MNG_SUPPORT_TRACE
14049   MNG_TRACE (pData, MNG_FN_SCALE_G2_G1, MNG_LC_END);
14050 #endif
14051 
14052   return MNG_NOERROR;
14053 }
14054 
14055 /* ************************************************************************** */
14056 
mng_scale_g4_g1(mng_datap pData)14057 mng_retcode mng_scale_g4_g1 (mng_datap pData)
14058 {
14059   mng_uint8p pWorkrow = pData->pRGBArow;
14060   mng_int32  iX;
14061 
14062 #ifdef MNG_SUPPORT_TRACE
14063   MNG_TRACE (pData, MNG_FN_SCALE_G4_G1, MNG_LC_START);
14064 #endif
14065 
14066 #ifdef MNG_DECREMENT_LOOPS
14067   for (iX = pData->iRowsamples; iX > 0; iX--)
14068 #else
14069   for (iX = 0; iX < pData->iRowsamples; iX++)
14070 #endif
14071   {
14072     *pWorkrow = (mng_uint8)(*pWorkrow >> 3);
14073     pWorkrow++;
14074   }
14075 
14076 #ifdef MNG_SUPPORT_TRACE
14077   MNG_TRACE (pData, MNG_FN_SCALE_G4_G1, MNG_LC_END);
14078 #endif
14079 
14080   return MNG_NOERROR;
14081 }
14082 
14083 /* ************************************************************************** */
14084 
mng_scale_g8_g1(mng_datap pData)14085 mng_retcode mng_scale_g8_g1 (mng_datap pData)
14086 {
14087   mng_uint8p pWorkrow = pData->pRGBArow;
14088   mng_int32  iX;
14089 
14090 #ifdef MNG_SUPPORT_TRACE
14091   MNG_TRACE (pData, MNG_FN_SCALE_G8_G1, MNG_LC_START);
14092 #endif
14093 
14094 #ifdef MNG_DECREMENT_LOOPS
14095   for (iX = pData->iRowsamples; iX > 0; iX--)
14096 #else
14097   for (iX = 0; iX < pData->iRowsamples; iX++)
14098 #endif
14099   {
14100     *pWorkrow = (mng_uint8)(*pWorkrow >> 7);
14101     pWorkrow++;
14102   }
14103 
14104 #ifdef MNG_SUPPORT_TRACE
14105   MNG_TRACE (pData, MNG_FN_SCALE_G8_G1, MNG_LC_END);
14106 #endif
14107 
14108   return MNG_NOERROR;
14109 }
14110 
14111 /* ************************************************************************** */
14112 
14113 #ifndef MNG_NO_16BIT_SUPPORT
mng_scale_g16_g1(mng_datap pData)14114 mng_retcode mng_scale_g16_g1 (mng_datap pData)
14115 {
14116   mng_uint8p pWorkrow = pData->pRGBArow;
14117   mng_uint8p pOutrow  = pData->pRGBArow;
14118   mng_int32  iX;
14119 
14120 #ifdef MNG_SUPPORT_TRACE
14121   MNG_TRACE (pData, MNG_FN_SCALE_G16_G1, MNG_LC_START);
14122 #endif
14123 
14124 #ifdef MNG_DECREMENT_LOOPS
14125   for (iX = pData->iRowsamples; iX > 0; iX--)
14126 #else
14127   for (iX = 0; iX < pData->iRowsamples; iX++)
14128 #endif
14129   {
14130     *pOutrow = (mng_uint8)(mng_get_uint16 (pWorkrow) >> 15);
14131     pOutrow++;
14132     pWorkrow += 2;
14133   }
14134 
14135 #ifdef MNG_SUPPORT_TRACE
14136   MNG_TRACE (pData, MNG_FN_SCALE_G16_G1, MNG_LC_END);
14137 #endif
14138 
14139   return MNG_NOERROR;
14140 }
14141 #endif
14142 
14143 /* ************************************************************************** */
14144 
mng_scale_g4_g2(mng_datap pData)14145 mng_retcode mng_scale_g4_g2 (mng_datap pData)
14146 {
14147   mng_uint8p pWorkrow = pData->pRGBArow;
14148   mng_int32  iX;
14149 
14150 #ifdef MNG_SUPPORT_TRACE
14151   MNG_TRACE (pData, MNG_FN_SCALE_G4_G2, MNG_LC_START);
14152 #endif
14153 
14154 #ifdef MNG_DECREMENT_LOOPS
14155   for (iX = pData->iRowsamples; iX > 0; iX--)
14156 #else
14157   for (iX = 0; iX < pData->iRowsamples; iX++)
14158 #endif
14159   {
14160     *pWorkrow = (mng_uint8)(*pWorkrow >> 2);
14161     pWorkrow++;
14162   }
14163 
14164 #ifdef MNG_SUPPORT_TRACE
14165   MNG_TRACE (pData, MNG_FN_SCALE_G4_G2, MNG_LC_END);
14166 #endif
14167 
14168   return MNG_NOERROR;
14169 }
14170 
14171 /* ************************************************************************** */
14172 
mng_scale_g8_g2(mng_datap pData)14173 mng_retcode mng_scale_g8_g2 (mng_datap pData)
14174 {
14175   mng_uint8p pWorkrow = pData->pRGBArow;
14176   mng_int32  iX;
14177 
14178 #ifdef MNG_SUPPORT_TRACE
14179   MNG_TRACE (pData, MNG_FN_SCALE_G8_G2, MNG_LC_START);
14180 #endif
14181 
14182 #ifdef MNG_DECREMENT_LOOPS
14183   for (iX = pData->iRowsamples; iX > 0; iX--)
14184 #else
14185   for (iX = 0; iX < pData->iRowsamples; iX++)
14186 #endif
14187   {
14188     *pWorkrow = (mng_uint8)(*pWorkrow >> 6);
14189     pWorkrow++;
14190   }
14191 
14192 #ifdef MNG_SUPPORT_TRACE
14193   MNG_TRACE (pData, MNG_FN_SCALE_G8_G2, MNG_LC_END);
14194 #endif
14195 
14196   return MNG_NOERROR;
14197 }
14198 
14199 /* ************************************************************************** */
14200 
14201 #ifndef MNG_NO_16BIT_SUPPORT
mng_scale_g16_g2(mng_datap pData)14202 mng_retcode mng_scale_g16_g2 (mng_datap pData)
14203 {
14204   mng_uint8p pWorkrow = pData->pRGBArow;
14205   mng_uint8p pOutrow  = pData->pRGBArow;
14206   mng_int32  iX;
14207 
14208 #ifdef MNG_SUPPORT_TRACE
14209   MNG_TRACE (pData, MNG_FN_SCALE_G16_G2, MNG_LC_START);
14210 #endif
14211 
14212 #ifdef MNG_DECREMENT_LOOPS
14213   for (iX = pData->iRowsamples; iX > 0; iX--)
14214 #else
14215   for (iX = 0; iX < pData->iRowsamples; iX++)
14216 #endif
14217   {
14218     *pOutrow = (mng_uint8)(mng_get_uint16 (pWorkrow) >> 14);
14219     pOutrow++;
14220     pWorkrow += 2;
14221   }
14222 
14223 #ifdef MNG_SUPPORT_TRACE
14224   MNG_TRACE (pData, MNG_FN_SCALE_G16_G2, MNG_LC_END);
14225 #endif
14226 
14227   return MNG_NOERROR;
14228 }
14229 #endif
14230 
14231 /* ************************************************************************** */
14232 
mng_scale_g8_g4(mng_datap pData)14233 mng_retcode mng_scale_g8_g4 (mng_datap pData)
14234 {
14235   mng_uint8p pWorkrow = pData->pRGBArow;
14236   mng_int32  iX;
14237 
14238 #ifdef MNG_SUPPORT_TRACE
14239   MNG_TRACE (pData, MNG_FN_SCALE_G8_G4, MNG_LC_START);
14240 #endif
14241 
14242 #ifdef MNG_DECREMENT_LOOPS
14243   for (iX = pData->iRowsamples; iX > 0; iX--)
14244 #else
14245   for (iX = 0; iX < pData->iRowsamples; iX++)
14246 #endif
14247   {
14248     *pWorkrow = (mng_uint8)(*pWorkrow >> 4);
14249     pWorkrow++;
14250   }
14251 
14252 #ifdef MNG_SUPPORT_TRACE
14253   MNG_TRACE (pData, MNG_FN_SCALE_G8_G4, MNG_LC_END);
14254 #endif
14255 
14256   return MNG_NOERROR;
14257 }
14258 
14259 /* ************************************************************************** */
14260 
14261 #ifndef MNG_NO_16BIT_SUPPORT
mng_scale_g16_g4(mng_datap pData)14262 mng_retcode mng_scale_g16_g4 (mng_datap pData)
14263 {
14264   mng_uint8p pWorkrow = pData->pRGBArow;
14265   mng_uint8p pOutrow  = pData->pRGBArow;
14266   mng_int32  iX;
14267 
14268 #ifdef MNG_SUPPORT_TRACE
14269   MNG_TRACE (pData, MNG_FN_SCALE_G16_G4, MNG_LC_START);
14270 #endif
14271 
14272 #ifdef MNG_DECREMENT_LOOPS
14273   for (iX = pData->iRowsamples; iX > 0; iX--)
14274 #else
14275   for (iX = 0; iX < pData->iRowsamples; iX++)
14276 #endif
14277   {
14278     *pOutrow = (mng_uint8)(mng_get_uint16 (pWorkrow) >> 12);
14279     pOutrow++;
14280     pWorkrow += 2;
14281   }
14282 
14283 #ifdef MNG_SUPPORT_TRACE
14284   MNG_TRACE (pData, MNG_FN_SCALE_G16_G4, MNG_LC_END);
14285 #endif
14286 
14287   return MNG_NOERROR;
14288 }
14289 #endif
14290 #endif /* NO_1_2_4BIT_SUPPORT */
14291 
14292 /* ************************************************************************** */
14293 
mng_scale_g16_g8(mng_datap pData)14294 mng_retcode mng_scale_g16_g8 (mng_datap pData)
14295 {
14296   mng_uint8p pWorkrow = pData->pRGBArow;
14297   mng_uint8p pOutrow  = pData->pRGBArow;
14298   mng_int32  iX;
14299 
14300 #ifdef MNG_SUPPORT_TRACE
14301   MNG_TRACE (pData, MNG_FN_SCALE_G16_G8, MNG_LC_START);
14302 #endif
14303 
14304 #ifdef MNG_DECREMENT_LOOPS
14305   for (iX = pData->iRowsamples; iX > 0; iX--)
14306 #else
14307   for (iX = 0; iX < pData->iRowsamples; iX++)
14308 #endif
14309   {
14310     *pOutrow = (mng_uint8)(mng_get_uint16 (pWorkrow) >> 8);
14311     pOutrow++;
14312     pWorkrow += 2;
14313   }
14314 
14315 #ifdef MNG_SUPPORT_TRACE
14316   MNG_TRACE (pData, MNG_FN_SCALE_G16_G8, MNG_LC_END);
14317 #endif
14318 
14319   return MNG_NOERROR;
14320 }
14321 
14322 /* ************************************************************************** */
14323 
mng_scale_ga16_ga8(mng_datap pData)14324 mng_retcode mng_scale_ga16_ga8 (mng_datap pData)
14325 {
14326   mng_uint8p pWorkrow = pData->pRGBArow;
14327   mng_uint8p pOutrow  = pData->pRGBArow;
14328   mng_int32  iX;
14329 
14330 #ifdef MNG_SUPPORT_TRACE
14331   MNG_TRACE (pData, MNG_FN_SCALE_GA16_GA8, MNG_LC_START);
14332 #endif
14333 
14334 #ifdef MNG_DECREMENT_LOOPS
14335   for (iX = pData->iRowsamples; iX > 0; iX--)
14336 #else
14337   for (iX = 0; iX < pData->iRowsamples; iX++)
14338 #endif
14339   {
14340     *pOutrow = (mng_uint8)(mng_get_uint16 (pWorkrow) >> 8);
14341     pOutrow++;
14342     pWorkrow += 2;
14343     *pOutrow = (mng_uint8)(mng_get_uint16 (pWorkrow) >> 8);
14344     pOutrow++;
14345     pWorkrow += 2;
14346   }
14347 
14348 #ifdef MNG_SUPPORT_TRACE
14349   MNG_TRACE (pData, MNG_FN_SCALE_GA16_GA8, MNG_LC_END);
14350 #endif
14351 
14352   return MNG_NOERROR;
14353 }
14354 
14355 /* ************************************************************************** */
14356 
mng_scale_rgb16_rgb8(mng_datap pData)14357 mng_retcode mng_scale_rgb16_rgb8 (mng_datap pData)
14358 {
14359   mng_uint8p pWorkrow = pData->pRGBArow;
14360   mng_uint8p pOutrow  = pData->pRGBArow;
14361   mng_int32  iX;
14362 
14363 #ifdef MNG_SUPPORT_TRACE
14364   MNG_TRACE (pData, MNG_FN_SCALE_RGB16_RGB8, MNG_LC_START);
14365 #endif
14366 
14367 #ifdef MNG_DECREMENT_LOOPS
14368   for (iX = pData->iRowsamples; iX > 0; iX--)
14369 #else
14370   for (iX = 0; iX < pData->iRowsamples; iX++)
14371 #endif
14372   {
14373     *pOutrow = (mng_uint8)(mng_get_uint16 (pWorkrow) >> 8);
14374     pOutrow++;
14375     pWorkrow += 2;
14376     *pOutrow = (mng_uint8)(mng_get_uint16 (pWorkrow) >> 8);
14377     pOutrow++;
14378     pWorkrow += 2;
14379     *pOutrow = (mng_uint8)(mng_get_uint16 (pWorkrow) >> 8);
14380     pOutrow++;
14381     pWorkrow += 2;
14382   }
14383 
14384 #ifdef MNG_SUPPORT_TRACE
14385   MNG_TRACE (pData, MNG_FN_SCALE_RGB16_RGB8, MNG_LC_END);
14386 #endif
14387 
14388   return MNG_NOERROR;
14389 }
14390 
14391 /* ************************************************************************** */
14392 
mng_scale_rgba16_rgba8(mng_datap pData)14393 mng_retcode mng_scale_rgba16_rgba8 (mng_datap pData)
14394 {
14395   mng_uint8p pWorkrow = pData->pRGBArow;
14396   mng_uint8p pOutrow  = pData->pRGBArow;
14397   mng_int32  iX;
14398 
14399 #ifdef MNG_SUPPORT_TRACE
14400   MNG_TRACE (pData, MNG_FN_SCALE_RGBA16_RGBA8, MNG_LC_START);
14401 #endif
14402 
14403 #ifdef MNG_DECREMENT_LOOPS
14404   for (iX = pData->iRowsamples; iX > 0; iX--)
14405 #else
14406   for (iX = 0; iX < pData->iRowsamples; iX++)
14407 #endif
14408   {
14409     *pOutrow = (mng_uint8)(mng_get_uint16 (pWorkrow) >> 8);
14410     pOutrow++;
14411     pWorkrow += 2;
14412     *pOutrow = (mng_uint8)(mng_get_uint16 (pWorkrow) >> 8);
14413     pOutrow++;
14414     pWorkrow += 2;
14415     *pOutrow = (mng_uint8)(mng_get_uint16 (pWorkrow) >> 8);
14416     pOutrow++;
14417     pWorkrow += 2;
14418     *pOutrow = (mng_uint8)(mng_get_uint16 (pWorkrow) >> 8);
14419     pOutrow++;
14420     pWorkrow += 2;
14421   }
14422 
14423 #ifdef MNG_SUPPORT_TRACE
14424   MNG_TRACE (pData, MNG_FN_SCALE_RGBA16_RGBA8, MNG_LC_END);
14425 #endif
14426 
14427   return MNG_NOERROR;
14428 }
14429 #endif
14430 
14431 /* ************************************************************************** */
14432 /* *                                                                        * */
14433 /* * Delta-image bit routines - promote bit_depth                           * */
14434 /* *                                                                        * */
14435 /* ************************************************************************** */
14436 
14437 #ifndef MNG_NO_1_2_4BIT_SUPPORT
mng_promote_replicate_1_2(mng_uint8 iB)14438 mng_uint8 mng_promote_replicate_1_2 (mng_uint8 iB)
14439 {
14440   return (mng_uint8)((iB << 1) | iB);
14441 }
14442 
14443 /* ************************************************************************** */
14444 
mng_promote_replicate_1_4(mng_uint8 iB)14445 mng_uint8 mng_promote_replicate_1_4 (mng_uint8 iB)
14446 {
14447   iB = (mng_uint8)((iB << 1) + iB);
14448   return (mng_uint8)((iB << 2) + iB);
14449 }
14450 
14451 /* ************************************************************************** */
14452 
mng_promote_replicate_1_8(mng_uint8 iB)14453 mng_uint8 mng_promote_replicate_1_8 (mng_uint8 iB)
14454 {
14455   iB = (mng_uint8)((iB << 1) + iB);
14456   iB = (mng_uint8)((iB << 2) + iB);
14457   return (mng_uint8)((iB << 4) + iB);
14458 }
14459 
14460 /* ************************************************************************** */
14461 
14462 #ifndef MNG_NO_16BIT_SUPPORT
mng_promote_replicate_1_16(mng_uint8 iB)14463 mng_uint16 mng_promote_replicate_1_16 (mng_uint8 iB)
14464 {
14465   iB = (mng_uint8)((iB << 1) + iB);
14466   iB = (mng_uint8)((iB << 2) + iB);
14467   iB = (mng_uint8)((iB << 4) + iB);
14468   return (mng_uint16)(((mng_uint16)iB << 8) + (mng_uint16)iB);
14469 }
14470 #endif
14471 
14472 /* ************************************************************************** */
14473 
mng_promote_replicate_2_4(mng_uint8 iB)14474 mng_uint8 mng_promote_replicate_2_4 (mng_uint8 iB)
14475 {
14476   return (mng_uint8)((iB << 2) + iB);
14477 }
14478 
14479 /* ************************************************************************** */
14480 
mng_promote_replicate_2_8(mng_uint8 iB)14481 mng_uint8 mng_promote_replicate_2_8 (mng_uint8 iB)
14482 {
14483   iB = (mng_uint8)((iB << 2) + iB);
14484   return (mng_uint8)((iB << 4) + iB);
14485 }
14486 
14487 /* ************************************************************************** */
14488 
14489 #ifndef MNG_NO_16BIT_SUPPORT
mng_promote_replicate_2_16(mng_uint8 iB)14490 mng_uint16 mng_promote_replicate_2_16 (mng_uint8 iB)
14491 {
14492   iB = (mng_uint8)((iB << 2) + iB);
14493   iB = (mng_uint8)((iB << 4) + iB);
14494   return (mng_uint16)(((mng_uint16)iB << 8) + (mng_uint16)iB);
14495 }
14496 #endif
14497 
14498 /* ************************************************************************** */
14499 
mng_promote_replicate_4_8(mng_uint8 iB)14500 mng_uint8 mng_promote_replicate_4_8 (mng_uint8 iB)
14501 {
14502   return (mng_uint8)((iB << 4) + iB);
14503 }
14504 
14505 /* ************************************************************************** */
14506 
14507 #ifndef MNG_NO_16BIT_SUPPORT
mng_promote_replicate_4_16(mng_uint8 iB)14508 mng_uint16 mng_promote_replicate_4_16 (mng_uint8 iB)
14509 {
14510   iB = (mng_uint8)((iB << 4) + iB);
14511   return (mng_uint16)(((mng_uint16)iB << 8) + (mng_uint16)iB);
14512 }
14513 #endif
14514 #endif /* NO_1_2_4BIT_SUPPORT */
14515 
14516 /* ************************************************************************** */
14517 
14518 #ifndef MNG_NO_16BIT_SUPPORT
mng_promote_replicate_8_16(mng_uint8 iB)14519 mng_uint16 mng_promote_replicate_8_16 (mng_uint8 iB)
14520 {
14521   return (mng_uint16)(((mng_uint16)iB << 8) + (mng_uint16)iB);
14522 }
14523 #endif
14524 
14525 /* ************************************************************************** */
14526 
14527 #if !defined(MNG_NO_DELTA_PNG)
14528 #ifndef MNG_NO_1_2_4BIT_SUPPORT
mng_promote_zerofill_1_2(mng_uint8 iB)14529 mng_uint8 mng_promote_zerofill_1_2 (mng_uint8 iB)
14530 {
14531   return (mng_uint8)(iB << 1);
14532 }
14533 
14534 /* ************************************************************************** */
14535 
mng_promote_zerofill_1_4(mng_uint8 iB)14536 mng_uint8 mng_promote_zerofill_1_4 (mng_uint8 iB)
14537 {
14538   return (mng_uint8)(iB << 3);
14539 }
14540 
14541 /* ************************************************************************** */
14542 
mng_promote_zerofill_1_8(mng_uint8 iB)14543 mng_uint8 mng_promote_zerofill_1_8 (mng_uint8 iB)
14544 {
14545   return (mng_uint8)(iB << 7);
14546 }
14547 
14548 /* ************************************************************************** */
14549 
14550 #ifndef MNG_NO_16BIT_SUPPORT
mng_promote_zerofill_1_16(mng_uint8 iB)14551 mng_uint16 mng_promote_zerofill_1_16 (mng_uint8 iB)
14552 {
14553   return (mng_uint16)((mng_uint16)iB << 15);
14554 }
14555 #endif
14556 
14557 /* ************************************************************************** */
14558 
mng_promote_zerofill_2_4(mng_uint8 iB)14559 mng_uint8 mng_promote_zerofill_2_4 (mng_uint8 iB)
14560 {
14561   return (mng_uint8)(iB << 2);
14562 }
14563 
14564 /* ************************************************************************** */
14565 
mng_promote_zerofill_2_8(mng_uint8 iB)14566 mng_uint8 mng_promote_zerofill_2_8 (mng_uint8 iB)
14567 {
14568   return (mng_uint8)(iB << 6);
14569 }
14570 
14571 /* ************************************************************************** */
14572 
14573 #ifndef MNG_NO_16BIT_SUPPORT
mng_promote_zerofill_2_16(mng_uint8 iB)14574 mng_uint16 mng_promote_zerofill_2_16 (mng_uint8 iB)
14575 {
14576   return (mng_uint16)((mng_uint16)iB << 14);
14577 }
14578 #endif
14579 
14580 /* ************************************************************************** */
14581 
mng_promote_zerofill_4_8(mng_uint8 iB)14582 mng_uint8 mng_promote_zerofill_4_8 (mng_uint8 iB)
14583 {
14584   return (mng_uint8)(iB << 4);
14585 }
14586 
14587 /* ************************************************************************** */
14588 
14589 #ifndef MNG_NO_16BIT_SUPPORT
mng_promote_zerofill_4_16(mng_uint8 iB)14590 mng_uint16 mng_promote_zerofill_4_16 (mng_uint8 iB)
14591 {
14592   return (mng_uint16)((mng_uint16)iB << 12);
14593 }
14594 #endif
14595 #endif /* MNG_NO_1_2_4BIT_SUPPORT */
14596 
14597 /* ************************************************************************** */
14598 
14599 #ifndef MNG_NO_16BIT_SUPPORT
mng_promote_zerofill_8_16(mng_uint8 iB)14600 mng_uint16 mng_promote_zerofill_8_16 (mng_uint8 iB)
14601 {
14602   return (mng_uint16)((mng_uint16)iB << 8);
14603 }
14604 #endif
14605 #endif /* MNG_NO_DELTA_PNG */
14606 
14607 /* ************************************************************************** */
14608 /* *                                                                        * */
14609 /* * Delta-image row routines - promote color_type                          * */
14610 /* *                                                                        * */
14611 /* ************************************************************************** */
14612 
14613 #if !defined(MNG_NO_DELTA_PNG) || !defined(MNG_SKIPCHUNK_PAST) || !defined(MNG_SKIPCHUNK_MAGN)
mng_promote_g8_g8(mng_datap pData)14614 mng_retcode mng_promote_g8_g8 (mng_datap pData)
14615 {
14616   mng_uint8p pSrcline = (mng_uint8p)pData->pPromSrc;
14617   mng_uint8p pDstline = (mng_uint8p)pData->pPromDst;
14618   mng_uint32 iX;
14619   mng_uint8  iB;
14620 
14621 #ifdef MNG_SUPPORT_TRACE
14622   MNG_TRACE (pData, MNG_FN_PROMOTE_G8_G8, MNG_LC_START);
14623 #endif
14624 
14625 #ifdef MNG_DECREMENT_LOOPS
14626   for (iX = pData->iPromWidth; iX > 0; iX--)
14627 #else
14628   for (iX = 0; iX < pData->iPromWidth; iX++)
14629 #endif
14630   {
14631     iB = *pSrcline;
14632     if (pData->fPromBitdepth)      /* bitdepth promoted ? */
14633       iB = ((mng_bitdepth_8)pData->fPromBitdepth) (iB);
14634     *pDstline = iB;
14635 
14636     pSrcline++;
14637     pDstline++;
14638   }
14639 
14640 #ifdef MNG_SUPPORT_TRACE
14641   MNG_TRACE (pData, MNG_FN_PROMOTE_G8_G8, MNG_LC_END);
14642 #endif
14643 
14644   return MNG_NOERROR;
14645 }
14646 
14647 /* ************************************************************************** */
14648 
14649 #ifndef MNG_NO_16BIT_SUPPORT
mng_promote_g8_g16(mng_datap pData)14650 mng_retcode mng_promote_g8_g16 (mng_datap pData)
14651 {
14652   mng_uint8p pSrcline = (mng_uint8p)pData->pPromSrc;
14653   mng_uint8p pDstline = (mng_uint8p)pData->pPromDst;
14654   mng_uint32 iX;
14655   mng_uint16 iW;
14656 
14657 #ifdef MNG_SUPPORT_TRACE
14658   MNG_TRACE (pData, MNG_FN_PROMOTE_G8_G16, MNG_LC_START);
14659 #endif
14660 
14661 #ifdef MNG_DECREMENT_LOOPS
14662   for (iX = pData->iPromWidth; iX > 0; iX--)
14663 #else
14664   for (iX = 0; iX < pData->iPromWidth; iX++)
14665 #endif
14666   {
14667     iW = ((mng_bitdepth_16)pData->fPromBitdepth) (*pSrcline);
14668 
14669     *pDstline     = (mng_uint8)(iW >> 8);
14670     *(pDstline+1) = (mng_uint8)(iW && 0xFF);
14671 
14672     pSrcline++;
14673     pDstline += 2;
14674   }
14675 
14676 #ifdef MNG_SUPPORT_TRACE
14677   MNG_TRACE (pData, MNG_FN_PROMOTE_G8_G16, MNG_LC_END);
14678 #endif
14679 
14680   return MNG_NOERROR;
14681 }
14682 
14683 /* ************************************************************************** */
14684 
mng_promote_g16_g16(mng_datap pData)14685 mng_retcode mng_promote_g16_g16 (mng_datap pData)
14686 {
14687   mng_uint16p pSrcline = (mng_uint16p)pData->pPromSrc;
14688   mng_uint16p pDstline = (mng_uint16p)pData->pPromDst;
14689   mng_uint32  iX;
14690 
14691 #ifdef MNG_SUPPORT_TRACE
14692   MNG_TRACE (pData, MNG_FN_PROMOTE_G16_G16, MNG_LC_START);
14693 #endif
14694 
14695 #ifdef MNG_DECREMENT_LOOPS
14696   for (iX = pData->iPromWidth; iX > 0; iX--)
14697 #else
14698   for (iX = 0; iX < pData->iPromWidth; iX++)
14699 #endif
14700   {
14701     *pDstline = *pSrcline;
14702     pSrcline++;
14703     pDstline++;
14704   }
14705 
14706 #ifdef MNG_SUPPORT_TRACE
14707   MNG_TRACE (pData, MNG_FN_PROMOTE_G16_G16, MNG_LC_END);
14708 #endif
14709 
14710   return MNG_NOERROR;
14711 }
14712 #endif
14713 
14714 /* ************************************************************************** */
14715 
mng_promote_g8_ga8(mng_datap pData)14716 mng_retcode mng_promote_g8_ga8 (mng_datap pData)
14717 {
14718   mng_imagedatap pBuf     = (mng_imagedatap)pData->pPromBuf;
14719   mng_uint8p     pSrcline = (mng_uint8p)pData->pPromSrc;
14720   mng_uint8p     pDstline = (mng_uint8p)pData->pPromDst;
14721   mng_uint32     iX;
14722   mng_uint8      iB;
14723 
14724 #ifdef MNG_SUPPORT_TRACE
14725   MNG_TRACE (pData, MNG_FN_PROMOTE_G8_GA8, MNG_LC_START);
14726 #endif
14727 
14728 #ifdef MNG_DECREMENT_LOOPS
14729   for (iX = pData->iPromWidth; iX > 0; iX--)
14730 #else
14731   for (iX = 0; iX < pData->iPromWidth; iX++)
14732 #endif
14733   {
14734     iB = *pSrcline;
14735                                    /* no cheap transparency ? */
14736     if ((!pBuf->bHasTRNS) || ((mng_uint16)iB != pBuf->iTRNSgray))
14737       *(pDstline+1) = 0xFF;
14738 
14739     if (pData->fPromBitdepth)      /* bitdepth promoted ? */
14740       iB = ((mng_bitdepth_8)pData->fPromBitdepth) (iB);
14741 
14742     *pDstline = iB;
14743 
14744     pSrcline++;
14745     pDstline += 2;
14746   }
14747 
14748 #ifdef MNG_SUPPORT_TRACE
14749   MNG_TRACE (pData, MNG_FN_PROMOTE_G8_GA8, MNG_LC_END);
14750 #endif
14751 
14752   return MNG_NOERROR;
14753 }
14754 
14755 /* ************************************************************************** */
14756 
14757 #ifndef MNG_NO_16BIT_SUPPORT
mng_promote_g8_ga16(mng_datap pData)14758 mng_retcode mng_promote_g8_ga16 (mng_datap pData)
14759 {
14760   mng_imagedatap pBuf     = (mng_imagedatap)pData->pPromBuf;
14761   mng_uint8p     pSrcline = (mng_uint8p)pData->pPromSrc;
14762   mng_uint8p     pDstline = (mng_uint8p)pData->pPromDst;
14763   mng_uint32     iX;
14764   mng_uint8      iB;
14765   mng_uint16     iW;
14766 
14767 #ifdef MNG_SUPPORT_TRACE
14768   MNG_TRACE (pData, MNG_FN_PROMOTE_G8_GA16, MNG_LC_START);
14769 #endif
14770 
14771 #ifdef MNG_DECREMENT_LOOPS
14772   for (iX = pData->iPromWidth; iX > 0; iX--)
14773 #else
14774   for (iX = 0; iX < pData->iPromWidth; iX++)
14775 #endif
14776   {
14777     iB = *pSrcline;
14778                                    /* no cheap transparency ? */
14779     if ((!pBuf->bHasTRNS) || ((mng_uint16)iB != pBuf->iTRNSgray))
14780     {
14781       *(pDstline+2) = 0xFF;
14782       *(pDstline+3) = 0xFF;
14783     }
14784 
14785     iW = ((mng_bitdepth_16)pData->fPromBitdepth) (iB);
14786 
14787     *pDstline     = (mng_uint8)(iW >> 8);
14788     *(pDstline+1) = (mng_uint8)(iW && 0xFF);
14789 
14790     pSrcline++;
14791     pDstline += 4;
14792   }
14793 
14794 #ifdef MNG_SUPPORT_TRACE
14795   MNG_TRACE (pData, MNG_FN_PROMOTE_G8_GA16, MNG_LC_END);
14796 #endif
14797 
14798   return MNG_NOERROR;
14799 }
14800 #endif
14801 
14802 /* ************************************************************************** */
14803 
14804 #ifndef MNG_NO_16BIT_SUPPORT
mng_promote_g16_ga16(mng_datap pData)14805 mng_retcode mng_promote_g16_ga16 (mng_datap pData)
14806 {
14807   mng_imagedatap pBuf     = (mng_imagedatap)pData->pPromBuf;
14808   mng_uint16p    pSrcline = (mng_uint16p)pData->pPromSrc;
14809   mng_uint16p    pDstline = (mng_uint16p)pData->pPromDst;
14810   mng_uint32     iX;
14811   mng_uint16     iW;
14812 
14813 #ifdef MNG_SUPPORT_TRACE
14814   MNG_TRACE (pData, MNG_FN_PROMOTE_G16_GA16, MNG_LC_START);
14815 #endif
14816 
14817 #ifdef MNG_DECREMENT_LOOPS
14818   for (iX = pData->iPromWidth; iX > 0; iX--)
14819 #else
14820   for (iX = 0; iX < pData->iPromWidth; iX++)
14821 #endif
14822   {
14823     iW = *pSrcline;
14824                                    /* no cheap transparency ? */
14825     if ((!pBuf->bHasTRNS) || ((mng_uint16)iW != pBuf->iTRNSgray))
14826       *(pDstline+1) = 0xFFFF;
14827 
14828     *pDstline = iW;
14829 
14830     pSrcline++;
14831     pDstline += 2;
14832   }
14833 
14834 #ifdef MNG_SUPPORT_TRACE
14835   MNG_TRACE (pData, MNG_FN_PROMOTE_G16_GA16, MNG_LC_END);
14836 #endif
14837 
14838   return MNG_NOERROR;
14839 }
14840 #endif
14841 
14842 /* ************************************************************************** */
14843 
mng_promote_g8_rgb8(mng_datap pData)14844 mng_retcode mng_promote_g8_rgb8 (mng_datap pData)
14845 {
14846   mng_uint8p pSrcline = (mng_uint8p)pData->pPromSrc;
14847   mng_uint8p pDstline = (mng_uint8p)pData->pPromDst;
14848   mng_uint32 iX;
14849   mng_uint8  iB;
14850 
14851 #ifdef MNG_SUPPORT_TRACE
14852   MNG_TRACE (pData, MNG_FN_PROMOTE_G8_RGB8, MNG_LC_START);
14853 #endif
14854 
14855 #ifdef MNG_DECREMENT_LOOPS
14856   for (iX = pData->iPromWidth; iX > 0; iX--)
14857 #else
14858   for (iX = 0; iX < pData->iPromWidth; iX++)
14859 #endif
14860   {
14861     iB = *pSrcline;
14862 
14863     if (pData->fPromBitdepth)      /* bitdepth promoted ? */
14864       iB = ((mng_bitdepth_8)pData->fPromBitdepth) (iB);
14865 
14866     *pDstline     = iB;
14867     *(pDstline+1) = iB;
14868     *(pDstline+2) = iB;
14869 
14870     pSrcline++;
14871     pDstline += 3;
14872   }
14873 
14874 #ifdef MNG_SUPPORT_TRACE
14875   MNG_TRACE (pData, MNG_FN_PROMOTE_G8_RGB8, MNG_LC_END);
14876 #endif
14877 
14878   return MNG_NOERROR;
14879 }
14880 
14881 /* ************************************************************************** */
14882 
14883 #ifndef MNG_NO_16BIT_SUPPORT
mng_promote_g8_rgb16(mng_datap pData)14884 mng_retcode mng_promote_g8_rgb16 (mng_datap pData)
14885 {
14886   mng_uint8p pSrcline = (mng_uint8p)pData->pPromSrc;
14887   mng_uint8p pDstline = (mng_uint8p)pData->pPromDst;
14888   mng_uint32 iX;
14889   mng_uint8  iB;
14890   mng_uint16 iW;
14891 
14892 #ifdef MNG_SUPPORT_TRACE
14893   MNG_TRACE (pData, MNG_FN_PROMOTE_G8_RGB16, MNG_LC_START);
14894 #endif
14895 
14896 #ifdef MNG_DECREMENT_LOOPS
14897   for (iX = pData->iPromWidth; iX > 0; iX--)
14898 #else
14899   for (iX = 0; iX < pData->iPromWidth; iX++)
14900 #endif
14901   {
14902     iB = *pSrcline;
14903     iW = ((mng_bitdepth_16)pData->fPromBitdepth) (iB);
14904 
14905     iB            = (mng_uint8)(iW >> 8);
14906     *pDstline     = iB;
14907     *(pDstline+2) = iB;
14908     *(pDstline+4) = iB;
14909     iB            = (mng_uint8)(iW && 0xFF);
14910     *(pDstline+1) = iB;
14911     *(pDstline+3) = iB;
14912     *(pDstline+5) = iB;
14913 
14914     pSrcline++;
14915     pDstline += 6;
14916   }
14917 
14918 #ifdef MNG_SUPPORT_TRACE
14919   MNG_TRACE (pData, MNG_FN_PROMOTE_G8_RGB16, MNG_LC_END);
14920 #endif
14921 
14922   return MNG_NOERROR;
14923 }
14924 #endif
14925 
14926 /* ************************************************************************** */
14927 
14928 #ifndef MNG_NO_16BIT_SUPPORT
mng_promote_g16_rgb16(mng_datap pData)14929 mng_retcode mng_promote_g16_rgb16 (mng_datap pData)
14930 {
14931   mng_uint16p pSrcline = (mng_uint16p)pData->pPromSrc;
14932   mng_uint16p pDstline = (mng_uint16p)pData->pPromDst;
14933   mng_uint32  iX;
14934   mng_uint16  iW;
14935 
14936 #ifdef MNG_SUPPORT_TRACE
14937   MNG_TRACE (pData, MNG_FN_PROMOTE_G16_RGB16, MNG_LC_START);
14938 #endif
14939 
14940 #ifdef MNG_DECREMENT_LOOPS
14941   for (iX = pData->iPromWidth; iX > 0; iX--)
14942 #else
14943   for (iX = 0; iX < pData->iPromWidth; iX++)
14944 #endif
14945   {
14946     iW = *pSrcline;
14947 
14948     *pDstline     = iW;
14949     *(pDstline+1) = iW;
14950     *(pDstline+2) = iW;
14951 
14952     pSrcline++;
14953     pDstline += 3;
14954   }
14955 
14956 #ifdef MNG_SUPPORT_TRACE
14957   MNG_TRACE (pData, MNG_FN_PROMOTE_G16_RGB16, MNG_LC_END);
14958 #endif
14959 
14960   return MNG_NOERROR;
14961 }
14962 #endif
14963 
14964 /* ************************************************************************** */
14965 
mng_promote_g8_rgba8(mng_datap pData)14966 mng_retcode mng_promote_g8_rgba8 (mng_datap pData)
14967 {
14968   mng_imagedatap pBuf     = (mng_imagedatap)pData->pPromBuf;
14969   mng_uint8p     pSrcline = (mng_uint8p)pData->pPromSrc;
14970   mng_uint8p     pDstline = (mng_uint8p)pData->pPromDst;
14971   mng_uint32     iX;
14972   mng_uint8      iB;
14973 
14974 #ifdef MNG_SUPPORT_TRACE
14975   MNG_TRACE (pData, MNG_FN_PROMOTE_G8_RGBA8, MNG_LC_START);
14976 #endif
14977 
14978 #ifdef MNG_DECREMENT_LOOPS
14979   for (iX = pData->iPromWidth; iX > 0; iX--)
14980 #else
14981   for (iX = 0; iX < pData->iPromWidth; iX++)
14982 #endif
14983   {
14984     iB = *pSrcline;
14985                                    /* no cheap transparency ? */
14986     if ((!pBuf->bHasTRNS) || ((mng_uint16)iB != pBuf->iTRNSgray))
14987       *(pDstline+3) = 0xFF;
14988 
14989     if (pData->fPromBitdepth)      /* bitdepth promoted ? */
14990       iB = ((mng_bitdepth_8)pData->fPromBitdepth) (iB);
14991 
14992     *pDstline     = iB;
14993     *(pDstline+1) = iB;
14994     *(pDstline+2) = iB;
14995 
14996     pSrcline++;
14997     pDstline += 4;
14998   }
14999 
15000 #ifdef MNG_SUPPORT_TRACE
15001   MNG_TRACE (pData, MNG_FN_PROMOTE_G8_RGBA8, MNG_LC_END);
15002 #endif
15003 
15004   return MNG_NOERROR;
15005 }
15006 
15007 /* ************************************************************************** */
15008 
15009 #ifndef MNG_NO_16BIT_SUPPORT
mng_promote_g8_rgba16(mng_datap pData)15010 mng_retcode mng_promote_g8_rgba16 (mng_datap pData)
15011 {
15012   mng_imagedatap pBuf     = (mng_imagedatap)pData->pPromBuf;
15013   mng_uint8p     pSrcline = (mng_uint8p)pData->pPromSrc;
15014   mng_uint8p     pDstline = (mng_uint8p)pData->pPromDst;
15015   mng_uint32     iX;
15016   mng_uint8      iB;
15017   mng_uint16     iW;
15018 
15019 #ifdef MNG_SUPPORT_TRACE
15020   MNG_TRACE (pData, MNG_FN_PROMOTE_G8_RGBA16, MNG_LC_START);
15021 #endif
15022 
15023 #ifdef MNG_DECREMENT_LOOPS
15024   for (iX = pData->iPromWidth; iX > 0; iX--)
15025 #else
15026   for (iX = 0; iX < pData->iPromWidth; iX++)
15027 #endif
15028   {
15029     iB = *pSrcline;
15030                                    /* no cheap transparency ? */
15031     if ((!pBuf->bHasTRNS) || ((mng_uint16)iB != pBuf->iTRNSgray))
15032     {
15033       *(pDstline+6) = 0xFF;
15034       *(pDstline+7) = 0xFF;
15035     }
15036 
15037     iW            = ((mng_bitdepth_16)pData->fPromBitdepth) (iB);
15038 
15039     iB            = (mng_uint8)(iW >> 8);
15040     *pDstline     = iB;
15041     *(pDstline+2) = iB;
15042     *(pDstline+4) = iB;
15043     iB            = (mng_uint8)(iW && 0xFF);
15044     *(pDstline+1) = iB;
15045     *(pDstline+3) = iB;
15046     *(pDstline+5) = iB;;
15047 
15048     pSrcline++;
15049     pDstline += 8;
15050   }
15051 
15052 #ifdef MNG_SUPPORT_TRACE
15053   MNG_TRACE (pData, MNG_FN_PROMOTE_G8_RGBA16, MNG_LC_END);
15054 #endif
15055 
15056   return MNG_NOERROR;
15057 }
15058 #endif
15059 
15060 /* ************************************************************************** */
15061 
15062 #ifndef MNG_NO_16BIT_SUPPORT
mng_promote_g16_rgba16(mng_datap pData)15063 mng_retcode mng_promote_g16_rgba16 (mng_datap pData)
15064 {
15065   mng_imagedatap pBuf     = (mng_imagedatap)pData->pPromBuf;
15066   mng_uint16p    pSrcline = (mng_uint16p)pData->pPromSrc;
15067   mng_uint16p    pDstline = (mng_uint16p)pData->pPromDst;
15068   mng_uint32     iX;
15069   mng_uint16     iW;
15070 
15071 #ifdef MNG_SUPPORT_TRACE
15072   MNG_TRACE (pData, MNG_FN_PROMOTE_G16_RGBA16, MNG_LC_START);
15073 #endif
15074 
15075 #ifdef MNG_DECREMENT_LOOPS
15076   for (iX = pData->iPromWidth; iX > 0; iX--)
15077 #else
15078   for (iX = 0; iX < pData->iPromWidth; iX++)
15079 #endif
15080   {
15081     iW = *pSrcline;
15082                                    /* no cheap transparency ? */
15083     if ((!pBuf->bHasTRNS) || (iW != pBuf->iTRNSgray))
15084       *(pDstline+3) = 0xFFFF;
15085 
15086     *pDstline     = iW;
15087     *(pDstline+1) = iW;
15088     *(pDstline+2) = iW;
15089 
15090     pSrcline++;
15091     pDstline += 4;
15092   }
15093 
15094 #ifdef MNG_SUPPORT_TRACE
15095   MNG_TRACE (pData, MNG_FN_PROMOTE_G16_RGBA16, MNG_LC_END);
15096 #endif
15097 
15098   return MNG_NOERROR;
15099 }
15100 #endif
15101 
15102 /* ************************************************************************** */
15103 
15104 #ifndef MNG_NO_16BIT_SUPPORT
mng_promote_ga8_ga16(mng_datap pData)15105 mng_retcode mng_promote_ga8_ga16 (mng_datap pData)
15106 {
15107   mng_uint8p pSrcline = (mng_uint8p)pData->pPromSrc;
15108   mng_uint8p pDstline = (mng_uint8p)pData->pPromDst;
15109   mng_uint32 iX;
15110   mng_uint16 iW;
15111   mng_uint16 iA;
15112 
15113 #ifdef MNG_SUPPORT_TRACE
15114   MNG_TRACE (pData, MNG_FN_PROMOTE_GA8_GA16, MNG_LC_START);
15115 #endif
15116 
15117 #ifdef MNG_DECREMENT_LOOPS
15118   for (iX = pData->iPromWidth; iX > 0; iX--)
15119 #else
15120   for (iX = 0; iX < pData->iPromWidth; iX++)
15121 #endif
15122   {
15123     iW = ((mng_bitdepth_16)pData->fPromBitdepth) (*pSrcline);
15124     iA = ((mng_bitdepth_16)pData->fPromBitdepth) (*(pSrcline+1));
15125 
15126     *pDstline     = (mng_uint8)(iW >> 8);
15127     *(pDstline+1) = (mng_uint8)(iW && 0xFF);
15128     *(pDstline+2) = (mng_uint8)(iA >> 8);
15129     *(pDstline+3) = (mng_uint8)(iA && 0xFF);
15130 
15131     pSrcline += 2;
15132     pDstline += 4;
15133   }
15134 
15135 #ifdef MNG_SUPPORT_TRACE
15136   MNG_TRACE (pData, MNG_FN_PROMOTE_GA8_GA16, MNG_LC_END);
15137 #endif
15138 
15139   return MNG_NOERROR;
15140 }
15141 #endif
15142 
15143 /* ************************************************************************** */
15144 
mng_promote_ga8_rgba8(mng_datap pData)15145 mng_retcode mng_promote_ga8_rgba8 (mng_datap pData)
15146 {
15147   mng_uint8p     pSrcline = (mng_uint8p)pData->pPromSrc;
15148   mng_uint8p     pDstline = (mng_uint8p)pData->pPromDst;
15149   mng_uint32     iX;
15150   mng_uint8      iB;
15151   mng_uint8      iA;
15152 
15153 #ifdef MNG_SUPPORT_TRACE
15154   MNG_TRACE (pData, MNG_FN_PROMOTE_GA8_RGBA8, MNG_LC_START);
15155 #endif
15156 
15157 #ifdef MNG_DECREMENT_LOOPS
15158   for (iX = pData->iPromWidth; iX > 0; iX--)
15159 #else
15160   for (iX = 0; iX < pData->iPromWidth; iX++)
15161 #endif
15162   {
15163     iB = *pSrcline;
15164     iA = *(pSrcline+1);
15165 
15166     *pDstline     = iB;
15167     *(pDstline+1) = iB;
15168     *(pDstline+2) = iB;
15169     *(pDstline+3) = iA;
15170 
15171     pSrcline += 2;
15172     pDstline += 4;
15173   }
15174 
15175 #ifdef MNG_SUPPORT_TRACE
15176   MNG_TRACE (pData, MNG_FN_PROMOTE_GA8_RGBA8, MNG_LC_END);
15177 #endif
15178 
15179   return MNG_NOERROR;
15180 }
15181 
15182 /* ************************************************************************** */
15183 
15184 #ifndef MNG_NO_16BIT_SUPPORT
mng_promote_ga8_rgba16(mng_datap pData)15185 mng_retcode mng_promote_ga8_rgba16 (mng_datap pData)
15186 {
15187   mng_uint8p pSrcline = (mng_uint8p)pData->pPromSrc;
15188   mng_uint8p pDstline = (mng_uint8p)pData->pPromDst;
15189   mng_uint32 iX;
15190   mng_uint8  iB;
15191   mng_uint16 iW;
15192   mng_uint16 iA;
15193 
15194 #ifdef MNG_SUPPORT_TRACE
15195   MNG_TRACE (pData, MNG_FN_PROMOTE_GA8_RGBA16, MNG_LC_START);
15196 #endif
15197 
15198 #ifdef MNG_DECREMENT_LOOPS
15199   for (iX = pData->iPromWidth; iX > 0; iX--)
15200 #else
15201   for (iX = 0; iX < pData->iPromWidth; iX++)
15202 #endif
15203   {
15204     iW = ((mng_bitdepth_16)pData->fPromBitdepth) (*pSrcline);
15205     iA = ((mng_bitdepth_16)pData->fPromBitdepth) (*(pSrcline+1));
15206 
15207     iB            = (mng_uint8)(iW >> 8);
15208     *pDstline     = iB;
15209     *(pDstline+2) = iB;
15210     *(pDstline+4) = iB;
15211     iB            = (mng_uint8)(iW && 0xFF);
15212     *(pDstline+1) = iB;
15213     *(pDstline+3) = iB;
15214     *(pDstline+5) = iB;
15215     *(pDstline+6) = (mng_uint8)(iA >> 8);
15216     *(pDstline+7) = (mng_uint8)(iA && 0xFF);
15217 
15218     pSrcline += 2;
15219     pDstline += 8;
15220   }
15221 
15222 #ifdef MNG_SUPPORT_TRACE
15223   MNG_TRACE (pData, MNG_FN_PROMOTE_GA8_RGBA16, MNG_LC_END);
15224 #endif
15225 
15226   return MNG_NOERROR;
15227 }
15228 #endif
15229 
15230 /* ************************************************************************** */
15231 
15232 #ifndef MNG_NO_16BIT_SUPPORT
mng_promote_ga16_rgba16(mng_datap pData)15233 mng_retcode mng_promote_ga16_rgba16 (mng_datap pData)
15234 {
15235   mng_uint16p pSrcline = (mng_uint16p)pData->pPromSrc;
15236   mng_uint16p pDstline = (mng_uint16p)pData->pPromDst;
15237   mng_uint32 iX;
15238   mng_uint16 iW;
15239   mng_uint16 iA;
15240 
15241 #ifdef MNG_SUPPORT_TRACE
15242   MNG_TRACE (pData, MNG_FN_PROMOTE_GA16_RGBA16, MNG_LC_START);
15243 #endif
15244 
15245 #ifdef MNG_DECREMENT_LOOPS
15246   for (iX = pData->iPromWidth; iX > 0; iX--)
15247 #else
15248   for (iX = 0; iX < pData->iPromWidth; iX++)
15249 #endif
15250   {
15251     iW = *pSrcline;
15252     iA = *(pSrcline+1);
15253 
15254     *pDstline     = iW;
15255     *(pDstline+1) = iW;
15256     *(pDstline+2) = iW;
15257     *(pDstline+3) = iA;
15258 
15259     pSrcline += 2;
15260     pDstline += 4;
15261   }
15262 
15263 #ifdef MNG_SUPPORT_TRACE
15264   MNG_TRACE (pData, MNG_FN_PROMOTE_GA16_RGBA16, MNG_LC_END);
15265 #endif
15266 
15267   return MNG_NOERROR;
15268 }
15269 #endif
15270 
15271 /* ************************************************************************** */
15272 
15273 #ifndef MNG_NO_16BIT_SUPPORT
mng_promote_rgb8_rgb16(mng_datap pData)15274 mng_retcode mng_promote_rgb8_rgb16 (mng_datap pData)
15275 {
15276   mng_uint8p pSrcline = (mng_uint8p)pData->pPromSrc;
15277   mng_uint8p pDstline = (mng_uint8p)pData->pPromDst;
15278   mng_uint32 iX;
15279   mng_uint16 iR;
15280   mng_uint16 iG;
15281   mng_uint16 iB;
15282 
15283 #ifdef MNG_SUPPORT_TRACE
15284   MNG_TRACE (pData, MNG_FN_PROMOTE_RGB8_RGB16, MNG_LC_START);
15285 #endif
15286 
15287 #ifdef MNG_DECREMENT_LOOPS
15288   for (iX = pData->iPromWidth; iX > 0; iX--)
15289 #else
15290   for (iX = 0; iX < pData->iPromWidth; iX++)
15291 #endif
15292   {
15293     iR            = ((mng_bitdepth_16)pData->fPromBitdepth) (*pSrcline);
15294     iG            = ((mng_bitdepth_16)pData->fPromBitdepth) (*(pSrcline+1));
15295     iB            = ((mng_bitdepth_16)pData->fPromBitdepth) (*(pSrcline+2));
15296 
15297     *pDstline     = (mng_uint8)(iR >> 8);
15298     *(pDstline+1) = (mng_uint8)(iR && 0xFF);
15299     *(pDstline+2) = (mng_uint8)(iG >> 8);
15300     *(pDstline+3) = (mng_uint8)(iG && 0xFF);
15301     *(pDstline+4) = (mng_uint8)(iB >> 8);
15302     *(pDstline+5) = (mng_uint8)(iB && 0xFF);
15303 
15304     pSrcline += 3;
15305     pDstline += 6;
15306   }
15307 
15308 #ifdef MNG_SUPPORT_TRACE
15309   MNG_TRACE (pData, MNG_FN_PROMOTE_RGB8_RGB16, MNG_LC_END);
15310 #endif
15311 
15312   return MNG_NOERROR;
15313 }
15314 #endif
15315 
15316 /* ************************************************************************** */
15317 
mng_promote_rgb8_rgba8(mng_datap pData)15318 mng_retcode mng_promote_rgb8_rgba8 (mng_datap pData)
15319 {
15320   mng_imagedatap pBuf     = (mng_imagedatap)pData->pPromBuf;
15321   mng_uint8p     pSrcline = (mng_uint8p)pData->pPromSrc;
15322   mng_uint8p     pDstline = (mng_uint8p)pData->pPromDst;
15323   mng_uint32     iX;
15324   mng_uint8      iR;
15325   mng_uint8      iG;
15326   mng_uint8      iB;
15327 
15328 #ifdef MNG_SUPPORT_TRACE
15329   MNG_TRACE (pData, MNG_FN_PROMOTE_RGB8_RGBA8, MNG_LC_START);
15330 #endif
15331 
15332 #ifdef MNG_DECREMENT_LOOPS
15333   for (iX = pData->iPromWidth; iX > 0; iX--)
15334 #else
15335   for (iX = 0; iX < pData->iPromWidth; iX++)
15336 #endif
15337   {
15338     iR = *pSrcline;
15339     iG = *(pSrcline+1);
15340     iB = *(pSrcline+2);
15341                                    /* no cheap transparency ? */
15342     if ((!pBuf->bHasTRNS) || ((mng_uint16)iR != pBuf->iTRNSred) ||
15343         ((mng_uint16)iG != pBuf->iTRNSgreen) || ((mng_uint16)iB != pBuf->iTRNSblue))
15344       *(pDstline+3) = 0xFF;
15345 
15346     *pDstline     = iR;
15347     *(pDstline+1) = iG;
15348     *(pDstline+2) = iB;
15349 
15350     pSrcline += 3;
15351     pDstline += 4;
15352   }
15353 
15354 #ifdef MNG_SUPPORT_TRACE
15355   MNG_TRACE (pData, MNG_FN_PROMOTE_RGB8_RGBA8, MNG_LC_END);
15356 #endif
15357 
15358   return MNG_NOERROR;
15359 }
15360 
15361 /* ************************************************************************** */
15362 
15363 #ifndef MNG_NO_16BIT_SUPPORT
mng_promote_rgb8_rgba16(mng_datap pData)15364 mng_retcode mng_promote_rgb8_rgba16 (mng_datap pData)
15365 {
15366   mng_imagedatap pBuf     = (mng_imagedatap)pData->pPromBuf;
15367   mng_uint8p     pSrcline = (mng_uint8p)pData->pPromSrc;
15368   mng_uint8p     pDstline = (mng_uint8p)pData->pPromDst;
15369   mng_uint32     iX;
15370   mng_uint8      iR;
15371   mng_uint8      iG;
15372   mng_uint8      iB;
15373   mng_uint16     iRw;
15374   mng_uint16     iGw;
15375   mng_uint16     iBw;
15376 
15377 #ifdef MNG_SUPPORT_TRACE
15378   MNG_TRACE (pData, MNG_FN_PROMOTE_RGB8_RGBA16, MNG_LC_START);
15379 #endif
15380 
15381 #ifdef MNG_DECREMENT_LOOPS
15382   for (iX = pData->iPromWidth; iX > 0; iX--)
15383 #else
15384   for (iX = 0; iX < pData->iPromWidth; iX++)
15385 #endif
15386   {
15387     iR = *pSrcline;
15388     iG = *(pSrcline+1);
15389     iB = *(pSrcline+2);
15390                                    /* no cheap transparency ? */
15391     if ((!pBuf->bHasTRNS) || ((mng_uint16)iR != pBuf->iTRNSred) ||
15392         ((mng_uint16)iG != pBuf->iTRNSgreen) || ((mng_uint16)iB != pBuf->iTRNSblue))
15393     {
15394       *(pDstline+6) = 0xFF;
15395       *(pDstline+7) = 0xFF;
15396     }
15397 
15398     iRw           = ((mng_bitdepth_16)pData->fPromBitdepth) (iR);
15399     iGw           = ((mng_bitdepth_16)pData->fPromBitdepth) (iG);
15400     iBw           = ((mng_bitdepth_16)pData->fPromBitdepth) (iB);
15401 
15402     *pDstline     = (mng_uint8)(iRw >> 8);
15403     *(pDstline+1) = (mng_uint8)(iRw && 0xFF);
15404     *(pDstline+2) = (mng_uint8)(iGw >> 8);
15405     *(pDstline+3) = (mng_uint8)(iGw && 0xFF);
15406     *(pDstline+4) = (mng_uint8)(iBw >> 8);
15407     *(pDstline+5) = (mng_uint8)(iBw && 0xFF);
15408 
15409     pSrcline += 3;
15410     pDstline += 8;
15411   }
15412 
15413 #ifdef MNG_SUPPORT_TRACE
15414   MNG_TRACE (pData, MNG_FN_PROMOTE_RGB8_RGBA16, MNG_LC_END);
15415 #endif
15416 
15417   return MNG_NOERROR;
15418 }
15419 #endif
15420 
15421 /* ************************************************************************** */
15422 
15423 #ifndef MNG_NO_16BIT_SUPPORT
mng_promote_rgb16_rgba16(mng_datap pData)15424 mng_retcode mng_promote_rgb16_rgba16 (mng_datap pData)
15425 {
15426   mng_imagedatap pBuf     = (mng_imagedatap)pData->pPromBuf;
15427   mng_uint16p    pSrcline = (mng_uint16p)pData->pPromSrc;
15428   mng_uint16p    pDstline = (mng_uint16p)pData->pPromDst;
15429   mng_uint32     iX;
15430   mng_uint16     iR;
15431   mng_uint16     iG;
15432   mng_uint16     iB;
15433 
15434 #ifdef MNG_SUPPORT_TRACE
15435   MNG_TRACE (pData, MNG_FN_PROMOTE_RGB16_RGBA16, MNG_LC_START);
15436 #endif
15437 
15438 #ifdef MNG_DECREMENT_LOOPS
15439   for (iX = pData->iPromWidth; iX > 0; iX--)
15440 #else
15441   for (iX = 0; iX < pData->iPromWidth; iX++)
15442 #endif
15443   {
15444     iR = *pSrcline;
15445     iG = *(pSrcline+1);
15446     iB = *(pSrcline+2);
15447                                    /* no cheap transparency ? */
15448     if ((!pBuf->bHasTRNS) || (iR != pBuf->iTRNSred) ||
15449         (iG != pBuf->iTRNSgreen) || (iB != pBuf->iTRNSblue))
15450       *(pDstline+3) = 0xFFFF;
15451 
15452     *pDstline     = iR;
15453     *(pDstline+1) = iG;
15454     *(pDstline+2) = iB;
15455 
15456     pSrcline += 3;
15457     pDstline += 4;
15458   }
15459 
15460 #ifdef MNG_SUPPORT_TRACE
15461   MNG_TRACE (pData, MNG_FN_PROMOTE_RGB16_RGBA16, MNG_LC_END);
15462 #endif
15463 
15464   return MNG_NOERROR;
15465 }
15466 #endif
15467 
15468 /* ************************************************************************** */
15469 
mng_promote_idx8_rgb8(mng_datap pData)15470 mng_retcode mng_promote_idx8_rgb8 (mng_datap pData)
15471 {
15472   mng_imagedatap pBuf     = (mng_imagedatap)pData->pPromBuf;
15473   mng_uint8p     pSrcline = (mng_uint8p)pData->pPromSrc;
15474   mng_uint8p     pDstline = (mng_uint8p)pData->pPromDst;
15475   mng_uint32     iX;
15476   mng_uint8      iB;
15477 
15478 #ifdef MNG_SUPPORT_TRACE
15479   MNG_TRACE (pData, MNG_FN_PROMOTE_IDX8_RGB8, MNG_LC_START);
15480 #endif
15481 
15482 #ifdef MNG_DECREMENT_LOOPS
15483   for (iX = pData->iPromWidth; iX > 0; iX--)
15484 #else
15485   for (iX = 0; iX < pData->iPromWidth; iX++)
15486 #endif
15487   {
15488     iB = *pSrcline;
15489 
15490     if ((mng_uint32)iB < pBuf->iPLTEcount)
15491     {
15492       *pDstline     = pBuf->aPLTEentries [iB].iRed;
15493       *(pDstline+1) = pBuf->aPLTEentries [iB].iGreen;
15494       *(pDstline+2) = pBuf->aPLTEentries [iB].iBlue;
15495     }
15496 
15497     pSrcline++;
15498     pDstline += 3;
15499   }
15500 
15501 #ifdef MNG_SUPPORT_TRACE
15502   MNG_TRACE (pData, MNG_FN_PROMOTE_IDX8_RGB8, MNG_LC_END);
15503 #endif
15504 
15505   return MNG_NOERROR;
15506 }
15507 
15508 /* ************************************************************************** */
15509 
15510 #ifndef MNG_NO_16BIT_SUPPORT
mng_promote_idx8_rgb16(mng_datap pData)15511 mng_retcode mng_promote_idx8_rgb16 (mng_datap pData)
15512 {
15513   mng_imagedatap pBuf     = (mng_imagedatap)pData->pPromBuf;
15514   mng_uint8p     pSrcline = (mng_uint8p)pData->pPromSrc;
15515   mng_uint8p     pDstline = (mng_uint8p)pData->pPromDst;
15516   mng_uint32     iX;
15517   mng_uint8      iN;
15518   mng_uint16     iR;
15519   mng_uint16     iG;
15520   mng_uint16     iB;
15521 
15522 #ifdef MNG_SUPPORT_TRACE
15523   MNG_TRACE (pData, MNG_FN_PROMOTE_IDX8_RGB16, MNG_LC_START);
15524 #endif
15525 
15526 #ifdef MNG_DECREMENT_LOOPS
15527   for (iX = pData->iPromWidth; iX > 0; iX--)
15528 #else
15529   for (iX = 0; iX < pData->iPromWidth; iX++)
15530 #endif
15531   {
15532     iN = *pSrcline;
15533 
15534     if ((mng_uint32)iN < pBuf->iPLTEcount)
15535     {
15536       iR              = ((mng_bitdepth_16)pData->fPromBitdepth) (pBuf->aPLTEentries [iN].iRed);
15537       iG              = ((mng_bitdepth_16)pData->fPromBitdepth) (pBuf->aPLTEentries [iN].iGreen);
15538       iB              = ((mng_bitdepth_16)pData->fPromBitdepth) (pBuf->aPLTEentries [iN].iBlue);
15539       *pDstline       = (mng_uint8)(iR >> 8);
15540       *(pDstline+1)   = (mng_uint8)(iR && 0xFF);
15541       *(pDstline+2)   = (mng_uint8)(iG >> 8);
15542       *(pDstline+3)   = (mng_uint8)(iG && 0xFF);
15543       *(pDstline+4)   = (mng_uint8)(iB >> 8);
15544       *(pDstline+5)   = (mng_uint8)(iB && 0xFF);
15545     }
15546 
15547     pSrcline++;
15548     pDstline += 6;
15549   }
15550 
15551 #ifdef MNG_SUPPORT_TRACE
15552   MNG_TRACE (pData, MNG_FN_PROMOTE_IDX8_RGB16, MNG_LC_END);
15553 #endif
15554 
15555   return MNG_NOERROR;
15556 }
15557 #endif
15558 
15559 /* ************************************************************************** */
15560 
mng_promote_idx8_rgba8(mng_datap pData)15561 mng_retcode mng_promote_idx8_rgba8 (mng_datap pData)
15562 {
15563   mng_imagedatap pBuf     = (mng_imagedatap)pData->pPromBuf;
15564   mng_uint8p     pSrcline = (mng_uint8p)pData->pPromSrc;
15565   mng_uint8p     pDstline = (mng_uint8p)pData->pPromDst;
15566   mng_uint32     iX;
15567   mng_uint8      iB;
15568 
15569 #ifdef MNG_SUPPORT_TRACE
15570   MNG_TRACE (pData, MNG_FN_PROMOTE_IDX8_RGBA8, MNG_LC_START);
15571 #endif
15572 
15573 #ifdef MNG_DECREMENT_LOOPS
15574   for (iX = pData->iPromWidth; iX > 0; iX--)
15575 #else
15576   for (iX = 0; iX < pData->iPromWidth; iX++)
15577 #endif
15578   {
15579     iB = *pSrcline;
15580 
15581     if ((mng_uint32)iB < pBuf->iPLTEcount)
15582     {
15583       *pDstline       = pBuf->aPLTEentries [iB].iRed;
15584       *(pDstline+1)   = pBuf->aPLTEentries [iB].iGreen;
15585       *(pDstline+2)   = pBuf->aPLTEentries [iB].iBlue;
15586 
15587       if ((pBuf->bHasTRNS) && ((mng_uint32)iB < pBuf->iTRNScount))
15588         *(pDstline+3) = pBuf->aTRNSentries [iB];
15589       else
15590         *(pDstline+3) = 0xFF;
15591     }
15592 
15593     pSrcline++;
15594     pDstline += 4;
15595   }
15596 
15597 #ifdef MNG_SUPPORT_TRACE
15598   MNG_TRACE (pData, MNG_FN_PROMOTE_IDX8_RGBA8, MNG_LC_END);
15599 #endif
15600 
15601   return MNG_NOERROR;
15602 }
15603 
15604 /* ************************************************************************** */
15605 
15606 #ifndef MNG_NO_16BIT_SUPPORT
mng_promote_idx8_rgba16(mng_datap pData)15607 mng_retcode mng_promote_idx8_rgba16 (mng_datap pData)
15608 {
15609   mng_imagedatap pBuf     = (mng_imagedatap)pData->pPromBuf;
15610   mng_uint8p     pSrcline = (mng_uint8p)pData->pPromSrc;
15611   mng_uint8p     pDstline = (mng_uint8p)pData->pPromDst;
15612   mng_uint32     iX;
15613   mng_uint8      iN;
15614   mng_uint16     iR;
15615   mng_uint16     iG;
15616   mng_uint16     iB;
15617   mng_uint16     iA;
15618 
15619 #ifdef MNG_SUPPORT_TRACE
15620   MNG_TRACE (pData, MNG_FN_PROMOTE_IDX8_RGBA16, MNG_LC_START);
15621 #endif
15622 
15623 #ifdef MNG_DECREMENT_LOOPS
15624   for (iX = pData->iPromWidth; iX > 0; iX--)
15625 #else
15626   for (iX = 0; iX < pData->iPromWidth; iX++)
15627 #endif
15628   {
15629     iN = *pSrcline;
15630 
15631     if ((mng_uint32)iN < pBuf->iPLTEcount)
15632     {
15633       iR            = ((mng_bitdepth_16)pData->fPromBitdepth) (pBuf->aPLTEentries [iN].iRed);
15634       iG            = ((mng_bitdepth_16)pData->fPromBitdepth) (pBuf->aPLTEentries [iN].iGreen);
15635       iB            = ((mng_bitdepth_16)pData->fPromBitdepth) (pBuf->aPLTEentries [iN].iBlue);
15636 
15637       if ((pBuf->bHasTRNS) && ((mng_uint32)iN < pBuf->iTRNScount))
15638         iA          = ((mng_bitdepth_16)pData->fPromBitdepth) (pBuf->aTRNSentries [iN]);
15639       else
15640         iA          = 0xFFFF;
15641 
15642       *pDstline     = (mng_uint8)(iR >> 8);
15643       *(pDstline+1) = (mng_uint8)(iR && 0xFF);
15644       *(pDstline+2) = (mng_uint8)(iG >> 8);
15645       *(pDstline+3) = (mng_uint8)(iG && 0xFF);
15646       *(pDstline+4) = (mng_uint8)(iB >> 8);
15647       *(pDstline+5) = (mng_uint8)(iB && 0xFF);
15648       *(pDstline+6) = (mng_uint8)(iA >> 8);
15649       *(pDstline+7) = (mng_uint8)(iA && 0xFF);
15650     }
15651 
15652     pSrcline++;
15653     pDstline += 8;
15654   }
15655 
15656 #ifdef MNG_SUPPORT_TRACE
15657   MNG_TRACE (pData, MNG_FN_PROMOTE_IDX8_RGBA16, MNG_LC_END);
15658 #endif
15659 
15660   return MNG_NOERROR;
15661 }
15662 
15663 /* ************************************************************************** */
15664 
mng_promote_rgba8_rgba16(mng_datap pData)15665 mng_retcode mng_promote_rgba8_rgba16 (mng_datap pData)
15666 {
15667   mng_uint8p pSrcline = (mng_uint8p)pData->pPromSrc;
15668   mng_uint8p pDstline = (mng_uint8p)pData->pPromDst;
15669   mng_uint32 iX;
15670   mng_uint16 iR;
15671   mng_uint16 iG;
15672   mng_uint16 iB;
15673   mng_uint16 iA;
15674 
15675 #ifdef MNG_SUPPORT_TRACE
15676   MNG_TRACE (pData, MNG_FN_PROMOTE_RGBA8_RGBA16, MNG_LC_START);
15677 #endif
15678 
15679 #ifdef MNG_DECREMENT_LOOPS
15680   for (iX = pData->iPromWidth; iX > 0; iX--)
15681 #else
15682   for (iX = 0; iX < pData->iPromWidth; iX++)
15683 #endif
15684   {
15685     iR            = ((mng_bitdepth_16)pData->fPromBitdepth) (*pSrcline);
15686     iG            = ((mng_bitdepth_16)pData->fPromBitdepth) (*(pSrcline+1));
15687     iB            = ((mng_bitdepth_16)pData->fPromBitdepth) (*(pSrcline+2));
15688     iA            = ((mng_bitdepth_16)pData->fPromBitdepth) (*(pSrcline+3));
15689 
15690     *pDstline     = (mng_uint8)(iR >> 8);
15691     *(pDstline+1) = (mng_uint8)(iR && 0xFF);
15692     *(pDstline+2) = (mng_uint8)(iG >> 8);
15693     *(pDstline+3) = (mng_uint8)(iG && 0xFF);
15694     *(pDstline+4) = (mng_uint8)(iB >> 8);
15695     *(pDstline+5) = (mng_uint8)(iB && 0xFF);
15696     *(pDstline+6) = (mng_uint8)(iA >> 8);
15697     *(pDstline+7) = (mng_uint8)(iA && 0xFF);
15698 
15699     pSrcline += 4;
15700     pDstline += 8;
15701   }
15702 
15703 #ifdef MNG_SUPPORT_TRACE
15704   MNG_TRACE (pData, MNG_FN_PROMOTE_RGBA8_RGBA16, MNG_LC_END);
15705 #endif
15706 
15707   return MNG_NOERROR;
15708 }
15709 #endif
15710 #endif /* !defined(MNG_NO_DELTA_PNG) || !defined(MNG_SKIPCHUNK_PAST) || !defined(MNG_SKIPCHUNK_MAGN) */
15711 
15712 /* ************************************************************************** */
15713 /* *                                                                        * */
15714 /* * Row processing routines - convert uncompressed data from zlib to       * */
15715 /* * managable row-data which serves as input to the color-management       * */
15716 /* * routines                                                               * */
15717 /* *                                                                        * */
15718 /* ************************************************************************** */
15719 
15720 #ifndef MNG_NO_1_2_4BIT_SUPPORT
mng_process_g1(mng_datap pData)15721 mng_retcode mng_process_g1 (mng_datap pData)
15722 {
15723   mng_uint8p     pWorkrow;
15724   mng_uint8p     pRGBArow;
15725   mng_int32      iX;
15726   mng_uint8      iB;
15727   mng_uint8      iM;
15728   mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
15729 
15730 #ifdef MNG_SUPPORT_TRACE
15731   MNG_TRACE (pData, MNG_FN_PROCESS_G1, MNG_LC_START);
15732 #endif
15733 
15734   if (!pBuf)                           /* no object? then use obj 0 */
15735     pBuf = ((mng_imagep)pData->pObjzero)->pImgbuf;
15736                                        /* temporary work pointers */
15737   pWorkrow = pData->pWorkrow + pData->iPixelofs;
15738   pRGBArow = pData->pRGBArow;
15739   iM       = 0;                        /* start at pixel 0 */
15740   iB       = 0;
15741 
15742   if (pBuf->bHasTRNS)                  /* tRNS encountered ? */
15743   {
15744     if (pBuf->iTRNSgray)               /* white transparent ? */
15745     {
15746 #ifdef MNG_DECREMENT_LOOPS
15747       for (iX = pData->iRowsamples; iX > 0; iX--)
15748 #else
15749       for (iX = 0; iX < pData->iRowsamples; iX++)
15750 #endif
15751       {
15752         if (!iM)                       /* mask underflow ? */
15753         {
15754           iB = *pWorkrow;              /* get next input-byte */
15755           pWorkrow++;
15756           iM = 0x80;
15757         }
15758 
15759         if (iB & iM)                   /* is it white ? */
15760                                        /* transparent ! */
15761           mng_put_uint32 (pRGBArow, 0x00000000);
15762         else                           /* opaque black */
15763           mng_put_uint32 (pRGBArow, 0x000000FF);
15764 
15765         pRGBArow += 4;                 /* next pixel */
15766         iM >>=  1;
15767       }
15768     }
15769     else                               /* black transparent */
15770     {
15771 #ifdef MNG_DECREMENT_LOOPS
15772       for (iX = pData->iRowsamples; iX > 0; iX--)
15773 #else
15774       for (iX = 0; iX < pData->iRowsamples; iX++)
15775 #endif
15776       {
15777         if (!iM)                       /* mask underflow ? */
15778         {
15779           iB = *pWorkrow;              /* get next input-byte */
15780           pWorkrow++;
15781           iM = 0x80;
15782         }
15783 
15784         if (iB & iM)                   /* is it white ? */
15785                                        /* opaque white */
15786           mng_put_uint32 (pRGBArow, 0xFFFFFFFF);
15787         else                           /* transparent */
15788           mng_put_uint32 (pRGBArow, 0x00000000);
15789 
15790         pRGBArow += 4;                 /* next pixel */
15791         iM >>=  1;
15792       }
15793     }
15794 
15795     pData->bIsOpaque = MNG_FALSE;      /* it's not fully opaque */
15796   }
15797   else                                 /* no transparency */
15798   {
15799 #ifdef MNG_DECREMENT_LOOPS
15800     for (iX = pData->iRowsamples; iX > 0; iX--)
15801 #else
15802     for (iX = 0; iX < pData->iRowsamples; iX++)
15803 #endif
15804     {
15805       if (!iM)                         /* mask underflow ? */
15806       {
15807         iB = *pWorkrow;                /* get next input-byte */
15808         pWorkrow++;
15809         iM = 0x80;
15810       }
15811 
15812       if (iB & iM)                     /* is it white ? */
15813                                        /* opaque white */
15814         mng_put_uint32 (pRGBArow, 0xFFFFFFFF);
15815       else                             /* opaque black */
15816         mng_put_uint32 (pRGBArow, 0x000000FF);
15817 
15818       pRGBArow += 4;                   /* next pixel */
15819       iM >>=  1;
15820     }
15821 
15822     pData->bIsOpaque = MNG_TRUE;       /* it's fully opaque */
15823   }
15824 
15825 #ifdef MNG_SUPPORT_TRACE
15826   MNG_TRACE (pData, MNG_FN_PROCESS_G1, MNG_LC_END);
15827 #endif
15828 
15829   return MNG_NOERROR;
15830 }
15831 
15832 /* ************************************************************************** */
15833 
mng_process_g2(mng_datap pData)15834 mng_retcode mng_process_g2 (mng_datap pData)
15835 {
15836   mng_uint8p     pWorkrow;
15837   mng_uint8p     pRGBArow;
15838   mng_int32      iX;
15839   mng_uint8      iB;
15840   mng_uint8      iM;
15841   mng_uint32     iS;
15842   mng_uint8      iQ;
15843   mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
15844 #ifdef MNG_OPTIMIZE_FOOTPRINT_SWITCH
15845   const mng_uint32  level[4] = { 0x000000FF, 0x555555FF,
15846           0xAAAAAAFF, 0xFFFFFFFF};
15847 #endif
15848 
15849 #ifdef MNG_SUPPORT_TRACE
15850   MNG_TRACE (pData, MNG_FN_PROCESS_G2, MNG_LC_START);
15851 #endif
15852 
15853   if (!pBuf)                           /* no object? then use obj 0 */
15854     pBuf = ((mng_imagep)pData->pObjzero)->pImgbuf;
15855                                        /* temporary work pointers */
15856   pWorkrow = pData->pWorkrow + pData->iPixelofs;
15857   pRGBArow = pData->pRGBArow;
15858   iM       = 0;                        /* start at pixel 0 */
15859   iB       = 0;
15860   iS       = 0;
15861 
15862   if (pBuf->bHasTRNS)                  /* tRNS encountered ? */
15863   {
15864 #ifdef MNG_DECREMENT_LOOPS
15865     for (iX = pData->iRowsamples; iX > 0; iX--)
15866 #else
15867     for (iX = 0; iX < pData->iRowsamples; iX++)
15868 #endif
15869     {
15870       if (!iM)                         /* mask underflow ? */
15871       {
15872         iB = *pWorkrow;                /* get next input-byte */
15873         pWorkrow++;
15874         iM = 0xC0;
15875         iS = 6;
15876       }
15877                                        /* determine gray level */
15878       iQ = (mng_uint8)((iB & iM) >> iS);
15879 
15880       if (iQ == pBuf->iTRNSgray)       /* transparent ? */
15881         mng_put_uint32 (pRGBArow, 0x00000000);
15882       else
15883       {
15884 #ifdef MNG_OPTIMIZE_FOOTPRINT_SWITCH
15885         mng_put_uint32 (pRGBArow, level[iQ]);
15886 #else
15887         switch (iQ)                    /* determine the gray level */
15888         {
15889           case 0x03 : { mng_put_uint32 (pRGBArow, 0xFFFFFFFF); break; }
15890           case 0x02 : { mng_put_uint32 (pRGBArow, 0xAAAAAAFF); break; }
15891           case 0x01 : { mng_put_uint32 (pRGBArow, 0x555555FF); break; }
15892           default   : { mng_put_uint32 (pRGBArow, 0x000000FF); }
15893         }
15894 #endif
15895       }
15896 
15897       pRGBArow += 4;                   /* next pixel */
15898       iM >>=  2;
15899       iS -= 2;
15900     }
15901 
15902     pData->bIsOpaque = MNG_FALSE;      /* it's not fully opaque */
15903   }
15904   else
15905   {
15906 #ifdef MNG_DECREMENT_LOOPS
15907     for (iX = pData->iRowsamples; iX > 0; iX--)
15908 #else
15909     for (iX = 0; iX < pData->iRowsamples; iX++)
15910 #endif
15911     {
15912       if (!iM)                         /* mask underflow ? */
15913       {
15914         iB = *pWorkrow;                /* get next input-byte */
15915         pWorkrow++;
15916         iM = 0xC0;
15917         iS = 6;
15918       }
15919 
15920 #ifdef MNG_OPTIMIZE_FOOTPRINT_SWITCH
15921       mng_put_uint32 (pRGBArow, level[((iB & iM) >> iS)] );
15922 #else
15923       switch ((iB & iM) >> iS)         /* determine the gray level */
15924       {
15925         case 0x03 : { mng_put_uint32 (pRGBArow, 0xFFFFFFFF); break; }
15926         case 0x02 : { mng_put_uint32 (pRGBArow, 0xAAAAAAFF); break; }
15927         case 0x01 : { mng_put_uint32 (pRGBArow, 0x555555FF); break; }
15928         default   : { mng_put_uint32 (pRGBArow, 0x000000FF); }
15929       }
15930 #endif
15931 
15932       pRGBArow += 4;                   /* next pixel */
15933       iM >>=  2;
15934       iS -= 2;
15935     }
15936 
15937     pData->bIsOpaque = MNG_TRUE;       /* it's fully opaque */
15938   }
15939 
15940 #ifdef MNG_SUPPORT_TRACE
15941   MNG_TRACE (pData, MNG_FN_PROCESS_G2, MNG_LC_END);
15942 #endif
15943 
15944   return MNG_NOERROR;
15945 }
15946 
15947 /* ************************************************************************** */
15948 
mng_process_g4(mng_datap pData)15949 mng_retcode mng_process_g4 (mng_datap pData)
15950 {
15951   mng_uint8p     pWorkrow;
15952   mng_uint8p     pRGBArow;
15953   mng_int32      iX;
15954   mng_uint8      iB;
15955   mng_uint8      iM;
15956   mng_uint32     iS;
15957   mng_uint8      iQ;
15958   mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
15959 
15960 #ifdef MNG_SUPPORT_TRACE
15961   MNG_TRACE (pData, MNG_FN_PROCESS_G4, MNG_LC_START);
15962 #endif
15963 
15964   if (!pBuf)                           /* no object? then use obj 0 */
15965     pBuf = ((mng_imagep)pData->pObjzero)->pImgbuf;
15966                                        /* temporary work pointers */
15967   pWorkrow = pData->pWorkrow + pData->iPixelofs;
15968   pRGBArow = pData->pRGBArow;
15969   iM       = 0;                        /* start at pixel 0 */
15970   iB       = 0;
15971   iS       = 0;
15972 
15973   if (pBuf->bHasTRNS)                  /* tRNS encountered ? */
15974   {
15975 #ifdef MNG_DECREMENT_LOOPS
15976     for (iX = pData->iRowsamples; iX > 0; iX--)
15977 #else
15978     for (iX = 0; iX < pData->iRowsamples; iX++)
15979 #endif
15980     {
15981       if (!iM)                         /* mask underflow ? */
15982       {
15983         iB = *pWorkrow;                /* get next input-byte */
15984         pWorkrow++;
15985         iM = 0xF0;
15986         iS = 4;
15987       }
15988                                        /* get the gray level */
15989       iQ = (mng_uint8)((iB & iM) >> iS);
15990 
15991       if (iQ == pBuf->iTRNSgray)       /* transparent ? */
15992       {
15993         *pRGBArow     = 0;             /* put in intermediate row */
15994         *(pRGBArow+1) = 0;
15995         *(pRGBArow+2) = 0;
15996         *(pRGBArow+3) = 0;
15997       }
15998       else
15999       {                                /* expand to 8-bit by replication */
16000         iQ = (mng_uint8)(iQ + (iQ << 4));
16001 
16002         *pRGBArow     = iQ;            /* put in intermediate row */
16003         *(pRGBArow+1) = iQ;
16004         *(pRGBArow+2) = iQ;
16005         *(pRGBArow+3) = 0xFF;
16006       }
16007 
16008       pRGBArow += 4;                   /* next pixel */
16009       iM >>=  4;
16010       iS -= 4;
16011     }
16012 
16013     pData->bIsOpaque = MNG_FALSE;      /* it's not fully opaque */
16014   }
16015   else
16016   {
16017 #ifdef MNG_DECREMENT_LOOPS
16018     for (iX = pData->iRowsamples; iX > 0; iX--)
16019 #else
16020     for (iX = 0; iX < pData->iRowsamples; iX++)
16021 #endif
16022     {
16023       if (!iM)                         /* mask underflow ? */
16024       {
16025         iB = *pWorkrow;                /* get next input-byte */
16026         pWorkrow++;
16027         iM = 0xF0;
16028         iS = 4;
16029       }
16030                                        /* get the gray level */
16031       iQ = (mng_uint8)((iB & iM) >> iS);
16032       iQ = (mng_uint8)(iQ + (iQ << 4));/* expand to 8-bit by replication */
16033 
16034       *pRGBArow     = iQ;              /* put in intermediate row */
16035       *(pRGBArow+1) = iQ;
16036       *(pRGBArow+2) = iQ;
16037       *(pRGBArow+3) = 0xFF;
16038 
16039       pRGBArow += 4;                   /* next pixel */
16040       iM >>=  4;
16041       iS -= 4;
16042     }
16043 
16044     pData->bIsOpaque = MNG_TRUE;       /* it's fully opaque */
16045   }
16046 
16047 #ifdef MNG_SUPPORT_TRACE
16048   MNG_TRACE (pData, MNG_FN_PROCESS_G4, MNG_LC_END);
16049 #endif
16050 
16051   return MNG_NOERROR;
16052 }
16053 #endif /* MNG_NO_1_2_4BIT_SUPPORT */
16054 
16055 /* ************************************************************************** */
16056 
mng_process_g8(mng_datap pData)16057 mng_retcode mng_process_g8 (mng_datap pData)
16058 {
16059   mng_uint8p     pWorkrow;
16060   mng_uint8p     pRGBArow;
16061   mng_int32      iX;
16062   mng_uint8      iB;
16063   mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
16064 
16065 #ifdef MNG_SUPPORT_TRACE
16066   MNG_TRACE (pData, MNG_FN_PROCESS_G8, MNG_LC_START);
16067 #endif
16068 
16069   if (!pBuf)                           /* no object? then use obj 0 */
16070     pBuf = ((mng_imagep)pData->pObjzero)->pImgbuf;
16071                                        /* temporary work pointers */
16072   pWorkrow = pData->pWorkrow + pData->iPixelofs;
16073   pRGBArow = pData->pRGBArow;
16074 
16075   if (pBuf->bHasTRNS)                  /* tRNS encountered ? */
16076   {
16077 #ifdef MNG_DECREMENT_LOOPS
16078     for (iX = pData->iRowsamples; iX > 0; iX--)
16079 #else
16080     for (iX = 0; iX < pData->iRowsamples; iX++)
16081 #endif
16082     {
16083       iB = *pWorkrow;                  /* get next input-byte */
16084 
16085       if (iB == pBuf->iTRNSgray)       /* transparent ? */
16086       {
16087         *pRGBArow     = 0;             /* put in intermediate row */
16088         *(pRGBArow+1) = 0;
16089         *(pRGBArow+2) = 0;
16090         *(pRGBArow+3) = 0;
16091       }
16092       else
16093       {
16094         *pRGBArow     = iB;            /* put in intermediate row */
16095         *(pRGBArow+1) = iB;
16096         *(pRGBArow+2) = iB;
16097         *(pRGBArow+3) = 0xFF;
16098       }
16099 
16100       pRGBArow += 4;                   /* next pixel */
16101       pWorkrow++;
16102     }
16103 
16104     pData->bIsOpaque = MNG_FALSE;      /* it's not fully opaque */
16105   }
16106   else
16107   {
16108 #ifdef MNG_DECREMENT_LOOPS
16109     for (iX = pData->iRowsamples; iX > 0; iX--)
16110 #else
16111     for (iX = 0; iX < pData->iRowsamples; iX++)
16112 #endif
16113     {
16114       iB = *pWorkrow;                  /* get next input-byte */
16115 
16116       *pRGBArow     = iB;              /* put in intermediate row */
16117       *(pRGBArow+1) = iB;
16118       *(pRGBArow+2) = iB;
16119       *(pRGBArow+3) = 0xFF;
16120 
16121       pRGBArow += 4;                   /* next pixel */
16122       pWorkrow++;
16123     }
16124 
16125     pData->bIsOpaque = MNG_TRUE;       /* it's fully opaque */
16126   }
16127 
16128 #ifdef MNG_SUPPORT_TRACE
16129   MNG_TRACE (pData, MNG_FN_PROCESS_G8, MNG_LC_END);
16130 #endif
16131 
16132   return MNG_NOERROR;
16133 }
16134 
16135 /* ************************************************************************** */
16136 
16137 #ifndef MNG_NO_16BIT_SUPPORT
mng_process_g16(mng_datap pData)16138 mng_retcode mng_process_g16 (mng_datap pData)
16139 {
16140   mng_uint8p     pWorkrow;
16141   mng_uint8p     pRGBArow;
16142   mng_int32      iX;
16143   mng_uint16     iW;
16144   mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
16145 
16146 #ifdef MNG_SUPPORT_TRACE
16147   MNG_TRACE (pData, MNG_FN_PROCESS_G16, MNG_LC_START);
16148 #endif
16149 
16150   if (!pBuf)                           /* no object? then use obj 0 */
16151     pBuf = ((mng_imagep)pData->pObjzero)->pImgbuf;
16152                                        /* temporary work pointers */
16153   pWorkrow = pData->pWorkrow + pData->iPixelofs;
16154   pRGBArow = pData->pRGBArow;
16155 
16156   if (pBuf->bHasTRNS)                  /* tRNS encountered ? */
16157   {
16158 #ifdef MNG_DECREMENT_LOOPS
16159     for (iX = pData->iRowsamples; iX > 0; iX--)
16160 #else
16161     for (iX = 0; iX < pData->iRowsamples; iX++)
16162 #endif
16163     {
16164       iW = mng_get_uint16 (pWorkrow);  /* get input */
16165 
16166       if (iW == pBuf->iTRNSgray)       /* transparent ? */
16167       {                                /* put in intermediate row */
16168         mng_put_uint16 (pRGBArow,   0);
16169         mng_put_uint16 (pRGBArow+2, 0);
16170         mng_put_uint16 (pRGBArow+4, 0);
16171         mng_put_uint16 (pRGBArow+6, 0);
16172       }
16173       else
16174       {                                /* put in intermediate row */
16175         mng_put_uint16 (pRGBArow,   iW);
16176         mng_put_uint16 (pRGBArow+2, iW);
16177         mng_put_uint16 (pRGBArow+4, iW);
16178         mng_put_uint16 (pRGBArow+6, 0xFFFF);
16179       }
16180 
16181       pRGBArow += 8;                   /* next pixel */
16182       pWorkrow += 2;
16183     }
16184 
16185     pData->bIsOpaque = MNG_FALSE;      /* it's not fully opaque */
16186   }
16187   else
16188   {
16189 #ifdef MNG_DECREMENT_LOOPS
16190     for (iX = pData->iRowsamples; iX > 0; iX--)
16191 #else
16192     for (iX = 0; iX < pData->iRowsamples; iX++)
16193 #endif
16194     {
16195       iW = mng_get_uint16 (pWorkrow);  /* get input */
16196 
16197       mng_put_uint16 (pRGBArow,   iW); /* and put in intermediate row */
16198       mng_put_uint16 (pRGBArow+2, iW);
16199       mng_put_uint16 (pRGBArow+4, iW);
16200       mng_put_uint16 (pRGBArow+6, 0xFFFF);
16201 
16202       pRGBArow += 8;                   /* next pixel */
16203       pWorkrow += 2;
16204     }
16205 
16206     pData->bIsOpaque = MNG_TRUE;       /* it's fully opaque */
16207   }
16208 
16209 #ifdef MNG_SUPPORT_TRACE
16210   MNG_TRACE (pData, MNG_FN_PROCESS_G16, MNG_LC_END);
16211 #endif
16212 
16213   return MNG_NOERROR;
16214 }
16215 #endif
16216 
16217 /* ************************************************************************** */
16218 
mng_process_rgb8(mng_datap pData)16219 mng_retcode mng_process_rgb8 (mng_datap pData)
16220 {
16221   mng_uint8p     pWorkrow;
16222   mng_uint8p     pRGBArow;
16223   mng_int32      iX;
16224   mng_uint8      iR, iG, iB;
16225   mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
16226 
16227 #ifdef MNG_SUPPORT_TRACE
16228   MNG_TRACE (pData, MNG_FN_PROCESS_RGB8, MNG_LC_START);
16229 #endif
16230 
16231   if (!pBuf)                           /* no object? then use obj 0 */
16232     pBuf = ((mng_imagep)pData->pObjzero)->pImgbuf;
16233                                        /* temporary work pointers */
16234   pWorkrow = pData->pWorkrow + pData->iPixelofs;
16235   pRGBArow = pData->pRGBArow;
16236 
16237   if (pBuf->bHasTRNS)                  /* tRNS encountered ? */
16238   {
16239 #ifdef MNG_DECREMENT_LOOPS
16240     for (iX = pData->iRowsamples; iX > 0; iX--)
16241 #else
16242     for (iX = 0; iX < pData->iRowsamples; iX++)
16243 #endif
16244     {
16245       iR = *pWorkrow;                  /* get the RGB values */
16246       iG = *(pWorkrow+1);
16247       iB = *(pWorkrow+2);
16248                                        /* transparent ? */
16249       if ((iR == pBuf->iTRNSred) && (iG == pBuf->iTRNSgreen) &&
16250           (iB == pBuf->iTRNSblue))
16251       {
16252         *pRGBArow     = 0;             /* this pixel is transparent ! */
16253         *(pRGBArow+1) = 0;
16254         *(pRGBArow+2) = 0;
16255         *(pRGBArow+3) = 0;
16256       }
16257       else
16258       {
16259         *pRGBArow     = iR;            /* copy the RGB values */
16260         *(pRGBArow+1) = iG;
16261         *(pRGBArow+2) = iB;
16262         *(pRGBArow+3) = 0xFF;          /* this one isn't transparent */
16263       }
16264 
16265       pWorkrow += 3;                   /* next pixel */
16266       pRGBArow += 4;
16267     }
16268 
16269     pData->bIsOpaque = MNG_FALSE;      /* it's not fully opaque */
16270   }
16271   else
16272   {
16273 #ifdef MNG_DECREMENT_LOOPS
16274     for (iX = pData->iRowsamples; iX > 0; iX--)
16275 #else
16276     for (iX = 0; iX < pData->iRowsamples; iX++)
16277 #endif
16278     {
16279       *pRGBArow     = *pWorkrow;       /* copy the RGB bytes */
16280       *(pRGBArow+1) = *(pWorkrow+1);
16281       *(pRGBArow+2) = *(pWorkrow+2);
16282       *(pRGBArow+3) = 0xFF;            /* no alpha; so always fully opaque */
16283 
16284       pWorkrow += 3;                   /* next pixel */
16285       pRGBArow += 4;
16286     }
16287 
16288     pData->bIsOpaque = MNG_TRUE;       /* it's fully opaque */
16289   }
16290 
16291 #ifdef MNG_SUPPORT_TRACE
16292   MNG_TRACE (pData, MNG_FN_PROCESS_RGB8, MNG_LC_END);
16293 #endif
16294 
16295   return MNG_NOERROR;
16296 }
16297 
16298 /* ************************************************************************** */
16299 
16300 #ifndef MNG_NO_16BIT_SUPPORT
mng_process_rgb16(mng_datap pData)16301 mng_retcode mng_process_rgb16 (mng_datap pData)
16302 {
16303   mng_uint8p     pWorkrow;
16304   mng_uint8p     pRGBArow;
16305   mng_int32      iX;
16306   mng_uint16     iR, iG, iB;
16307   mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
16308 
16309 #ifdef MNG_SUPPORT_TRACE
16310   MNG_TRACE (pData, MNG_FN_PROCESS_RGB16, MNG_LC_START);
16311 #endif
16312 
16313   if (!pBuf)                           /* no object? then use obj 0 */
16314     pBuf = ((mng_imagep)pData->pObjzero)->pImgbuf;
16315                                        /* temporary work pointers */
16316   pWorkrow = pData->pWorkrow + pData->iPixelofs;
16317   pRGBArow = pData->pRGBArow;
16318 
16319   if (pBuf->bHasTRNS)                  /* tRNS encountered ? */
16320   {
16321 #ifdef MNG_DECREMENT_LOOPS
16322     for (iX = pData->iRowsamples; iX > 0; iX--)
16323 #else
16324     for (iX = 0; iX < pData->iRowsamples; iX++)
16325 #endif
16326     {
16327       iR = mng_get_uint16 (pWorkrow);  /* get the RGB values */
16328       iG = mng_get_uint16 (pWorkrow+2);
16329       iB = mng_get_uint16 (pWorkrow+4);
16330                                        /* transparent ? */
16331       if ((iR == pBuf->iTRNSred) && (iG == pBuf->iTRNSgreen) &&
16332           (iB == pBuf->iTRNSblue))
16333       {                                /* transparent then */
16334         mng_put_uint16 (pRGBArow,   0);
16335         mng_put_uint16 (pRGBArow+2, 0);
16336         mng_put_uint16 (pRGBArow+4, 0);
16337         mng_put_uint16 (pRGBArow+6, 0);
16338       }
16339       else
16340       {                                /* put in intermediate row */
16341         mng_put_uint16 (pRGBArow,   iR);
16342         mng_put_uint16 (pRGBArow+2, iG);
16343         mng_put_uint16 (pRGBArow+4, iB);
16344         mng_put_uint16 (pRGBArow+6, 0xFFFF);
16345       }
16346 
16347       pWorkrow += 6;                   /* next pixel */
16348       pRGBArow += 8;
16349     }
16350 
16351     pData->bIsOpaque = MNG_FALSE;      /* it's not fully opaque */
16352   }
16353   else
16354   {
16355 #ifdef MNG_DECREMENT_LOOPS
16356     for (iX = pData->iRowsamples; iX > 0; iX--)
16357 #else
16358     for (iX = 0; iX < pData->iRowsamples; iX++)
16359 #endif
16360     {                                  /* copy the RGB values */
16361       mng_put_uint16 (pRGBArow,   mng_get_uint16 (pWorkrow  ));
16362       mng_put_uint16 (pRGBArow+2, mng_get_uint16 (pWorkrow+2));
16363       mng_put_uint16 (pRGBArow+4, mng_get_uint16 (pWorkrow+4));
16364       mng_put_uint16 (pRGBArow+6, 0xFFFF);
16365 
16366       pWorkrow += 6;                   /* next pixel */
16367       pRGBArow += 8;
16368     }
16369 
16370     pData->bIsOpaque = MNG_TRUE;       /* it's fully opaque */
16371   }
16372 
16373 #ifdef MNG_SUPPORT_TRACE
16374   MNG_TRACE (pData, MNG_FN_PROCESS_RGB16, MNG_LC_END);
16375 #endif
16376 
16377   return MNG_NOERROR;
16378 }
16379 #endif
16380 
16381 /* ************************************************************************** */
16382 
16383 #ifndef MNG_NO_1_2_4BIT_SUPPORT
mng_process_idx1(mng_datap pData)16384 mng_retcode mng_process_idx1 (mng_datap pData)
16385 {
16386   mng_uint8p     pWorkrow;
16387   mng_uint8p     pRGBArow;
16388   mng_int32      iX;
16389   mng_uint8      iB;
16390   mng_uint8      iM;
16391   mng_uint32     iS;
16392   mng_uint8      iQ;
16393   mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
16394 
16395 #ifdef MNG_SUPPORT_TRACE
16396   MNG_TRACE (pData, MNG_FN_PROCESS_IDX1, MNG_LC_START);
16397 #endif
16398 
16399   if (!pBuf)                           /* no object? then use obj 0 */
16400     pBuf = ((mng_imagep)pData->pObjzero)->pImgbuf;
16401                                        /* temporary work pointers */
16402   pWorkrow = pData->pWorkrow + pData->iPixelofs;
16403   pRGBArow = pData->pRGBArow;
16404   iM       = 0;                        /* start at pixel 0 */
16405   iB       = 0;
16406   iS       = 0;
16407 
16408   if (pBuf->bHasTRNS)                  /* tRNS encountered ? */
16409   {
16410 #ifdef MNG_DECREMENT_LOOPS
16411     for (iX = pData->iRowsamples; iX > 0; iX--)
16412 #else
16413     for (iX = 0; iX < pData->iRowsamples; iX++)
16414 #endif
16415     {
16416       if (!iM)                         /* mask underflow ? */
16417       {
16418         iB = *pWorkrow;                /* get next input-byte */
16419         pWorkrow++;
16420         iM = 0x80;
16421         iS = 7;
16422       }
16423                                        /* get the index */
16424       iQ = (mng_uint8)((iB & iM) >> iS);
16425                                        /* index valid ? */
16426       if ((mng_uint32)iQ < pBuf->iPLTEcount)
16427       {                                /* put in intermediate row */
16428         *pRGBArow     = pBuf->aPLTEentries [iQ].iRed;
16429         *(pRGBArow+1) = pBuf->aPLTEentries [iQ].iGreen;
16430         *(pRGBArow+2) = pBuf->aPLTEentries [iQ].iBlue;
16431                                        /* transparency for this index ? */
16432         if ((mng_uint32)iQ < pBuf->iTRNScount)
16433           *(pRGBArow+3) = pBuf->aTRNSentries [iQ];
16434         else
16435           *(pRGBArow+3) = 0xFF;
16436       }
16437       else
16438         MNG_ERROR (pData, MNG_PLTEINDEXERROR);
16439 
16440       pRGBArow += 4;                   /* next pixel */
16441       iM >>=  1;
16442       iS -= 1;
16443     }
16444 
16445     pData->bIsOpaque = MNG_FALSE;      /* it's not fully opaque */
16446   }
16447   else
16448   {
16449 #ifdef MNG_DECREMENT_LOOPS
16450     for (iX = pData->iRowsamples; iX > 0; iX--)
16451 #else
16452     for (iX = 0; iX < pData->iRowsamples; iX++)
16453 #endif
16454     {
16455       if (!iM)                         /* mask underflow ? */
16456       {
16457         iB = *pWorkrow;                /* get next input-byte */
16458         pWorkrow++;
16459         iM = 0x80;
16460         iS = 7;
16461       }
16462                                        /* get the index */
16463       iQ = (mng_uint8)((iB & iM) >> iS);
16464                                        /* index valid ? */
16465       if ((mng_uint32)iQ < pBuf->iPLTEcount)
16466       {                                /* put in intermediate row */
16467         *pRGBArow     = pBuf->aPLTEentries [iQ].iRed;
16468         *(pRGBArow+1) = pBuf->aPLTEentries [iQ].iGreen;
16469         *(pRGBArow+2) = pBuf->aPLTEentries [iQ].iBlue;
16470         *(pRGBArow+3) = 0xFF;
16471       }
16472       else
16473         MNG_ERROR (pData, MNG_PLTEINDEXERROR);
16474 
16475       pRGBArow += 4;                   /* next pixel */
16476       iM >>=  1;
16477       iS -= 1;
16478     }
16479 
16480     pData->bIsOpaque = MNG_TRUE;       /* it's fully opaque */
16481   }
16482 
16483 #ifdef MNG_SUPPORT_TRACE
16484   MNG_TRACE (pData, MNG_FN_PROCESS_IDX1, MNG_LC_END);
16485 #endif
16486 
16487   return MNG_NOERROR;
16488 }
16489 
16490 /* ************************************************************************** */
16491 
mng_process_idx2(mng_datap pData)16492 mng_retcode mng_process_idx2 (mng_datap pData)
16493 {
16494   mng_uint8p     pWorkrow;
16495   mng_uint8p     pRGBArow;
16496   mng_int32      iX;
16497   mng_uint8      iB;
16498   mng_uint8      iM;
16499   mng_uint32     iS;
16500   mng_uint8      iQ;
16501   mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
16502 
16503 #ifdef MNG_SUPPORT_TRACE
16504   MNG_TRACE (pData, MNG_FN_PROCESS_IDX2, MNG_LC_START);
16505 #endif
16506 
16507   if (!pBuf)                           /* no object? then use obj 0 */
16508     pBuf = ((mng_imagep)pData->pObjzero)->pImgbuf;
16509                                        /* temporary work pointers */
16510   pWorkrow = pData->pWorkrow + pData->iPixelofs;
16511   pRGBArow = pData->pRGBArow;
16512   iM       = 0;                        /* start at pixel 0 */
16513   iB       = 0;
16514   iS       = 0;
16515 
16516   if (pBuf->bHasTRNS)                  /* tRNS encountered ? */
16517   {
16518 #ifdef MNG_DECREMENT_LOOPS
16519     for (iX = pData->iRowsamples; iX > 0; iX--)
16520 #else
16521     for (iX = 0; iX < pData->iRowsamples; iX++)
16522 #endif
16523     {
16524       if (!iM)                         /* mask underflow ? */
16525       {
16526         iB = *pWorkrow;                /* get next input-byte */
16527         pWorkrow++;
16528         iM = 0xC0;
16529         iS = 6;
16530       }
16531                                        /* get the index */
16532       iQ = (mng_uint8)((iB & iM) >> iS);
16533                                        /* index valid ? */
16534       if ((mng_uint32)iQ < pBuf->iPLTEcount)
16535       {                                /* put in intermediate row */
16536         *pRGBArow     = pBuf->aPLTEentries [iQ].iRed;
16537         *(pRGBArow+1) = pBuf->aPLTEentries [iQ].iGreen;
16538         *(pRGBArow+2) = pBuf->aPLTEentries [iQ].iBlue;
16539                                        /* transparency for this index ? */
16540         if ((mng_uint32)iQ < pBuf->iTRNScount)
16541           *(pRGBArow+3) = pBuf->aTRNSentries [iQ];
16542         else
16543           *(pRGBArow+3) = 0xFF;
16544       }
16545       else
16546         MNG_ERROR (pData, MNG_PLTEINDEXERROR);
16547 
16548       pRGBArow += 4;                   /* next pixel */
16549       iM >>=  2;
16550       iS -= 2;
16551     }
16552 
16553     pData->bIsOpaque = MNG_FALSE;      /* it's not fully opaque */
16554   }
16555   else
16556   {
16557 #ifdef MNG_DECREMENT_LOOPS
16558     for (iX = pData->iRowsamples; iX > 0; iX--)
16559 #else
16560     for (iX = 0; iX < pData->iRowsamples; iX++)
16561 #endif
16562     {
16563       if (!iM)                         /* mask underflow ? */
16564       {
16565         iB = *pWorkrow;                /* get next input-byte */
16566         pWorkrow++;
16567         iM = 0xC0;
16568         iS = 6;
16569       }
16570                                        /* get the index */
16571       iQ = (mng_uint8)((iB & iM) >> iS);
16572                                        /* index valid ? */
16573       if ((mng_uint32)iQ < pBuf->iPLTEcount)
16574       {                                /* put in intermediate row */
16575         *pRGBArow     = pBuf->aPLTEentries [iQ].iRed;
16576         *(pRGBArow+1) = pBuf->aPLTEentries [iQ].iGreen;
16577         *(pRGBArow+2) = pBuf->aPLTEentries [iQ].iBlue;
16578         *(pRGBArow+3) = 0xFF;
16579       }
16580       else
16581         MNG_ERROR (pData, MNG_PLTEINDEXERROR);
16582 
16583       pRGBArow += 4;                   /* next pixel */
16584       iM >>=  2;
16585       iS -= 2;
16586     }
16587 
16588     pData->bIsOpaque = MNG_TRUE;       /* it's fully opaque */
16589   }
16590 
16591 #ifdef MNG_SUPPORT_TRACE
16592   MNG_TRACE (pData, MNG_FN_PROCESS_IDX2, MNG_LC_END);
16593 #endif
16594 
16595   return MNG_NOERROR;
16596 }
16597 
16598 /* ************************************************************************** */
16599 
mng_process_idx4(mng_datap pData)16600 mng_retcode mng_process_idx4 (mng_datap pData)
16601 {
16602   mng_uint8p     pWorkrow;
16603   mng_uint8p     pRGBArow;
16604   mng_int32      iX;
16605   mng_uint8      iB;
16606   mng_uint8      iM;
16607   mng_uint32     iS;
16608   mng_uint8      iQ;
16609   mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
16610 
16611 #ifdef MNG_SUPPORT_TRACE
16612   MNG_TRACE (pData, MNG_FN_PROCESS_IDX4, MNG_LC_START);
16613 #endif
16614 
16615   if (!pBuf)                           /* no object? then use obj 0 */
16616     pBuf = ((mng_imagep)pData->pObjzero)->pImgbuf;
16617                                        /* temporary work pointers */
16618   pWorkrow = pData->pWorkrow + pData->iPixelofs;
16619   pRGBArow = pData->pRGBArow;
16620   iM       = 0;                        /* start at pixel 0 */
16621   iB       = 0;
16622   iS       = 0;
16623 
16624   if (pBuf->bHasTRNS)                  /* tRNS encountered ? */
16625   {
16626 #ifdef MNG_DECREMENT_LOOPS
16627     for (iX = pData->iRowsamples; iX > 0; iX--)
16628 #else
16629     for (iX = 0; iX < pData->iRowsamples; iX++)
16630 #endif
16631     {
16632       if (!iM)                         /* mask underflow ? */
16633       {
16634         iB = pWorkrow [0];             /* get next input-byte */
16635         pWorkrow++;
16636         iM = 0xF0;
16637         iS = 4;
16638       }
16639                                        /* get the index */
16640       iQ = (mng_uint8)((iB & iM) >> iS);
16641                                        /* index valid ? */
16642       if ((mng_uint32)iQ < pBuf->iPLTEcount)
16643       {                                /* put in intermediate row */
16644         pRGBArow [0] = pBuf->aPLTEentries [iQ].iRed;
16645         pRGBArow [1] = pBuf->aPLTEentries [iQ].iGreen;
16646         pRGBArow [2] = pBuf->aPLTEentries [iQ].iBlue;
16647                                        /* transparency for this index ? */
16648         if ((mng_uint32)iQ < pBuf->iTRNScount)
16649           pRGBArow [3] = pBuf->aTRNSentries [iQ];
16650         else
16651           pRGBArow [3] = 0xFF;
16652       }
16653       else
16654         MNG_ERROR (pData, MNG_PLTEINDEXERROR);
16655 
16656       pRGBArow += 4;                   /* next pixel */
16657       iM >>=  4;
16658       iS -= 4;
16659     }
16660 
16661     pData->bIsOpaque = MNG_FALSE;      /* it's not fully opaque */
16662   }
16663   else
16664   {
16665 #ifdef MNG_DECREMENT_LOOPS
16666     for (iX = pData->iRowsamples; iX > 0; iX--)
16667 #else
16668     for (iX = 0; iX < pData->iRowsamples; iX++)
16669 #endif
16670     {
16671       if (!iM)                         /* mask underflow ? */
16672       {
16673         iB = pWorkrow [0];             /* get next input-byte */
16674         pWorkrow++;
16675         iM = 0xF0;
16676         iS = 4;
16677       }
16678                                        /* get the index */
16679       iQ = (mng_uint8)((iB & iM) >> iS);
16680                                        /* index valid ? */
16681       if ((mng_uint32)iQ < pBuf->iPLTEcount)
16682       {                                /* put in intermediate row */
16683         pRGBArow [0] = pBuf->aPLTEentries [iQ].iRed;
16684         pRGBArow [1] = pBuf->aPLTEentries [iQ].iGreen;
16685         pRGBArow [2] = pBuf->aPLTEentries [iQ].iBlue;
16686         pRGBArow [3] = 0xFF;
16687       }
16688       else
16689         MNG_ERROR (pData, MNG_PLTEINDEXERROR);
16690 
16691       pRGBArow += 4;                   /* next pixel */
16692       iM >>=  4;
16693       iS -= 4;
16694     }
16695 
16696     pData->bIsOpaque = MNG_TRUE;       /* it's fully opaque */
16697   }
16698 
16699 #ifdef MNG_SUPPORT_TRACE
16700   MNG_TRACE (pData, MNG_FN_PROCESS_IDX4, MNG_LC_END);
16701 #endif
16702 
16703   return MNG_NOERROR;
16704 }
16705 #endif /* MNG_NO_1_2_4BIT_SUPPORT */
16706 
16707 /* ************************************************************************** */
16708 
mng_process_idx8(mng_datap pData)16709 mng_retcode mng_process_idx8 (mng_datap pData)
16710 {
16711   mng_uint8p     pWorkrow;
16712   mng_uint8p     pRGBArow;
16713   mng_int32      iX;
16714   mng_uint8      iQ;
16715   mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
16716 
16717 #ifdef MNG_SUPPORT_TRACE
16718   MNG_TRACE (pData, MNG_FN_PROCESS_IDX8, MNG_LC_START);
16719 #endif
16720 
16721   if (!pBuf)                           /* no object? then use obj 0 */
16722     pBuf = ((mng_imagep)pData->pObjzero)->pImgbuf;
16723                                        /* temporary work pointers */
16724   pWorkrow = pData->pWorkrow + pData->iPixelofs;
16725   pRGBArow = pData->pRGBArow;
16726 
16727   if (pBuf->bHasTRNS)                  /* tRNS encountered ? */
16728   {
16729 #ifdef MNG_DECREMENT_LOOPS
16730     for (iX = pData->iRowsamples; iX > 0; iX--)
16731 #else
16732     for (iX = 0; iX < pData->iRowsamples; iX++)
16733 #endif
16734     {
16735       iQ = *pWorkrow;                  /* get input byte */
16736                                        /* index valid ? */
16737       if ((mng_uint32)iQ < pBuf->iPLTEcount)
16738       {                                /* put in intermediate row */
16739         pRGBArow [0] = pBuf->aPLTEentries [iQ].iRed;
16740         pRGBArow [1] = pBuf->aPLTEentries [iQ].iGreen;
16741         pRGBArow [2] = pBuf->aPLTEentries [iQ].iBlue;
16742                                        /* transparency for this index ? */
16743         if ((mng_uint32)iQ < pBuf->iTRNScount)
16744           pRGBArow [3] = pBuf->aTRNSentries [iQ];
16745         else
16746           pRGBArow [3] = 0xFF;
16747       }
16748       else
16749         MNG_ERROR (pData, MNG_PLTEINDEXERROR);
16750 
16751       pRGBArow += 4;                   /* next pixel */
16752       pWorkrow++;
16753     }
16754 
16755     pData->bIsOpaque = MNG_FALSE;      /* it's not fully opaque */
16756   }
16757   else
16758   {
16759 #ifdef MNG_DECREMENT_LOOPS
16760     for (iX = pData->iRowsamples; iX > 0; iX--)
16761 #else
16762     for (iX = 0; iX < pData->iRowsamples; iX++)
16763 #endif
16764     {
16765       iQ = *pWorkrow;                  /* get input byte */
16766                                        /* index valid ? */
16767       if ((mng_uint32)iQ < pBuf->iPLTEcount)
16768       {                                /* put in intermediate row */
16769         pRGBArow [0] = pBuf->aPLTEentries [iQ].iRed;
16770         pRGBArow [1] = pBuf->aPLTEentries [iQ].iGreen;
16771         pRGBArow [2] = pBuf->aPLTEentries [iQ].iBlue;
16772         pRGBArow [3] = 0xFF;
16773       }
16774       else
16775         MNG_ERROR (pData, MNG_PLTEINDEXERROR);
16776 
16777       pRGBArow += 4;                   /* next pixel */
16778       pWorkrow++;
16779     }
16780 
16781     pData->bIsOpaque = MNG_TRUE;       /* it's fully opaque */
16782   }
16783 
16784 #ifdef MNG_SUPPORT_TRACE
16785   MNG_TRACE (pData, MNG_FN_PROCESS_IDX8, MNG_LC_END);
16786 #endif
16787 
16788   return MNG_NOERROR;
16789 }
16790 
16791 /* ************************************************************************** */
16792 
mng_process_ga8(mng_datap pData)16793 mng_retcode mng_process_ga8 (mng_datap pData)
16794 {
16795   mng_uint8p pWorkrow;
16796   mng_uint8p pRGBArow;
16797   mng_int32  iX;
16798 
16799 #ifdef MNG_SUPPORT_TRACE
16800   MNG_TRACE (pData, MNG_FN_PROCESS_GA8, MNG_LC_START);
16801 #endif
16802                                        /* temporary work pointers */
16803   pWorkrow = pData->pWorkrow + pData->iPixelofs;
16804   pRGBArow = pData->pRGBArow;
16805 
16806 #ifdef MNG_DECREMENT_LOOPS
16807   for (iX = pData->iRowsamples; iX > 0; iX--)
16808 #else
16809   for (iX = 0; iX < pData->iRowsamples; iX++)
16810 #endif
16811   {
16812     *pRGBArow     = *pWorkrow;         /* copy the gray value */
16813     *(pRGBArow+1) = *pWorkrow;
16814     *(pRGBArow+2) = *pWorkrow;
16815     *(pRGBArow+3) = *(pWorkrow+1);     /* copy the alpha value */
16816 
16817     pWorkrow += 2;                     /* next pixel */
16818     pRGBArow += 4;
16819   }
16820 
16821   pData->bIsOpaque = MNG_FALSE;        /* it's definitely not fully opaque */
16822 
16823 #ifdef MNG_SUPPORT_TRACE
16824   MNG_TRACE (pData, MNG_FN_PROCESS_GA8, MNG_LC_END);
16825 #endif
16826 
16827   return MNG_NOERROR;
16828 }
16829 
16830 /* ************************************************************************** */
16831 
16832 #ifndef MNG_NO_16BIT_SUPPORT
mng_process_ga16(mng_datap pData)16833 mng_retcode mng_process_ga16 (mng_datap pData)
16834 {
16835   mng_uint8p  pWorkrow;
16836   mng_uint8p  pRGBArow;
16837   mng_int32  iX;
16838   mng_uint16 iW;
16839 
16840 #ifdef MNG_SUPPORT_TRACE
16841   MNG_TRACE (pData, MNG_FN_PROCESS_GA16, MNG_LC_START);
16842 #endif
16843                                        /* temporary work pointers */
16844   pWorkrow = pData->pWorkrow + pData->iPixelofs;
16845   pRGBArow = pData->pRGBArow;
16846 
16847 #ifdef MNG_DECREMENT_LOOPS
16848   for (iX = pData->iRowsamples; iX > 0; iX--)
16849 #else
16850   for (iX = 0; iX < pData->iRowsamples; iX++)
16851 #endif
16852   {
16853     iW = mng_get_uint16 (pWorkrow);    /* copy the gray value */
16854     mng_put_uint16 (pRGBArow,   iW);
16855     mng_put_uint16 (pRGBArow+2, iW);
16856     mng_put_uint16 (pRGBArow+4, iW);
16857                                        /* copy the alpha value */
16858     mng_put_uint16 (pRGBArow+6, mng_get_uint16 (pWorkrow+2));
16859 
16860     pWorkrow += 4;                     /* next pixel */
16861     pRGBArow += 8;
16862   }
16863 
16864   pData->bIsOpaque = MNG_FALSE;        /* it's definitely not fully opaque */
16865 
16866 #ifdef MNG_SUPPORT_TRACE
16867   MNG_TRACE (pData, MNG_FN_PROCESS_GA16, MNG_LC_END);
16868 #endif
16869 
16870   return MNG_NOERROR;
16871 }
16872 #endif
16873 
16874 /* ************************************************************************** */
16875 
mng_process_rgba8(mng_datap pData)16876 mng_retcode mng_process_rgba8 (mng_datap pData)
16877 {
16878 #ifdef MNG_SUPPORT_TRACE
16879   MNG_TRACE (pData, MNG_FN_PROCESS_RGBA8, MNG_LC_START);
16880 #endif
16881                                        /* this is the easiest transform */
16882   MNG_COPY (pData->pRGBArow, pData->pWorkrow + pData->iPixelofs, pData->iRowsize);
16883 
16884   pData->bIsOpaque = MNG_FALSE;        /* it's definitely not fully opaque */
16885 
16886 #ifdef MNG_SUPPORT_TRACE
16887   MNG_TRACE (pData, MNG_FN_PROCESS_RGBA8, MNG_LC_END);
16888 #endif
16889 
16890   return MNG_NOERROR;
16891 }
16892 
16893 /* ************************************************************************** */
16894 
16895 #ifndef MNG_NO_16BIT_SUPPORT
mng_process_rgba16(mng_datap pData)16896 mng_retcode mng_process_rgba16 (mng_datap pData)
16897 {
16898 #ifdef MNG_SUPPORT_TRACE
16899   MNG_TRACE (pData, MNG_FN_PROCESS_RGBA16, MNG_LC_START);
16900 #endif
16901                                        /* this is the easiest transform */
16902   MNG_COPY (pData->pRGBArow, pData->pWorkrow + pData->iPixelofs, pData->iRowsize);
16903 
16904   pData->bIsOpaque = MNG_FALSE;        /* it's definitely not fully opaque */
16905 
16906 #ifdef MNG_SUPPORT_TRACE
16907   MNG_TRACE (pData, MNG_FN_PROCESS_RGBA16, MNG_LC_END);
16908 #endif
16909 
16910   return MNG_NOERROR;
16911 }
16912 #endif
16913 
16914 /* ************************************************************************** */
16915 /* *                                                                        * */
16916 /* * Row processing initialization routines - set up the variables needed   * */
16917 /* * to process uncompressed row-data                                       * */
16918 /* *                                                                        * */
16919 /* ************************************************************************** */
16920 
16921 #ifndef MNG_OPTIMIZE_FOOTPRINT_INIT
16922 #ifndef MNG_NO_1_2_4BIT_SUPPORT
mng_init_g1_ni(mng_datap pData)16923 mng_retcode mng_init_g1_ni     (mng_datap pData)
16924 {
16925 #ifdef MNG_SUPPORT_TRACE
16926   MNG_TRACE (pData, MNG_FN_INIT_G1_NI, MNG_LC_START);
16927 #endif
16928 
16929   if (pData->fDisplayrow)
16930     pData->fProcessrow = (mng_fptr)mng_process_g1;
16931 
16932   if (pData->pStoreobj)                /* store in object too ? */
16933   {                                    /* immediate delta ? */
16934 #ifndef MNG_NO_DELTA_PNG
16935     if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
16936       pData->fStorerow = (mng_fptr)mng_delta_g1;
16937     else
16938 #endif
16939       pData->fStorerow = (mng_fptr)mng_store_g1;
16940   }
16941 
16942 #ifdef FILTER192                       /* leveling & differing ? */
16943   if (pData->iFilter == MNG_FILTER_DIFFERING)
16944     pData->fDifferrow  = (mng_fptr)mng_differ_g1;
16945 #endif
16946 
16947   pData->iPass       = -1;
16948   pData->iRow        = 0;
16949   pData->iRowinc     = 1;
16950   pData->iCol        = 0;
16951   pData->iColinc     = 1;
16952   pData->iRowsamples = pData->iDatawidth;
16953   pData->iSamplemul  = 1;
16954   pData->iSampleofs  = 7;
16955   pData->iSamplediv  = 3;
16956   pData->iRowsize    = (pData->iRowsamples + 7) >> 3;
16957   pData->iRowmax     = pData->iRowsize + pData->iPixelofs;
16958   pData->iFilterbpp  = 1;
16959   pData->bIsRGBA16   = MNG_FALSE;      /* intermediate row is 8-bit deep */
16960 
16961 #ifdef MNG_SUPPORT_TRACE
16962   MNG_TRACE (pData, MNG_FN_INIT_G1_NI, MNG_LC_END);
16963 #endif
16964 
16965   return mng_init_rowproc (pData);
16966 }
16967 
16968 /* ************************************************************************** */
16969 
mng_init_g1_i(mng_datap pData)16970 mng_retcode mng_init_g1_i      (mng_datap pData)
16971 {
16972 #ifdef MNG_SUPPORT_TRACE
16973   MNG_TRACE (pData, MNG_FN_INIT_G1_I, MNG_LC_START);
16974 #endif
16975 
16976   if (pData->fDisplayrow)
16977     pData->fProcessrow = (mng_fptr)mng_process_g1;
16978 
16979   if (pData->pStoreobj)                /* store in object too ? */
16980   {                                    /* immediate delta ? */
16981 #ifndef MNG_NO_DELTA_PNG
16982     if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
16983       pData->fStorerow = (mng_fptr)mng_delta_g1;
16984     else
16985 #endif
16986       pData->fStorerow = (mng_fptr)mng_store_g1;
16987   }
16988 
16989 #ifdef FILTER192                       /* leveling & differing ? */
16990   if (pData->iFilter == MNG_FILTER_DIFFERING)
16991     pData->fDifferrow  = (mng_fptr)mng_differ_g1;
16992 #endif
16993 
16994   pData->iPass       = 0;              /* from 0..6; is 1..7 in specifications */
16995   pData->iRow        = interlace_row     [0];
16996   pData->iRowinc     = interlace_rowskip [0];
16997   pData->iCol        = interlace_col     [0];
16998   pData->iColinc     = interlace_colskip [0];
16999   pData->iRowsamples = (pData->iDatawidth + interlace_roundoff [0]) >> interlace_divider [0];
17000   pData->iSamplemul  = 1;
17001   pData->iSampleofs  = 7;
17002   pData->iSamplediv  = 3;
17003   pData->iRowsize    = ((pData->iRowsamples + 7) >> 3);
17004   pData->iRowmax     = ((pData->iDatawidth + 7) >> 3) + pData->iPixelofs;
17005   pData->iFilterbpp  = 1;
17006   pData->bIsRGBA16   = MNG_FALSE;      /* intermediate row is 8-bit deep */
17007 
17008 #ifdef MNG_SUPPORT_TRACE
17009   MNG_TRACE (pData, MNG_FN_INIT_G1_I, MNG_LC_END);
17010 #endif
17011 
17012   return mng_init_rowproc (pData);
17013 }
17014 
17015 /* ************************************************************************** */
17016 
mng_init_g2_ni(mng_datap pData)17017 mng_retcode mng_init_g2_ni     (mng_datap pData)
17018 {
17019 #ifdef MNG_SUPPORT_TRACE
17020   MNG_TRACE (pData, MNG_FN_INIT_G2_NI, MNG_LC_START);
17021 #endif
17022 
17023   if (pData->fDisplayrow)
17024     pData->fProcessrow = (mng_fptr)mng_process_g2;
17025 
17026   if (pData->pStoreobj)                /* store in object too ? */
17027   {                                    /* immediate delta ? */
17028 #ifndef MNG_NO_DELTA_PNG
17029     if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
17030       pData->fStorerow = (mng_fptr)mng_delta_g2;
17031     else
17032 #endif
17033       pData->fStorerow = (mng_fptr)mng_store_g2;
17034   }
17035 
17036 #ifdef FILTER192                       /* leveling & differing ? */
17037   if (pData->iFilter == MNG_FILTER_DIFFERING)
17038     pData->fDifferrow  = (mng_fptr)mng_differ_g2;
17039 #endif
17040 
17041   pData->iPass       = -1;
17042   pData->iRow        = 0;
17043   pData->iRowinc     = 1;
17044   pData->iCol        = 0;
17045   pData->iColinc     = 1;
17046   pData->iRowsamples = pData->iDatawidth;
17047   pData->iSamplemul  = 1;
17048   pData->iSampleofs  = 3;
17049   pData->iSamplediv  = 2;
17050   pData->iRowsize    = (pData->iRowsamples + 3) >> 2;
17051   pData->iRowmax     = pData->iRowsize + pData->iPixelofs;
17052   pData->iFilterbpp  = 1;
17053   pData->bIsRGBA16   = MNG_FALSE;      /* intermediate row is 8-bit deep */
17054 
17055 #ifdef MNG_SUPPORT_TRACE
17056   MNG_TRACE (pData, MNG_FN_INIT_G2_NI, MNG_LC_END);
17057 #endif
17058 
17059   return mng_init_rowproc (pData);
17060 }
17061 
17062 /* ************************************************************************** */
17063 
mng_init_g2_i(mng_datap pData)17064 mng_retcode mng_init_g2_i      (mng_datap pData)
17065 {
17066 #ifdef MNG_SUPPORT_TRACE
17067   MNG_TRACE (pData, MNG_FN_INIT_G2_I, MNG_LC_START);
17068 #endif
17069 
17070   if (pData->fDisplayrow)
17071     pData->fProcessrow = (mng_fptr)mng_process_g2;
17072 
17073   if (pData->pStoreobj)                /* store in object too ? */
17074   {                                    /* immediate delta ? */
17075 #ifndef MNG_NO_DELTA_PNG
17076     if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
17077       pData->fStorerow = (mng_fptr)mng_delta_g2;
17078     else
17079 #endif
17080       pData->fStorerow = (mng_fptr)mng_store_g2;
17081   }
17082 
17083 #ifdef FILTER192                       /* leveling & differing ? */
17084   if (pData->iFilter == MNG_FILTER_DIFFERING)
17085     pData->fDifferrow  = (mng_fptr)mng_differ_g2;
17086 #endif
17087 
17088   pData->iPass       = 0;              /* from 0..6; is 1..7 in specifications */
17089   pData->iRow        = interlace_row     [0];
17090   pData->iRowinc     = interlace_rowskip [0];
17091   pData->iCol        = interlace_col     [0];
17092   pData->iColinc     = interlace_colskip [0];
17093   pData->iRowsamples = (pData->iDatawidth + interlace_roundoff [0]) >> interlace_divider [0];
17094   pData->iSamplemul  = 1;
17095   pData->iSampleofs  = 3;
17096   pData->iSamplediv  = 2;
17097   pData->iRowsize    = ((pData->iRowsamples + 3) >> 2);
17098   pData->iRowmax     = ((pData->iDatawidth + 3) >> 2) + pData->iPixelofs;
17099   pData->iFilterbpp  = 1;
17100   pData->bIsRGBA16   = MNG_FALSE;      /* intermediate row is 8-bit deep */
17101 
17102 #ifdef MNG_SUPPORT_TRACE
17103   MNG_TRACE (pData, MNG_FN_INIT_G2_I, MNG_LC_END);
17104 #endif
17105 
17106   return mng_init_rowproc (pData);
17107 }
17108 
17109 /* ************************************************************************** */
17110 
mng_init_g4_ni(mng_datap pData)17111 mng_retcode mng_init_g4_ni     (mng_datap pData)
17112 {
17113 #ifdef MNG_SUPPORT_TRACE
17114   MNG_TRACE (pData, MNG_FN_INIT_G4_NI, MNG_LC_START);
17115 #endif
17116 
17117   if (pData->fDisplayrow)
17118     pData->fProcessrow = (mng_fptr)mng_process_g4;
17119 
17120   if (pData->pStoreobj)                /* store in object too ? */
17121   {                                    /* immediate delta ? */
17122 #ifndef MNG_NO_DELTA_PNG
17123     if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
17124       pData->fStorerow = (mng_fptr)mng_delta_g4;
17125     else
17126 #endif
17127       pData->fStorerow = (mng_fptr)mng_store_g4;
17128   }
17129 
17130 #ifdef FILTER192                       /* leveling & differing ? */
17131   if (pData->iFilter == MNG_FILTER_DIFFERING)
17132     pData->fDifferrow  = (mng_fptr)mng_differ_g4;
17133 #endif
17134 
17135   pData->iPass       = -1;
17136   pData->iRow        = 0;
17137   pData->iRowinc     = 1;
17138   pData->iCol        = 0;
17139   pData->iColinc     = 1;
17140   pData->iRowsamples = pData->iDatawidth;
17141   pData->iSamplemul  = 1;
17142   pData->iSampleofs  = 1;
17143   pData->iSamplediv  = 1;
17144   pData->iRowsize    = (pData->iRowsamples + 1) >> 1;
17145   pData->iRowmax     = pData->iRowsize + pData->iPixelofs;
17146   pData->iFilterbpp  = 1;
17147   pData->bIsRGBA16   = MNG_FALSE;      /* intermediate row is 8-bit deep */
17148 
17149 #ifdef MNG_SUPPORT_TRACE
17150   MNG_TRACE (pData, MNG_FN_INIT_G4_NI, MNG_LC_END);
17151 #endif
17152 
17153   return mng_init_rowproc (pData);
17154 }
17155 
17156 /* ************************************************************************** */
17157 
mng_init_g4_i(mng_datap pData)17158 mng_retcode mng_init_g4_i      (mng_datap pData)
17159 {
17160 #ifdef MNG_SUPPORT_TRACE
17161   MNG_TRACE (pData, MNG_FN_INIT_G4_I, MNG_LC_START);
17162 #endif
17163 
17164   if (pData->fDisplayrow)
17165     pData->fProcessrow = (mng_fptr)mng_process_g4;
17166 
17167   if (pData->pStoreobj)                /* store in object too ? */
17168   {                                    /* immediate delta ? */
17169 #ifndef MNG_NO_DELTA_PNG
17170     if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
17171       pData->fStorerow = (mng_fptr)mng_delta_g4;
17172     else
17173 #endif
17174       pData->fStorerow = (mng_fptr)mng_store_g4;
17175   }
17176 
17177 #ifdef FILTER192                       /* leveling & differing ? */
17178   if (pData->iFilter == MNG_FILTER_DIFFERING)
17179     pData->fDifferrow  = (mng_fptr)mng_differ_g4;
17180 #endif
17181 
17182   pData->iPass       = 0;              /* from 0..6; is 1..7 in specifications */
17183   pData->iRow        = interlace_row     [0];
17184   pData->iRowinc     = interlace_rowskip [0];
17185   pData->iCol        = interlace_col     [0];
17186   pData->iColinc     = interlace_colskip [0];
17187   pData->iRowsamples = (pData->iDatawidth + interlace_roundoff [0]) >> interlace_divider [0];
17188   pData->iSamplemul  = 1;
17189   pData->iSampleofs  = 1;
17190   pData->iSamplediv  = 1;
17191   pData->iRowsize    = ((pData->iRowsamples + 1) >> 1);
17192   pData->iRowmax     = ((pData->iDatawidth + 1) >> 1) + pData->iPixelofs;
17193   pData->iFilterbpp  = 1;
17194   pData->bIsRGBA16   = MNG_FALSE;      /* intermediate row is 8-bit deep */
17195 
17196 #ifdef MNG_SUPPORT_TRACE
17197   MNG_TRACE (pData, MNG_FN_INIT_G4_I, MNG_LC_END);
17198 #endif
17199 
17200   return mng_init_rowproc (pData);
17201 }
17202 #endif /* MNG_NO_1_2_4BIT_SUPPORT */
17203 
17204 /* ************************************************************************** */
17205 
mng_init_g8_ni(mng_datap pData)17206 mng_retcode mng_init_g8_ni     (mng_datap pData)
17207 {
17208 #ifdef MNG_SUPPORT_TRACE
17209   MNG_TRACE (pData, MNG_FN_INIT_G8_NI, MNG_LC_START);
17210 #endif
17211 
17212   if (pData->fDisplayrow)
17213     pData->fProcessrow = (mng_fptr)mng_process_g8;
17214 
17215   if (pData->pStoreobj)                /* store in object too ? */
17216   {                                    /* immediate delta ? */
17217 #ifndef MNG_NO_DELTA_PNG
17218     if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
17219       pData->fStorerow = (mng_fptr)mng_delta_g8;
17220     else
17221 #endif
17222       pData->fStorerow = (mng_fptr)mng_store_g8;
17223   }
17224 
17225 #ifdef FILTER192                       /* leveling & differing ? */
17226   if (pData->iFilter == MNG_FILTER_DIFFERING)
17227     pData->fDifferrow  = (mng_fptr)mng_differ_g8;
17228 #endif
17229 
17230   pData->iPass       = -1;
17231   pData->iRow        = 0;
17232   pData->iRowinc     = 1;
17233   pData->iCol        = 0;
17234   pData->iColinc     = 1;
17235   pData->iRowsamples = pData->iDatawidth;
17236   pData->iSamplemul  = 1;
17237   pData->iSampleofs  = 0;
17238   pData->iSamplediv  = 0;
17239   pData->iRowsize    = pData->iRowsamples;
17240   pData->iRowmax     = pData->iRowsize + pData->iPixelofs;
17241   pData->iFilterbpp  = 1;
17242   pData->bIsRGBA16   = MNG_FALSE;      /* intermediate row is 8-bit deep */
17243 
17244 #ifdef MNG_SUPPORT_TRACE
17245   MNG_TRACE (pData, MNG_FN_INIT_G8_NI, MNG_LC_END);
17246 #endif
17247 
17248   return mng_init_rowproc (pData);
17249 }
17250 
17251 /* ************************************************************************** */
17252 
mng_init_g8_i(mng_datap pData)17253 mng_retcode mng_init_g8_i      (mng_datap pData)
17254 {
17255 #ifdef MNG_SUPPORT_TRACE
17256   MNG_TRACE (pData, MNG_FN_INIT_G8_I, MNG_LC_START);
17257 #endif
17258 
17259   if (pData->fDisplayrow)
17260     pData->fProcessrow = (mng_fptr)mng_process_g8;
17261 
17262   if (pData->pStoreobj)                /* store in object too ? */
17263   {                                    /* immediate delta ? */
17264 #ifndef MNG_NO_DELTA_PNG
17265     if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
17266       pData->fStorerow = (mng_fptr)mng_delta_g8;
17267     else
17268 #endif
17269       pData->fStorerow = (mng_fptr)mng_store_g8;
17270   }
17271 
17272 #ifdef FILTER192                       /* leveling & differing ? */
17273   if (pData->iFilter == MNG_FILTER_DIFFERING)
17274     pData->fDifferrow  = (mng_fptr)mng_differ_g8;
17275 #endif
17276 
17277   pData->iPass       = 0;              /* from 0..6; is 1..7 in specifications */
17278   pData->iRow        = interlace_row     [0];
17279   pData->iRowinc     = interlace_rowskip [0];
17280   pData->iCol        = interlace_col     [0];
17281   pData->iColinc     = interlace_colskip [0];
17282   pData->iRowsamples = (pData->iDatawidth + interlace_roundoff [0]) >> interlace_divider [0];
17283   pData->iSamplemul  = 1;
17284   pData->iSampleofs  = 0;
17285   pData->iSamplediv  = 0;
17286   pData->iRowsize    = pData->iRowsamples;
17287   pData->iRowmax     = pData->iDatawidth + pData->iPixelofs;
17288   pData->iFilterbpp  = 1;
17289   pData->bIsRGBA16   = MNG_FALSE;      /* intermediate row is 8-bit deep */
17290 
17291 #ifdef MNG_SUPPORT_TRACE
17292   MNG_TRACE (pData, MNG_FN_INIT_G8_I, MNG_LC_END);
17293 #endif
17294 
17295   return mng_init_rowproc (pData);
17296 }
17297 
17298 /* ************************************************************************** */
17299 
17300 #ifndef MNG_NO_16BIT_SUPPORT
mng_init_g16_ni(mng_datap pData)17301 mng_retcode mng_init_g16_ni    (mng_datap pData)
17302 {
17303 #ifdef MNG_SUPPORT_TRACE
17304   MNG_TRACE (pData, MNG_FN_INIT_G16_NI, MNG_LC_START);
17305 #endif
17306 
17307   if (pData->fDisplayrow)
17308     pData->fProcessrow = (mng_fptr)mng_process_g16;
17309 
17310   if (pData->pStoreobj)                /* store in object too ? */
17311   {                                    /* immediate delta ? */
17312 #ifndef MNG_NO_DELTA_PNG
17313     if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
17314       pData->fStorerow = (mng_fptr)mng_delta_g16;
17315     else
17316 #endif
17317       pData->fStorerow = (mng_fptr)mng_store_g16;
17318   }
17319 
17320 #ifdef FILTER192                       /* leveling & differing ? */
17321   if (pData->iFilter == MNG_FILTER_DIFFERING)
17322     pData->fDifferrow  = (mng_fptr)mng_differ_g16;
17323 #endif
17324 
17325   pData->iPass       = -1;
17326   pData->iRow        = 0;
17327   pData->iRowinc     = 1;
17328   pData->iCol        = 0;
17329   pData->iColinc     = 1;
17330   pData->iRowsamples = pData->iDatawidth;
17331   pData->iSamplemul  = 2;
17332   pData->iSampleofs  = 0;
17333   pData->iSamplediv  = 0;
17334   pData->iRowsize    = pData->iRowsamples << 1;
17335   pData->iRowmax     = pData->iRowsize + pData->iPixelofs;
17336   pData->iFilterbpp  = 2;
17337   pData->bIsRGBA16   = MNG_TRUE;       /* intermediate row is 16-bit deep */
17338 
17339 #ifdef MNG_SUPPORT_TRACE
17340   MNG_TRACE (pData, MNG_FN_INIT_G16_NI, MNG_LC_END);
17341 #endif
17342 
17343   return mng_init_rowproc (pData);
17344 }
17345 #endif
17346 
17347 /* ************************************************************************** */
17348 
17349 #ifndef MNG_NO_16BIT_SUPPORT
mng_init_g16_i(mng_datap pData)17350 mng_retcode mng_init_g16_i     (mng_datap pData)
17351 {
17352 #ifdef MNG_SUPPORT_TRACE
17353   MNG_TRACE (pData, MNG_FN_INIT_G16_I, MNG_LC_START);
17354 #endif
17355 
17356   if (pData->fDisplayrow)
17357     pData->fProcessrow = (mng_fptr)mng_process_g16;
17358 
17359   if (pData->pStoreobj)                /* store in object too ? */
17360   {                                    /* immediate delta ? */
17361 #ifndef MNG_NO_DELTA_PNG
17362     if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
17363       pData->fStorerow = (mng_fptr)mng_delta_g16;
17364     else
17365 #endif
17366       pData->fStorerow = (mng_fptr)mng_store_g16;
17367   }
17368 
17369 #ifdef FILTER192                       /* leveling & differing ? */
17370   if (pData->iFilter == MNG_FILTER_DIFFERING)
17371     pData->fDifferrow  = (mng_fptr)mng_differ_g16;
17372 #endif
17373 
17374   pData->iPass       = 0;              /* from 0..6; is 1..7 in specifications */
17375   pData->iRow        = interlace_row     [0];
17376   pData->iRowinc     = interlace_rowskip [0];
17377   pData->iCol        = interlace_col     [0];
17378   pData->iColinc     = interlace_colskip [0];
17379   pData->iRowsamples = (pData->iDatawidth + interlace_roundoff [0]) >> interlace_divider [0];
17380   pData->iSamplemul  = 2;
17381   pData->iSampleofs  = 0;
17382   pData->iSamplediv  = 0;
17383   pData->iRowsize    = pData->iRowsamples << 1;
17384   pData->iRowmax     = (pData->iDatawidth << 1) + pData->iPixelofs;
17385   pData->iFilterbpp  = 2;
17386   pData->bIsRGBA16   = MNG_TRUE;       /* intermediate row is 16-bit deep */
17387 
17388 #ifdef MNG_SUPPORT_TRACE
17389   MNG_TRACE (pData, MNG_FN_INIT_G16_I, MNG_LC_END);
17390 #endif
17391 
17392   return mng_init_rowproc (pData);
17393 }
17394 #endif
17395 
17396 /* ************************************************************************** */
17397 
mng_init_rgb8_ni(mng_datap pData)17398 mng_retcode mng_init_rgb8_ni   (mng_datap pData)
17399 {
17400 #ifdef MNG_SUPPORT_TRACE
17401   MNG_TRACE (pData, MNG_FN_INIT_RGB8_NI, MNG_LC_START);
17402 #endif
17403 
17404   if (pData->fDisplayrow)
17405     pData->fProcessrow = (mng_fptr)mng_process_rgb8;
17406 
17407   if (pData->pStoreobj)                /* store in object too ? */
17408   {                                    /* immediate delta ? */
17409 #ifndef MNG_NO_DELTA_PNG
17410     if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
17411       pData->fStorerow = (mng_fptr)mng_delta_rgb8;
17412     else
17413 #endif
17414       pData->fStorerow = (mng_fptr)mng_store_rgb8;
17415   }
17416 
17417 #ifdef FILTER192                       /* leveling & differing ? */
17418   if (pData->iFilter == MNG_FILTER_DIFFERING)
17419     pData->fDifferrow  = (mng_fptr)mng_differ_rgb8;
17420 #endif
17421 
17422   pData->iPass       = -1;
17423   pData->iRow        = 0;
17424   pData->iRowinc     = 1;
17425   pData->iCol        = 0;
17426   pData->iColinc     = 1;
17427   pData->iRowsamples = pData->iDatawidth;
17428   pData->iSamplemul  = 3;
17429   pData->iSampleofs  = 0;
17430   pData->iSamplediv  = 0;
17431   pData->iRowsize    = pData->iRowsamples * 3;
17432   pData->iRowmax     = pData->iRowsize + pData->iPixelofs;
17433   pData->iFilterbpp  = 3;
17434   pData->bIsRGBA16   = MNG_FALSE;      /* intermediate row is 8-bit deep */
17435 
17436 #ifdef MNG_SUPPORT_TRACE
17437   MNG_TRACE (pData, MNG_FN_INIT_RGB8_NI, MNG_LC_END);
17438 #endif
17439 
17440   return mng_init_rowproc (pData);
17441 }
17442 
17443 /* ************************************************************************** */
17444 
mng_init_rgb8_i(mng_datap pData)17445 mng_retcode mng_init_rgb8_i    (mng_datap pData)
17446 {
17447 #ifdef MNG_SUPPORT_TRACE
17448   MNG_TRACE (pData, MNG_FN_INIT_RGB8_I, MNG_LC_START);
17449 #endif
17450 
17451   if (pData->fDisplayrow)
17452     pData->fProcessrow = (mng_fptr)mng_process_rgb8;
17453 
17454   if (pData->pStoreobj)                /* store in object too ? */
17455   {                                    /* immediate delta ? */
17456 #ifndef MNG_NO_DELTA_PNG
17457     if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
17458       pData->fStorerow = (mng_fptr)mng_delta_rgb8;
17459     else
17460 #endif
17461       pData->fStorerow = (mng_fptr)mng_store_rgb8;
17462   }
17463 
17464 #ifdef FILTER192                       /* leveling & differing ? */
17465   if (pData->iFilter == MNG_FILTER_DIFFERING)
17466     pData->fDifferrow  = (mng_fptr)mng_differ_rgb8;
17467 #endif
17468 
17469   pData->iPass       = 0;              /* from 0..6; is 1..7 in specifications */
17470   pData->iRow        = interlace_row     [0];
17471   pData->iRowinc     = interlace_rowskip [0];
17472   pData->iCol        = interlace_col     [0];
17473   pData->iColinc     = interlace_colskip [0];
17474   pData->iRowsamples = (pData->iDatawidth + interlace_roundoff [0]) >> interlace_divider [0];
17475   pData->iSamplemul  = 3;
17476   pData->iSampleofs  = 0;
17477   pData->iSamplediv  = 0;
17478   pData->iRowsize    = pData->iRowsamples * 3;
17479   pData->iRowmax     = (pData->iDatawidth * 3) + pData->iPixelofs;
17480   pData->iFilterbpp  = 3;
17481   pData->bIsRGBA16   = MNG_FALSE;      /* intermediate row is 8-bit deep */
17482 
17483 #ifdef MNG_SUPPORT_TRACE
17484   MNG_TRACE (pData, MNG_FN_INIT_RGB8_I, MNG_LC_END);
17485 #endif
17486 
17487   return mng_init_rowproc (pData);
17488 }
17489 
17490 /* ************************************************************************** */
17491 
17492 #ifndef MNG_NO_16BIT_SUPPORT
mng_init_rgb16_ni(mng_datap pData)17493 mng_retcode mng_init_rgb16_ni  (mng_datap pData)
17494 {
17495 #ifdef MNG_SUPPORT_TRACE
17496   MNG_TRACE (pData, MNG_FN_INIT_RGB16_NI, MNG_LC_START);
17497 #endif
17498 
17499   if (pData->fDisplayrow)
17500     pData->fProcessrow = (mng_fptr)mng_process_rgb16;
17501 
17502   if (pData->pStoreobj)                /* store in object too ? */
17503   {                                    /* immediate delta ? */
17504 #ifndef MNG_NO_DELTA_PNG
17505     if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
17506       pData->fStorerow = (mng_fptr)mng_delta_rgb16;
17507     else
17508 #endif
17509       pData->fStorerow = (mng_fptr)mng_store_rgb16;
17510   }
17511 
17512 #ifdef FILTER192                       /* leveling & differing ? */
17513   if (pData->iFilter == MNG_FILTER_DIFFERING)
17514     pData->fDifferrow  = (mng_fptr)mng_differ_rgb16;
17515 #endif
17516 
17517   pData->iPass       = -1;
17518   pData->iRow        = 0;
17519   pData->iRowinc     = 1;
17520   pData->iCol        = 0;
17521   pData->iColinc     = 1;
17522   pData->iRowsamples = pData->iDatawidth;
17523   pData->iSamplemul  = 6;
17524   pData->iSampleofs  = 0;
17525   pData->iSamplediv  = 0;
17526   pData->iRowsize    = pData->iRowsamples * 6;
17527   pData->iRowmax     = pData->iRowsize + pData->iPixelofs;
17528   pData->iFilterbpp  = 6;
17529   pData->bIsRGBA16   = MNG_TRUE;       /* intermediate row is 16-bit deep */
17530 
17531 #ifdef MNG_SUPPORT_TRACE
17532   MNG_TRACE (pData, MNG_FN_INIT_RGB16_NI, MNG_LC_END);
17533 #endif
17534 
17535   return mng_init_rowproc (pData);
17536 }
17537 #endif
17538 
17539 /* ************************************************************************** */
17540 
17541 #ifndef MNG_NO_16BIT_SUPPORT
mng_init_rgb16_i(mng_datap pData)17542 mng_retcode mng_init_rgb16_i   (mng_datap pData)
17543 {
17544 #ifdef MNG_SUPPORT_TRACE
17545   MNG_TRACE (pData, MNG_FN_INIT_RGB16_I, MNG_LC_START);
17546 #endif
17547 
17548   if (pData->fDisplayrow)
17549     pData->fProcessrow = (mng_fptr)mng_process_rgb16;
17550 
17551   if (pData->pStoreobj)                /* store in object too ? */
17552   {                                    /* immediate delta ? */
17553 #ifndef MNG_NO_DELTA_PNG
17554     if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
17555       pData->fStorerow = (mng_fptr)mng_delta_rgb16;
17556     else
17557 #endif
17558       pData->fStorerow = (mng_fptr)mng_store_rgb16;
17559   }
17560 
17561 #ifdef FILTER192                       /* leveling & differing ? */
17562   if (pData->iFilter == MNG_FILTER_DIFFERING)
17563     pData->fDifferrow  = (mng_fptr)mng_differ_rgb16;
17564 #endif
17565 
17566   pData->iPass       = 0;              /* from 0..6; is 1..7 in specifications */
17567   pData->iRow        = interlace_row     [0];
17568   pData->iRowinc     = interlace_rowskip [0];
17569   pData->iCol        = interlace_col     [0];
17570   pData->iColinc     = interlace_colskip [0];
17571   pData->iRowsamples = (pData->iDatawidth + interlace_roundoff [0]) >> interlace_divider [0];
17572   pData->iSamplemul  = 6;
17573   pData->iSampleofs  = 0;
17574   pData->iSamplediv  = 0;
17575   pData->iRowsize    = pData->iRowsamples * 6;
17576   pData->iRowmax     = (pData->iDatawidth * 6) + pData->iPixelofs;
17577   pData->iFilterbpp  = 6;
17578   pData->bIsRGBA16   = MNG_TRUE;       /* intermediate row is 16-bit deep */
17579 
17580 #ifdef MNG_SUPPORT_TRACE
17581   MNG_TRACE (pData, MNG_FN_INIT_RGB16_I, MNG_LC_END);
17582 #endif
17583 
17584   return mng_init_rowproc (pData);
17585 }
17586 #endif
17587 
17588 /* ************************************************************************** */
17589 
17590 #ifndef MNG_NO_1_2_4BIT_SUPPORT
mng_init_idx1_ni(mng_datap pData)17591 mng_retcode mng_init_idx1_ni   (mng_datap pData)
17592 {
17593 #ifdef MNG_SUPPORT_TRACE
17594   MNG_TRACE (pData, MNG_FN_INIT_IDX1_NI, MNG_LC_START);
17595 #endif
17596 
17597   if (pData->fDisplayrow)
17598     pData->fProcessrow = (mng_fptr)mng_process_idx1;
17599 
17600   if (pData->pStoreobj)                /* store in object too ? */
17601   {                                    /* immediate delta ? */
17602 #ifndef MNG_NO_DELTA_PNG
17603     if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
17604       pData->fStorerow = (mng_fptr)mng_delta_idx1;
17605     else
17606 #endif
17607       pData->fStorerow = (mng_fptr)mng_store_idx1;
17608   }
17609 
17610 #ifdef FILTER192                       /* leveling & differing ? */
17611   if (pData->iFilter == MNG_FILTER_DIFFERING)
17612     pData->fDifferrow  = (mng_fptr)mng_differ_idx1;
17613 #endif
17614 
17615   pData->iPass       = -1;
17616   pData->iRow        = 0;
17617   pData->iRowinc     = 1;
17618   pData->iCol        = 0;
17619   pData->iColinc     = 1;
17620   pData->iRowsamples = pData->iDatawidth;
17621   pData->iSamplemul  = 1;
17622   pData->iSampleofs  = 7;
17623   pData->iSamplediv  = 3;
17624   pData->iRowsize    = (pData->iRowsamples + 7) >> 3;
17625   pData->iRowmax     = pData->iRowsize + pData->iPixelofs;
17626   pData->iFilterbpp  = 1;
17627   pData->bIsRGBA16   = MNG_FALSE;      /* intermediate row is 8-bit deep */
17628 
17629 #ifdef MNG_SUPPORT_TRACE
17630   MNG_TRACE (pData, MNG_FN_INIT_IDX1_NI, MNG_LC_END);
17631 #endif
17632 
17633   return mng_init_rowproc (pData);
17634 }
17635 
17636 /* ************************************************************************** */
17637 
mng_init_idx1_i(mng_datap pData)17638 mng_retcode mng_init_idx1_i    (mng_datap pData)
17639 {
17640 #ifdef MNG_SUPPORT_TRACE
17641   MNG_TRACE (pData, MNG_FN_INIT_IDX1_I, MNG_LC_START);
17642 #endif
17643 
17644   if (pData->fDisplayrow)
17645     pData->fProcessrow = (mng_fptr)mng_process_idx1;
17646 
17647   if (pData->pStoreobj)                /* store in object too ? */
17648   {                                    /* immediate delta ? */
17649 #ifndef MNG_NO_DELTA_PNG
17650     if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
17651       pData->fStorerow = (mng_fptr)mng_delta_idx1;
17652     else
17653 #endif
17654       pData->fStorerow = (mng_fptr)mng_store_idx1;
17655   }
17656 
17657 #ifdef FILTER192                       /* leveling & differing ? */
17658   if (pData->iFilter == MNG_FILTER_DIFFERING)
17659     pData->fDifferrow  = (mng_fptr)mng_differ_idx1;
17660 #endif
17661 
17662   pData->iPass       = 0;              /* from 0..6; is 1..7 in specifications */
17663   pData->iRow        = interlace_row     [0];
17664   pData->iRowinc     = interlace_rowskip [0];
17665   pData->iCol        = interlace_col     [0];
17666   pData->iColinc     = interlace_colskip [0];
17667   pData->iRowsamples = (pData->iDatawidth + interlace_roundoff [0]) >> interlace_divider [0];
17668   pData->iSamplemul  = 1;
17669   pData->iSampleofs  = 7;
17670   pData->iSamplediv  = 3;
17671   pData->iRowsize    = (pData->iRowsamples + 7) >> 3;
17672   pData->iRowmax     = ((pData->iDatawidth + 7) >> 3) + pData->iPixelofs;
17673   pData->iFilterbpp  = 1;
17674   pData->bIsRGBA16   = MNG_FALSE;      /* intermediate row is 8-bit deep */
17675 
17676 #ifdef MNG_SUPPORT_TRACE
17677   MNG_TRACE (pData, MNG_FN_INIT_IDX1_I, MNG_LC_END);
17678 #endif
17679 
17680   return mng_init_rowproc (pData);
17681 }
17682 
17683 /* ************************************************************************** */
17684 
mng_init_idx2_ni(mng_datap pData)17685 mng_retcode mng_init_idx2_ni   (mng_datap pData)
17686 {
17687 #ifdef MNG_SUPPORT_TRACE
17688   MNG_TRACE (pData, MNG_FN_INIT_IDX2_NI, MNG_LC_START);
17689 #endif
17690 
17691   if (pData->fDisplayrow)
17692     pData->fProcessrow = (mng_fptr)mng_process_idx2;
17693 
17694   if (pData->pStoreobj)                /* store in object too ? */
17695   {                                    /* immediate delta ? */
17696 #ifndef MNG_NO_DELTA_PNG
17697     if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
17698       pData->fStorerow = (mng_fptr)mng_delta_idx2;
17699     else
17700 #endif
17701       pData->fStorerow = (mng_fptr)mng_store_idx2;
17702   }
17703 
17704 #ifdef FILTER192                       /* leveling & differing ? */
17705   if (pData->iFilter == MNG_FILTER_DIFFERING)
17706     pData->fDifferrow  = (mng_fptr)mng_differ_idx2;
17707 #endif
17708 
17709   pData->iPass       = -1;
17710   pData->iRow        = 0;
17711   pData->iRowinc     = 1;
17712   pData->iCol        = 0;
17713   pData->iColinc     = 1;
17714   pData->iRowsamples = pData->iDatawidth;
17715   pData->iSamplemul  = 1;
17716   pData->iSampleofs  = 3;
17717   pData->iSamplediv  = 2;
17718   pData->iRowsize    = (pData->iRowsamples + 3) >> 2;
17719   pData->iRowmax     = pData->iRowsize + pData->iPixelofs;
17720   pData->iFilterbpp  = 1;
17721   pData->bIsRGBA16   = MNG_FALSE;      /* intermediate row is 8-bit deep */
17722 
17723 #ifdef MNG_SUPPORT_TRACE
17724   MNG_TRACE (pData, MNG_FN_INIT_IDX2_NI, MNG_LC_END);
17725 #endif
17726 
17727   return mng_init_rowproc (pData);
17728 }
17729 
17730 /* ************************************************************************** */
17731 
mng_init_idx2_i(mng_datap pData)17732 mng_retcode mng_init_idx2_i    (mng_datap pData)
17733 {
17734 #ifdef MNG_SUPPORT_TRACE
17735   MNG_TRACE (pData, MNG_FN_INIT_IDX2_I, MNG_LC_START);
17736 #endif
17737 
17738   if (pData->fDisplayrow)
17739     pData->fProcessrow = (mng_fptr)mng_process_idx2;
17740 
17741   if (pData->pStoreobj)                /* store in object too ? */
17742   {                                    /* immediate delta ? */
17743 #ifndef MNG_NO_DELTA_PNG
17744     if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
17745       pData->fStorerow = (mng_fptr)mng_delta_idx2;
17746     else
17747 #endif
17748       pData->fStorerow = (mng_fptr)mng_store_idx2;
17749   }
17750 
17751 #ifdef FILTER192                       /* leveling & differing ? */
17752   if (pData->iFilter == MNG_FILTER_DIFFERING)
17753     pData->fDifferrow  = (mng_fptr)mng_differ_idx2;
17754 #endif
17755 
17756   pData->iPass       = 0;              /* from 0..6; is 1..7 in specifications */
17757   pData->iRow        = interlace_row     [0];
17758   pData->iRowinc     = interlace_rowskip [0];
17759   pData->iCol        = interlace_col     [0];
17760   pData->iColinc     = interlace_colskip [0];
17761   pData->iRowsamples = (pData->iDatawidth + interlace_roundoff [0]) >> interlace_divider [0];
17762   pData->iSamplemul  = 1;
17763   pData->iSampleofs  = 3;
17764   pData->iSamplediv  = 2;
17765   pData->iRowsize    = (pData->iRowsamples + 3) >> 2;
17766   pData->iRowmax     = ((pData->iDatawidth + 3) >> 2) + pData->iPixelofs;
17767   pData->iFilterbpp  = 1;
17768   pData->bIsRGBA16   = MNG_FALSE;      /* intermediate row is 8-bit deep */
17769 
17770 #ifdef MNG_SUPPORT_TRACE
17771   MNG_TRACE (pData, MNG_FN_INIT_IDX2_I, MNG_LC_END);
17772 #endif
17773 
17774   return mng_init_rowproc (pData);
17775 }
17776 
17777 /* ************************************************************************** */
17778 
mng_init_idx4_ni(mng_datap pData)17779 mng_retcode mng_init_idx4_ni   (mng_datap pData)
17780 {
17781 #ifdef MNG_SUPPORT_TRACE
17782   MNG_TRACE (pData, MNG_FN_INIT_IDX4_NI, MNG_LC_START);
17783 #endif
17784 
17785   if (pData->fDisplayrow)
17786     pData->fProcessrow = (mng_fptr)mng_process_idx4;
17787 
17788   if (pData->pStoreobj)                /* store in object too ? */
17789   {                                    /* immediate delta ? */
17790 #ifndef MNG_NO_DELTA_PNG
17791     if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
17792       pData->fStorerow = (mng_fptr)mng_delta_idx4;
17793     else
17794 #endif
17795       pData->fStorerow = (mng_fptr)mng_store_idx4;
17796   }
17797 
17798 #ifdef FILTER192                       /* leveling & differing ? */
17799   if (pData->iFilter == MNG_FILTER_DIFFERING)
17800     pData->fDifferrow  = (mng_fptr)mng_differ_idx4;
17801 #endif
17802 
17803   pData->iPass       = -1;
17804   pData->iRow        = 0;
17805   pData->iRowinc     = 1;
17806   pData->iCol        = 0;
17807   pData->iColinc     = 1;
17808   pData->iRowsamples = pData->iDatawidth;
17809   pData->iSamplemul  = 1;
17810   pData->iSampleofs  = 1;
17811   pData->iSamplediv  = 1;
17812   pData->iRowsize    = (pData->iRowsamples + 1) >> 1;
17813   pData->iRowmax     = pData->iRowsize + pData->iPixelofs;
17814   pData->iFilterbpp  = 1;
17815   pData->bIsRGBA16   = MNG_FALSE;      /* intermediate row is 8-bit deep */
17816 
17817 #ifdef MNG_SUPPORT_TRACE
17818   MNG_TRACE (pData, MNG_FN_INIT_IDX4_NI, MNG_LC_END);
17819 #endif
17820 
17821   return mng_init_rowproc (pData);
17822 }
17823 
17824 /* ************************************************************************** */
17825 
mng_init_idx4_i(mng_datap pData)17826 mng_retcode mng_init_idx4_i    (mng_datap pData)
17827 {
17828 #ifdef MNG_SUPPORT_TRACE
17829   MNG_TRACE (pData, MNG_FN_INIT_IDX4_I, MNG_LC_START);
17830 #endif
17831 
17832   if (pData->fDisplayrow)
17833     pData->fProcessrow = (mng_fptr)mng_process_idx4;
17834 
17835   if (pData->pStoreobj)                /* store in object too ? */
17836   {                                    /* immediate delta ? */
17837 #ifndef MNG_NO_DELTA_PNG
17838     if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
17839       pData->fStorerow = (mng_fptr)mng_delta_idx4;
17840     else
17841 #endif
17842       pData->fStorerow = (mng_fptr)mng_store_idx4;
17843   }
17844 
17845 #ifdef FILTER192                       /* leveling & differing ? */
17846   if (pData->iFilter == MNG_FILTER_DIFFERING)
17847     pData->fDifferrow  = (mng_fptr)mng_differ_idx4;
17848 #endif
17849 
17850   pData->iPass       = 0;              /* from 0..6; is 1..7 in specifications */
17851   pData->iRow        = interlace_row     [0];
17852   pData->iRowinc     = interlace_rowskip [0];
17853   pData->iCol        = interlace_col     [0];
17854   pData->iColinc     = interlace_colskip [0];
17855   pData->iRowsamples = (pData->iDatawidth + interlace_roundoff [0]) >> interlace_divider [0];
17856   pData->iSamplemul  = 1;
17857   pData->iSampleofs  = 1;
17858   pData->iSamplediv  = 1;
17859   pData->iRowsize    = (pData->iRowsamples + 1) >> 1;
17860   pData->iRowmax     = ((pData->iDatawidth + 1) >> 1) + pData->iPixelofs;
17861   pData->iFilterbpp  = 1;
17862   pData->bIsRGBA16   = MNG_FALSE;      /* intermediate row is 8-bit deep */
17863 
17864 #ifdef MNG_SUPPORT_TRACE
17865   MNG_TRACE (pData, MNG_FN_INIT_IDX4_I, MNG_LC_END);
17866 #endif
17867 
17868   return mng_init_rowproc (pData);
17869 }
17870 #endif /* MNG_NO_1_2_4BIT_SUPPORT */
17871 
17872 /* ************************************************************************** */
17873 
mng_init_idx8_ni(mng_datap pData)17874 mng_retcode mng_init_idx8_ni   (mng_datap pData)
17875 {
17876 #ifdef MNG_SUPPORT_TRACE
17877   MNG_TRACE (pData, MNG_FN_INIT_IDX8_NI, MNG_LC_START);
17878 #endif
17879 
17880   if (pData->fDisplayrow)
17881     pData->fProcessrow = (mng_fptr)mng_process_idx8;
17882 
17883   if (pData->pStoreobj)                /* store in object too ? */
17884   {                                    /* immediate delta ? */
17885 #ifndef MNG_NO_DELTA_PNG
17886     if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
17887       pData->fStorerow = (mng_fptr)mng_delta_idx8;
17888     else
17889 #endif
17890       pData->fStorerow = (mng_fptr)mng_store_idx8;
17891   }
17892 
17893 #ifdef FILTER192                       /* leveling & differing ? */
17894   if (pData->iFilter == MNG_FILTER_DIFFERING)
17895     pData->fDifferrow  = (mng_fptr)mng_differ_idx8;
17896 #endif
17897 
17898   pData->iPass       = -1;
17899   pData->iRow        = 0;
17900   pData->iRowinc     = 1;
17901   pData->iCol        = 0;
17902   pData->iColinc     = 1;
17903   pData->iRowsamples = pData->iDatawidth;
17904   pData->iSamplemul  = 1;
17905   pData->iSampleofs  = 0;
17906   pData->iSamplediv  = 0;
17907   pData->iRowsize    = pData->iRowsamples;
17908   pData->iRowmax     = pData->iRowsize + pData->iPixelofs;
17909   pData->iFilterbpp  = 1;
17910   pData->bIsRGBA16   = MNG_FALSE;      /* intermediate row is 8-bit deep */
17911 
17912 #ifdef MNG_SUPPORT_TRACE
17913   MNG_TRACE (pData, MNG_FN_INIT_IDX8_NI, MNG_LC_END);
17914 #endif
17915 
17916   return mng_init_rowproc (pData);
17917 }
17918 
17919 /* ************************************************************************** */
17920 
mng_init_idx8_i(mng_datap pData)17921 mng_retcode mng_init_idx8_i    (mng_datap pData)
17922 {
17923 #ifdef MNG_SUPPORT_TRACE
17924   MNG_TRACE (pData, MNG_FN_INIT_IDX8_I, MNG_LC_START);
17925 #endif
17926 
17927   if (pData->fDisplayrow)
17928     pData->fProcessrow = (mng_fptr)mng_process_idx8;
17929 
17930   if (pData->pStoreobj)                /* store in object too ? */
17931   {                                    /* immediate delta ? */
17932 #ifndef MNG_NO_DELTA_PNG
17933     if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
17934       pData->fStorerow = (mng_fptr)mng_delta_idx8;
17935     else
17936 #endif
17937       pData->fStorerow = (mng_fptr)mng_store_idx8;
17938   }
17939 
17940 #ifdef FILTER192                       /* leveling & differing ? */
17941   if (pData->iFilter == MNG_FILTER_DIFFERING)
17942     pData->fDifferrow  = (mng_fptr)mng_differ_idx8;
17943 #endif
17944 
17945   pData->iPass       = 0;              /* from 0..6; is 1..7 in specifications */
17946   pData->iRow        = interlace_row     [0];
17947   pData->iRowinc     = interlace_rowskip [0];
17948   pData->iCol        = interlace_col     [0];
17949   pData->iColinc     = interlace_colskip [0];
17950   pData->iRowsamples = (pData->iDatawidth + interlace_roundoff [0]) >> interlace_divider [0];
17951   pData->iSamplemul  = 1;
17952   pData->iSampleofs  = 0;
17953   pData->iSamplediv  = 0;
17954   pData->iRowsize    = pData->iRowsamples;
17955   pData->iRowmax     = pData->iDatawidth + pData->iPixelofs;
17956   pData->iFilterbpp  = 1;
17957   pData->bIsRGBA16   = MNG_FALSE;      /* intermediate row is 8-bit deep */
17958 
17959 #ifdef MNG_SUPPORT_TRACE
17960   MNG_TRACE (pData, MNG_FN_INIT_IDX8_I, MNG_LC_END);
17961 #endif
17962 
17963   return mng_init_rowproc (pData);
17964 }
17965 
17966 /* ************************************************************************** */
17967 
mng_init_ga8_ni(mng_datap pData)17968 mng_retcode mng_init_ga8_ni    (mng_datap pData)
17969 {
17970 #ifdef MNG_SUPPORT_TRACE
17971   MNG_TRACE (pData, MNG_FN_INIT_GA8_NI, MNG_LC_START);
17972 #endif
17973 
17974   if (pData->fDisplayrow)
17975     pData->fProcessrow = (mng_fptr)mng_process_ga8;
17976 
17977   if (pData->pStoreobj)                /* store in object too ? */
17978   {                                    /* immediate delta ? */
17979 #ifndef MNG_NO_DELTA_PNG
17980     if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
17981       pData->fStorerow = (mng_fptr)mng_delta_ga8;
17982     else
17983 #endif
17984       pData->fStorerow = (mng_fptr)mng_store_ga8;
17985   }
17986 
17987 #ifdef FILTER192                       /* leveling & differing ? */
17988   if (pData->iFilter == MNG_FILTER_DIFFERING)
17989     pData->fDifferrow  = (mng_fptr)mng_differ_ga8;
17990 #endif
17991 
17992   pData->iPass       = -1;
17993   pData->iRow        = 0;
17994   pData->iRowinc     = 1;
17995   pData->iCol        = 0;
17996   pData->iColinc     = 1;
17997   pData->iRowsamples = pData->iDatawidth;
17998   pData->iSamplemul  = 2;
17999   pData->iSampleofs  = 0;
18000   pData->iSamplediv  = 0;
18001   pData->iRowsize    = pData->iRowsamples << 1;
18002   pData->iRowmax     = pData->iRowsize + pData->iPixelofs;
18003   pData->iFilterbpp  = 2;
18004   pData->bIsRGBA16   = MNG_FALSE;      /* intermediate row is 8-bit deep */
18005 
18006 #ifdef MNG_SUPPORT_TRACE
18007   MNG_TRACE (pData, MNG_FN_INIT_GA8_NI, MNG_LC_END);
18008 #endif
18009 
18010   return mng_init_rowproc (pData);
18011 }
18012 
18013 /* ************************************************************************** */
18014 
mng_init_ga8_i(mng_datap pData)18015 mng_retcode mng_init_ga8_i     (mng_datap pData)
18016 {
18017 #ifdef MNG_SUPPORT_TRACE
18018   MNG_TRACE (pData, MNG_FN_INIT_GA8_I, MNG_LC_START);
18019 #endif
18020 
18021   if (pData->fDisplayrow)
18022     pData->fProcessrow = (mng_fptr)mng_process_ga8;
18023 
18024   if (pData->pStoreobj)                /* store in object too ? */
18025   {                                    /* immediate delta ? */
18026 #ifndef MNG_NO_DELTA_PNG
18027     if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
18028       pData->fStorerow = (mng_fptr)mng_delta_ga8;
18029     else
18030 #endif
18031       pData->fStorerow = (mng_fptr)mng_store_ga8;
18032   }
18033 
18034 #ifdef FILTER192                       /* leveling & differing ? */
18035   if (pData->iFilter == MNG_FILTER_DIFFERING)
18036     pData->fDifferrow  = (mng_fptr)mng_differ_ga8;
18037 #endif
18038 
18039   pData->iPass       = 0;              /* from 0..6; is 1..7 in specifications */
18040   pData->iRow        = interlace_row     [0];
18041   pData->iRowinc     = interlace_rowskip [0];
18042   pData->iCol        = interlace_col     [0];
18043   pData->iColinc     = interlace_colskip [0];
18044   pData->iRowsamples = (pData->iDatawidth + interlace_roundoff [0]) >> interlace_divider [0];
18045   pData->iSamplemul  = 2;
18046   pData->iSampleofs  = 0;
18047   pData->iSamplediv  = 0;
18048   pData->iRowsize    = pData->iRowsamples << 1;
18049   pData->iRowmax     = (pData->iDatawidth << 1) + pData->iPixelofs;
18050   pData->iFilterbpp  = 2;
18051   pData->bIsRGBA16   = MNG_FALSE;      /* intermediate row is 8-bit deep */
18052 
18053 #ifdef MNG_SUPPORT_TRACE
18054   MNG_TRACE (pData, MNG_FN_INIT_GA8_I, MNG_LC_END);
18055 #endif
18056 
18057   return mng_init_rowproc (pData);
18058 }
18059 
18060 /* ************************************************************************** */
18061 
18062 #ifndef MNG_NO_16BIT_SUPPORT
mng_init_ga16_ni(mng_datap pData)18063 mng_retcode mng_init_ga16_ni   (mng_datap pData)
18064 {
18065 #ifdef MNG_SUPPORT_TRACE
18066   MNG_TRACE (pData, MNG_FN_INIT_GA16_NI, MNG_LC_START);
18067 #endif
18068 
18069   if (pData->fDisplayrow)
18070     pData->fProcessrow = (mng_fptr)mng_process_ga16;
18071 
18072   if (pData->pStoreobj)                /* store in object too ? */
18073   {                                    /* immediate delta ? */
18074 #ifndef MNG_NO_DELTA_PNG
18075     if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
18076       pData->fStorerow = (mng_fptr)mng_delta_ga16;
18077     else
18078 #endif
18079       pData->fStorerow = (mng_fptr)mng_store_ga16;
18080   }
18081 
18082 #ifdef FILTER192                       /* leveling & differing ? */
18083   if (pData->iFilter == MNG_FILTER_DIFFERING)
18084     pData->fDifferrow  = (mng_fptr)mng_differ_ga16;
18085 #endif
18086 
18087   pData->iPass       = -1;
18088   pData->iRow        = 0;
18089   pData->iRowinc     = 1;
18090   pData->iCol        = 0;
18091   pData->iColinc     = 1;
18092   pData->iRowsamples = pData->iDatawidth;
18093   pData->iSamplemul  = 4;
18094   pData->iSampleofs  = 0;
18095   pData->iSamplediv  = 0;
18096   pData->iRowsize    = pData->iRowsamples << 2;
18097   pData->iRowmax     = pData->iRowsize + pData->iPixelofs;
18098   pData->iFilterbpp  = 4;
18099   pData->bIsRGBA16   = MNG_TRUE;       /* intermediate row is 16-bit deep */
18100 
18101 #ifdef MNG_SUPPORT_TRACE
18102   MNG_TRACE (pData, MNG_FN_INIT_GA16_NI, MNG_LC_END);
18103 #endif
18104 
18105   return mng_init_rowproc (pData);
18106 }
18107 #endif
18108 
18109 /* ************************************************************************** */
18110 
18111 #ifndef MNG_NO_16BIT_SUPPORT
mng_init_ga16_i(mng_datap pData)18112 mng_retcode mng_init_ga16_i    (mng_datap pData)
18113 {
18114 #ifdef MNG_SUPPORT_TRACE
18115   MNG_TRACE (pData, MNG_FN_INIT_GA16_I, MNG_LC_START);
18116 #endif
18117 
18118   if (pData->fDisplayrow)
18119     pData->fProcessrow = (mng_fptr)mng_process_ga16;
18120 
18121   if (pData->pStoreobj)                /* store in object too ? */
18122   {                                    /* immediate delta ? */
18123 #ifndef MNG_NO_DELTA_PNG
18124     if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
18125       pData->fStorerow = (mng_fptr)mng_delta_ga16;
18126     else
18127 #endif
18128       pData->fStorerow = (mng_fptr)mng_store_ga16;
18129   }
18130 
18131 #ifdef FILTER192                       /* leveling & differing ? */
18132   if (pData->iFilter == MNG_FILTER_DIFFERING)
18133     pData->fDifferrow  = (mng_fptr)mng_differ_ga16;
18134 #endif
18135 
18136   pData->iPass       = 0;              /* from 0..6; is 1..7 in specifications */
18137   pData->iRow        = interlace_row     [0];
18138   pData->iRowinc     = interlace_rowskip [0];
18139   pData->iCol        = interlace_col     [0];
18140   pData->iColinc     = interlace_colskip [0];
18141   pData->iRowsamples = (pData->iDatawidth + interlace_roundoff [0]) >> interlace_divider [0];
18142   pData->iSamplemul  = 4;
18143   pData->iSampleofs  = 0;
18144   pData->iSamplediv  = 0;
18145   pData->iRowsize    = pData->iRowsamples << 2;
18146   pData->iRowmax     = (pData->iDatawidth << 2) + pData->iPixelofs;
18147   pData->iFilterbpp  = 4;
18148   pData->bIsRGBA16   = MNG_TRUE;       /* intermediate row is 16-bit deep */
18149 
18150 #ifdef MNG_SUPPORT_TRACE
18151   MNG_TRACE (pData, MNG_FN_INIT_GA16_I, MNG_LC_END);
18152 #endif
18153 
18154   return mng_init_rowproc (pData);
18155 }
18156 #endif
18157 
18158 /* ************************************************************************** */
18159 
mng_init_rgba8_ni(mng_datap pData)18160 mng_retcode mng_init_rgba8_ni  (mng_datap pData)
18161 {
18162 #ifdef MNG_SUPPORT_TRACE
18163   MNG_TRACE (pData, MNG_FN_INIT_RGBA8_NI, MNG_LC_START);
18164 #endif
18165 
18166   if (pData->fDisplayrow)
18167     pData->fProcessrow = (mng_fptr)mng_process_rgba8;
18168 
18169   if (pData->pStoreobj)                /* store in object too ? */
18170   {                                    /* immediate delta ? */
18171 #ifndef MNG_NO_DELTA_PNG
18172     if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
18173       pData->fStorerow = (mng_fptr)mng_delta_rgba8;
18174     else
18175 #endif
18176       pData->fStorerow = (mng_fptr)mng_store_rgba8;
18177   }
18178 
18179 #ifdef FILTER192                       /* leveling & differing ? */
18180   if (pData->iFilter == MNG_FILTER_DIFFERING)
18181     pData->fDifferrow  = (mng_fptr)mng_differ_rgba8;
18182 #endif
18183 
18184   pData->iPass       = -1;
18185   pData->iRow        = 0;
18186   pData->iRowinc     = 1;
18187   pData->iCol        = 0;
18188   pData->iColinc     = 1;
18189   pData->iRowsamples = pData->iDatawidth;
18190   pData->iSamplemul  = 4;
18191   pData->iSampleofs  = 0;
18192   pData->iSamplediv  = 0;
18193   pData->iRowsize    = pData->iRowsamples << 2;
18194   pData->iRowmax     = pData->iRowsize + pData->iPixelofs;
18195   pData->iFilterbpp  = 4;
18196   pData->bIsRGBA16   = MNG_FALSE;      /* intermediate row is 8-bit deep */
18197 
18198 #ifdef MNG_SUPPORT_TRACE
18199   MNG_TRACE (pData, MNG_FN_INIT_RGBA8_NI, MNG_LC_END);
18200 #endif
18201 
18202   return mng_init_rowproc (pData);
18203 }
18204 /* ************************************************************************** */
18205 
mng_init_rgba8_i(mng_datap pData)18206 mng_retcode mng_init_rgba8_i   (mng_datap pData)
18207 {
18208 #ifdef MNG_SUPPORT_TRACE
18209   MNG_TRACE (pData, MNG_FN_INIT_RGBA8_I, MNG_LC_START);
18210 #endif
18211 
18212   if (pData->fDisplayrow)
18213     pData->fProcessrow = (mng_fptr)mng_process_rgba8;
18214 
18215   if (pData->pStoreobj)                /* store in object too ? */
18216   {                                    /* immediate delta ? */
18217 #ifndef MNG_NO_DELTA_PNG
18218     if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
18219       pData->fStorerow = (mng_fptr)mng_delta_rgba8;
18220     else
18221 #endif
18222       pData->fStorerow = (mng_fptr)mng_store_rgba8;
18223   }
18224 
18225 #ifdef FILTER192                       /* leveling & differing ? */
18226   if (pData->iFilter == MNG_FILTER_DIFFERING)
18227     pData->fDifferrow  = (mng_fptr)mng_differ_rgba8;
18228 #endif
18229 
18230   pData->iPass       = 0;              /* from 0..6; is 1..7 in specifications */
18231   pData->iRow        = interlace_row     [0];
18232   pData->iRowinc     = interlace_rowskip [0];
18233   pData->iCol        = interlace_col     [0];
18234   pData->iColinc     = interlace_colskip [0];
18235   pData->iRowsamples = (pData->iDatawidth + interlace_roundoff [0]) >> interlace_divider [0];
18236   pData->iSamplemul  = 4;
18237   pData->iSampleofs  = 0;
18238   pData->iSamplediv  = 0;
18239   pData->iRowsize    = pData->iRowsamples << 2;
18240   pData->iRowmax     = (pData->iDatawidth << 2) + pData->iPixelofs;
18241   pData->iFilterbpp  = 4;
18242   pData->bIsRGBA16   = MNG_FALSE;      /* intermediate row is 8-bit deep */
18243 
18244 #ifdef MNG_SUPPORT_TRACE
18245   MNG_TRACE (pData, MNG_FN_INIT_RGBA8_I, MNG_LC_END);
18246 #endif
18247 
18248   return mng_init_rowproc (pData);
18249 }
18250 
18251 /* ************************************************************************** */
18252 
18253 #ifndef MNG_NO_16BIT_SUPPORT
mng_init_rgba16_ni(mng_datap pData)18254 mng_retcode mng_init_rgba16_ni (mng_datap pData)
18255 {
18256 #ifdef MNG_SUPPORT_TRACE
18257   MNG_TRACE (pData, MNG_FN_INIT_RGBA16_NI, MNG_LC_START);
18258 #endif
18259 
18260   if (pData->fDisplayrow)
18261     pData->fProcessrow = (mng_fptr)mng_process_rgba16;
18262 
18263   if (pData->pStoreobj)                /* store in object too ? */
18264   {                                    /* immediate delta ? */
18265 #ifndef MNG_NO_DELTA_PNG
18266     if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
18267       pData->fStorerow = (mng_fptr)mng_delta_rgba16;
18268     else
18269 #endif
18270       pData->fStorerow = (mng_fptr)mng_store_rgba16;
18271   }
18272 
18273 #ifdef FILTER192                       /* leveling & differing ? */
18274   if (pData->iFilter == MNG_FILTER_DIFFERING)
18275     pData->fDifferrow  = (mng_fptr)mng_differ_rgba16;
18276 #endif
18277 
18278   pData->iPass       = -1;
18279   pData->iRow        = 0;
18280   pData->iRowinc     = 1;
18281   pData->iCol        = 0;
18282   pData->iColinc     = 1;
18283   pData->iRowsamples = pData->iDatawidth;
18284   pData->iSamplemul  = 8;
18285   pData->iSampleofs  = 0;
18286   pData->iSamplediv  = 0;
18287   pData->iRowsize    = pData->iRowsamples << 3;
18288   pData->iRowmax     = pData->iRowsize + pData->iPixelofs;
18289   pData->iFilterbpp  = 8;
18290   pData->bIsRGBA16   = MNG_TRUE;       /* intermediate row is 16-bit deep */
18291 
18292 #ifdef MNG_SUPPORT_TRACE
18293   MNG_TRACE (pData, MNG_FN_INIT_RGBA16_NI, MNG_LC_END);
18294 #endif
18295 
18296   return mng_init_rowproc (pData);
18297 }
18298 #endif
18299 
18300 /* ************************************************************************** */
18301 
18302 #ifndef MNG_NO_16BIT_SUPPORT
mng_init_rgba16_i(mng_datap pData)18303 mng_retcode mng_init_rgba16_i  (mng_datap pData)
18304 {
18305 #ifdef MNG_SUPPORT_TRACE
18306   MNG_TRACE (pData, MNG_FN_INIT_RGBA16_I, MNG_LC_START);
18307 #endif
18308 
18309   if (pData->fDisplayrow)
18310     pData->fProcessrow = (mng_fptr)mng_process_rgba16;
18311 
18312   if (pData->pStoreobj)                /* store in object too ? */
18313   {                                    /* immediate delta ? */
18314 #ifndef MNG_NO_DELTA_PNG
18315     if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
18316       pData->fStorerow = (mng_fptr)mng_delta_rgba16;
18317     else
18318 #endif
18319       pData->fStorerow = (mng_fptr)mng_store_rgba16;
18320   }
18321 
18322 #ifdef FILTER192                       /* leveling & differing ? */
18323   if (pData->iFilter == MNG_FILTER_DIFFERING)
18324     pData->fDifferrow  = (mng_fptr)mng_differ_rgba16;
18325 #endif
18326 
18327   pData->iPass       = 0;              /* from 0..6; (1..7 in specification) */
18328   pData->iRow        = interlace_row     [0];
18329   pData->iRowinc     = interlace_rowskip [0];
18330   pData->iCol        = interlace_col     [0];
18331   pData->iColinc     = interlace_colskip [0];
18332   pData->iRowsamples = (pData->iDatawidth + interlace_roundoff [0]) >> interlace_divider [0];
18333   pData->iSamplemul  = 8;
18334   pData->iSampleofs  = 0;
18335   pData->iSamplediv  = 0;
18336   pData->iRowsize    = pData->iRowsamples << 3;
18337   pData->iRowmax     = (pData->iDatawidth << 3) + pData->iPixelofs;
18338   pData->iFilterbpp  = 8;
18339   pData->bIsRGBA16   = MNG_TRUE;       /* intermediate row is 16-bit deep */
18340 
18341 #ifdef MNG_SUPPORT_TRACE
18342   MNG_TRACE (pData, MNG_FN_INIT_RGBA16_I, MNG_LC_END);
18343 #endif
18344 
18345   return mng_init_rowproc (pData);
18346 }
18347 #endif
18348 
18349 /* ************************************************************************** */
18350 /* *                                                                        * */
18351 /* * Row processing initialization routines (JPEG) - set up the variables   * */
18352 /* * needed to process uncompressed row-data                                * */
18353 /* *                                                                        * */
18354 /* ************************************************************************** */
18355 
18356 #ifdef MNG_INCLUDE_JNG
18357 
18358 /* ************************************************************************** */
18359 
18360 #ifndef MNG_NO_1_2_4BIT_SUPPORT
mng_init_jpeg_a1_ni(mng_datap pData)18361 mng_retcode mng_init_jpeg_a1_ni     (mng_datap pData)
18362 {
18363 #ifdef MNG_SUPPORT_TRACE
18364   MNG_TRACE (pData, MNG_FN_INIT_JPEG_A1_NI, MNG_LC_START);
18365 #endif
18366 
18367   if (pData->pStoreobj)                /* store in object too ? */
18368   {
18369     if (pData->iJHDRimgbitdepth == 8)
18370     {
18371       switch (pData->iJHDRcolortype)
18372       {
18373         case 12 : { pData->fStorerow = (mng_fptr)mng_store_jpeg_g8_a1;   break; }
18374         case 14 : { pData->fStorerow = (mng_fptr)mng_store_jpeg_rgb8_a1; break; }
18375       }
18376     }
18377 
18378     /* TODO: bitdepth 12 & 20 */
18379 
18380   }
18381 
18382 #ifdef FILTER192                       /* leveling & differing ? */
18383   if (pData->iFilter == MNG_FILTER_DIFFERING)
18384     pData->fDifferrow  = (mng_fptr)mng_differ_g1;
18385 #endif
18386 
18387   pData->iPass       = -1;
18388   pData->iRow        = 0;
18389   pData->iRowinc     = 1;
18390   pData->iCol        = 0;
18391   pData->iColinc     = 1;
18392   pData->iRowsamples = pData->iDatawidth;
18393   pData->iSamplemul  = 1;
18394   pData->iSampleofs  = 7;
18395   pData->iSamplediv  = 3;
18396   pData->iRowsize    = (pData->iRowsamples + 7) >> 3;
18397   pData->iRowmax     = pData->iRowsize + pData->iPixelofs;
18398   pData->iFilterbpp  = 1;
18399 
18400 #ifdef MNG_SUPPORT_TRACE
18401   MNG_TRACE (pData, MNG_FN_INIT_JPEG_A1_NI, MNG_LC_END);
18402 #endif
18403 
18404   return mng_init_rowproc (pData);
18405 }
18406 
18407 /* ************************************************************************** */
18408 
mng_init_jpeg_a2_ni(mng_datap pData)18409 mng_retcode mng_init_jpeg_a2_ni     (mng_datap pData)
18410 {
18411 #ifdef MNG_SUPPORT_TRACE
18412   MNG_TRACE (pData, MNG_FN_INIT_JPEG_A2_NI, MNG_LC_START);
18413 #endif
18414 
18415   if (pData->pStoreobj)                /* store in object too ? */
18416   {
18417     if (pData->iJHDRimgbitdepth == 8)
18418     {
18419       switch (pData->iJHDRcolortype)
18420       {
18421         case 12 : { pData->fStorerow = (mng_fptr)mng_store_jpeg_g8_a2;   break; }
18422         case 14 : { pData->fStorerow = (mng_fptr)mng_store_jpeg_rgb8_a2; break; }
18423       }
18424     }
18425 
18426     /* TODO: bitdepth 12 & 20 */
18427 
18428   }
18429 
18430 #ifdef FILTER192                       /* leveling & differing ? */
18431   if (pData->iFilter == MNG_FILTER_DIFFERING)
18432     pData->fDifferrow  = (mng_fptr)mng_differ_g2;
18433 #endif
18434 
18435   pData->iPass       = -1;
18436   pData->iRow        = 0;
18437   pData->iRowinc     = 1;
18438   pData->iCol        = 0;
18439   pData->iColinc     = 1;
18440   pData->iRowsamples = pData->iDatawidth;
18441   pData->iSamplemul  = 1;
18442   pData->iSampleofs  = 3;
18443   pData->iSamplediv  = 2;
18444   pData->iRowsize    = (pData->iRowsamples + 3) >> 2;
18445   pData->iRowmax     = pData->iRowsize + pData->iPixelofs;
18446   pData->iFilterbpp  = 1;
18447 
18448 #ifdef MNG_SUPPORT_TRACE
18449   MNG_TRACE (pData, MNG_FN_INIT_JPEG_A2_NI, MNG_LC_END);
18450 #endif
18451 
18452   return mng_init_rowproc (pData);
18453 }
18454 
18455 /* ************************************************************************** */
18456 
mng_init_jpeg_a4_ni(mng_datap pData)18457 mng_retcode mng_init_jpeg_a4_ni     (mng_datap pData)
18458 {
18459 #ifdef MNG_SUPPORT_TRACE
18460   MNG_TRACE (pData, MNG_FN_INIT_JPEG_A4_NI, MNG_LC_START);
18461 #endif
18462 
18463   if (pData->pStoreobj)                /* store in object too ? */
18464   {
18465     if (pData->iJHDRimgbitdepth == 8)
18466     {
18467       switch (pData->iJHDRcolortype)
18468       {
18469         case 12 : { pData->fStorerow = (mng_fptr)mng_store_jpeg_g8_a4;   break; }
18470         case 14 : { pData->fStorerow = (mng_fptr)mng_store_jpeg_rgb8_a4; break; }
18471       }
18472     }
18473 
18474     /* TODO: bitdepth 12 & 20 */
18475 
18476   }
18477 
18478 #ifdef FILTER192                       /* leveling & differing ? */
18479   if (pData->iFilter == MNG_FILTER_DIFFERING)
18480     pData->fDifferrow  = (mng_fptr)mng_differ_g4;
18481 #endif
18482 
18483   pData->iPass       = -1;
18484   pData->iRow        = 0;
18485   pData->iRowinc     = 1;
18486   pData->iCol        = 0;
18487   pData->iColinc     = 1;
18488   pData->iRowsamples = pData->iDatawidth;
18489   pData->iSamplemul  = 1;
18490   pData->iSampleofs  = 1;
18491   pData->iSamplediv  = 1;
18492   pData->iRowsize    = (pData->iRowsamples + 1) >> 1;
18493   pData->iRowmax     = pData->iRowsize + pData->iPixelofs;
18494   pData->iFilterbpp  = 1;
18495 
18496 #ifdef MNG_SUPPORT_TRACE
18497   MNG_TRACE (pData, MNG_FN_INIT_JPEG_A4_NI, MNG_LC_END);
18498 #endif
18499 
18500   return mng_init_rowproc (pData);
18501 }
18502 #endif /* MNG_NO_1_2_4BIT_SUPPORT */
18503 
18504 /* ************************************************************************** */
18505 
mng_init_jpeg_a8_ni(mng_datap pData)18506 mng_retcode mng_init_jpeg_a8_ni     (mng_datap pData)
18507 {
18508 #ifdef MNG_SUPPORT_TRACE
18509   MNG_TRACE (pData, MNG_FN_INIT_JPEG_A8_NI, MNG_LC_START);
18510 #endif
18511 
18512   if (pData->pStoreobj)                /* store in object too ? */
18513   {
18514     if (pData->iJHDRimgbitdepth == 8)
18515     {
18516       switch (pData->iJHDRcolortype)
18517       {
18518         case 12 : { pData->fStorerow = (mng_fptr)mng_store_jpeg_g8_a8;   break; }
18519         case 14 : { pData->fStorerow = (mng_fptr)mng_store_jpeg_rgb8_a8; break; }
18520       }
18521     }
18522 
18523     /* TODO: bitdepth 12 & 20 */
18524 
18525   }
18526 
18527 #ifdef FILTER192                       /* leveling & differing ? */
18528   if (pData->iFilter == MNG_FILTER_DIFFERING)
18529     pData->fDifferrow  = (mng_fptr)mng_differ_g8;
18530 #endif
18531 
18532   pData->iPass       = -1;
18533   pData->iRow        = 0;
18534   pData->iRowinc     = 1;
18535   pData->iCol        = 0;
18536   pData->iColinc     = 1;
18537   pData->iRowsamples = pData->iDatawidth;
18538   pData->iSamplemul  = 1;
18539   pData->iSampleofs  = 0;
18540   pData->iSamplediv  = 0;
18541   pData->iRowsize    = pData->iRowsamples;
18542   pData->iRowmax     = pData->iRowsize + pData->iPixelofs;
18543   pData->iFilterbpp  = 1;
18544 
18545 #ifdef MNG_SUPPORT_TRACE
18546   MNG_TRACE (pData, MNG_FN_INIT_JPEG_A8_NI, MNG_LC_END);
18547 #endif
18548 
18549   return mng_init_rowproc (pData);
18550 }
18551 
18552 /* ************************************************************************** */
18553 
18554 #ifndef MNG_NO_16BIT_SUPPORT
mng_init_jpeg_a16_ni(mng_datap pData)18555 mng_retcode mng_init_jpeg_a16_ni    (mng_datap pData)
18556 {
18557 #ifdef MNG_SUPPORT_TRACE
18558   MNG_TRACE (pData, MNG_FN_INIT_JPEG_A16_NI, MNG_LC_START);
18559 #endif
18560 
18561   if (pData->pStoreobj)                /* store in object too ? */
18562   {
18563     if (pData->iJHDRimgbitdepth == 8)
18564     {
18565       switch (pData->iJHDRcolortype)
18566       {
18567         case 12 : { pData->fStorerow = (mng_fptr)mng_store_jpeg_g8_a16;   break; }
18568         case 14 : { pData->fStorerow = (mng_fptr)mng_store_jpeg_rgb8_a16; break; }
18569       }
18570     }
18571 
18572     /* TODO: bitdepth 12 & 20 */
18573 
18574   }
18575 
18576 #ifdef FILTER192                       /* leveling & differing ? */
18577   if (pData->iFilter == MNG_FILTER_DIFFERING)
18578     pData->fDifferrow  = (mng_fptr)mng_differ_g16;
18579 #endif
18580 
18581   pData->iPass       = -1;
18582   pData->iRow        = 0;
18583   pData->iRowinc     = 1;
18584   pData->iCol        = 0;
18585   pData->iColinc     = 1;
18586   pData->iRowsamples = pData->iDatawidth;
18587   pData->iSamplemul  = 2;
18588   pData->iSampleofs  = 0;
18589   pData->iSamplediv  = 0;
18590   pData->iRowsize    = pData->iRowsamples << 1;
18591   pData->iRowmax     = pData->iRowsize + pData->iPixelofs;
18592   pData->iFilterbpp  = 2;
18593 
18594 #ifdef MNG_SUPPORT_TRACE
18595   MNG_TRACE (pData, MNG_FN_INIT_JPEG_A16_NI, MNG_LC_END);
18596 #endif
18597 
18598   return mng_init_rowproc (pData);
18599 }
18600 #endif
18601 
18602 /* ************************************************************************** */
18603 
18604 #endif /* MNG_INCLUDE_JNG */
18605 #endif /* MNG_OPTIMIZE_FOOTPRINT_INIT */
18606 
18607 
18608 /* ************************************************************************** */
18609 /* *                                                                        * */
18610 /* * Generic row processing initialization & cleanup routines               * */
18611 /* * - initialize the buffers used by the row processing routines           * */
18612 /* * - cleanup the buffers used by the row processing routines              * */
18613 /* *                                                                        * */
18614 /* ************************************************************************** */
18615 
mng_init_rowproc(mng_datap pData)18616 mng_retcode mng_init_rowproc (mng_datap pData)
18617 {
18618 #ifdef MNG_SUPPORT_TRACE
18619   MNG_TRACE (pData, MNG_FN_INIT_ROWPROC, MNG_LC_START);
18620 #endif
18621 
18622 #ifdef MNG_OPTIMIZE_FOOTPRINT_INIT
18623   if (pData->ePng_imgtype != png_none)
18624   {
18625   if (pData->fDisplayrow)
18626     switch (pData->ePng_imgtype)
18627     {
18628 #ifndef MNG_NO_1_2_4BIT_SUPPORT
18629     case png_g1:
18630       pData->fProcessrow = (mng_fptr)mng_process_g1;
18631       break;
18632     case png_g2:
18633       pData->fProcessrow = (mng_fptr)mng_process_g2;
18634       break;
18635     case png_g4:
18636       pData->fProcessrow = (mng_fptr)mng_process_g4;
18637       break;
18638 #endif /* MNG_NO_1_2_4BIT_SUPPORT */
18639     case png_g8:
18640       pData->fProcessrow = (mng_fptr)mng_process_g8;
18641       break;
18642 #ifndef MNG_NO_1_2_4BIT_SUPPORT
18643     case png_idx1:
18644       pData->fProcessrow = (mng_fptr)mng_process_idx1;
18645       break;
18646     case png_idx2:
18647       pData->fProcessrow = (mng_fptr)mng_process_idx2;
18648       break;
18649     case png_idx4:
18650       pData->fProcessrow = (mng_fptr)mng_process_idx4;
18651       break;
18652 #endif /* MNG_NO_1_2_4BIT_SUPPORT */
18653     case png_idx8:
18654       pData->fProcessrow = (mng_fptr)mng_process_idx8;
18655       break;
18656     case png_ga8:
18657       pData->fProcessrow = (mng_fptr)mng_process_ga8;
18658       break;
18659     case png_rgb8:
18660       pData->fProcessrow = (mng_fptr)mng_process_rgb8;
18661       break;
18662     case png_rgba8:
18663       pData->fProcessrow = (mng_fptr)mng_process_rgba8;
18664       break;
18665 #ifndef MNG_NO_16BIT_SUPPORT
18666     case png_g16:
18667       pData->fProcessrow = (mng_fptr)mng_process_g16;
18668       break;
18669     case png_ga16:
18670       pData->fProcessrow = (mng_fptr)mng_process_ga16;
18671       break;
18672     case png_rgb16:
18673       pData->fProcessrow = (mng_fptr)mng_process_rgb16;
18674       break;
18675     case png_rgba16:
18676       pData->fProcessrow = (mng_fptr)mng_process_rgba16;
18677       break;
18678 #endif
18679     default:
18680       break;
18681     }
18682 
18683   if (pData->pStoreobj)                /* store in object too ? */
18684   {
18685 #ifndef MNG_NO_DELTA_PNG
18686   if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
18687     switch (pData->ePng_imgtype)
18688     {
18689 #ifndef MNG_NO_1_2_4BIT_SUPPORT
18690     case png_g1:
18691       pData->fStorerow = (mng_fptr)mng_delta_g1;
18692       break;
18693     case png_g2:
18694       pData->fStorerow = (mng_fptr)mng_delta_g2;
18695       break;
18696     case png_g4:
18697       pData->fStorerow = (mng_fptr)mng_delta_g4;
18698       break;
18699 #endif /* MNG_NO_1_2_4BIT_SUPPORT */
18700     case png_g8:
18701       pData->fStorerow = (mng_fptr)mng_delta_g8;
18702       break;
18703 #ifndef MNG_NO_1_2_4BIT_SUPPORT
18704     case png_idx1:
18705       pData->fStorerow = (mng_fptr)mng_delta_idx1;
18706       break;
18707     case png_idx2:
18708       pData->fStorerow = (mng_fptr)mng_delta_idx2;
18709       break;
18710     case png_idx4:
18711       pData->fStorerow = (mng_fptr)mng_delta_idx4;
18712       break;
18713 #endif /* MNG_NO_1_2_4BIT_SUPPORT */
18714     case png_idx8:
18715       pData->fStorerow = (mng_fptr)mng_delta_idx8;
18716       break;
18717     case png_ga8:
18718       pData->fStorerow = (mng_fptr)mng_delta_ga8;
18719       break;
18720     case png_rgb8:
18721       pData->fStorerow = (mng_fptr)mng_delta_rgb8;
18722       break;
18723     case png_rgba8:
18724       pData->fStorerow = (mng_fptr)mng_delta_rgba8;
18725       break;
18726 #ifndef MNG_NO_16BIT_SUPPORT
18727     case png_g16:
18728       pData->fStorerow = (mng_fptr)mng_delta_g16;
18729       break;
18730     case png_ga16:
18731       pData->fStorerow = (mng_fptr)mng_delta_ga16;
18732       break;
18733     case png_rgb16:
18734       pData->fStorerow = (mng_fptr)mng_delta_rgb16;
18735       break;
18736     case png_rgba16:
18737       pData->fStorerow = (mng_fptr)mng_delta_rgba16;
18738       break;
18739 #endif
18740     default:
18741       break;
18742     }
18743   else
18744 #endif  /* MNG_NO_DELTA_PNG */
18745     switch (pData->ePng_imgtype)
18746     {
18747 #ifndef MNG_NO_1_2_4BIT_SUPPORT
18748     case png_g1:
18749       pData->fStorerow = (mng_fptr)mng_store_g1;
18750       break;
18751     case png_g2:
18752       pData->fStorerow = (mng_fptr)mng_store_g2;
18753       break;
18754     case png_g4:
18755       pData->fStorerow = (mng_fptr)mng_store_g4;
18756       break;
18757 #endif /* MNG_NO_1_2_4BIT_SUPPORT */
18758     case png_g8:
18759       pData->fStorerow = (mng_fptr)mng_store_g8;
18760       break;
18761 #ifndef MNG_NO_1_2_4BIT_SUPPORT
18762     case png_idx1:
18763       pData->fStorerow = (mng_fptr)mng_store_idx1;
18764       break;
18765     case png_idx2:
18766       pData->fStorerow = (mng_fptr)mng_store_idx2;
18767       break;
18768     case png_idx4:
18769       pData->fStorerow = (mng_fptr)mng_store_idx4;
18770       break;
18771 #endif /* MNG_NO_1_2_4BIT_SUPPORT */
18772     case png_idx8:
18773       pData->fStorerow = (mng_fptr)mng_store_idx8;
18774       break;
18775     case png_ga8:
18776       pData->fStorerow = (mng_fptr)mng_store_ga8;
18777       break;
18778     case png_rgb8:
18779       pData->fStorerow = (mng_fptr)mng_store_rgb8;
18780       break;
18781     case png_rgba8:
18782       pData->fStorerow = (mng_fptr)mng_store_rgba8;
18783       break;
18784 #ifndef MNG_NO_16BIT_SUPPORT
18785     case png_g16:
18786       pData->fStorerow = (mng_fptr)mng_store_g16;
18787       break;
18788     case png_ga16:
18789       pData->fStorerow = (mng_fptr)mng_store_ga16;
18790       break;
18791     case png_rgb16:
18792       pData->fStorerow = (mng_fptr)mng_store_rgb16;
18793       break;
18794     case png_rgba16:
18795       pData->fStorerow = (mng_fptr)mng_store_rgba16;
18796       break;
18797 #endif
18798 
18799 #ifdef MNG_INCLUDE_JNG
18800 #ifndef MNG_NO_1_2_4BIT_SUPPORT
18801     case png_jpeg_a1:
18802 /*  if (pData->iJHDRimgbitdepth == 8) */
18803       {
18804         switch (pData->iJHDRcolortype)
18805         {
18806         case 12 :
18807           { pData->fStorerow = (mng_fptr)mng_store_jpeg_g8_a1;   break; }
18808         case 14 :
18809           { pData->fStorerow = (mng_fptr)mng_store_jpeg_rgb8_a1; break; }
18810         }
18811       }
18812       /* TODO: bitdepth 12 & 20 */
18813       break;
18814     case png_jpeg_a2:
18815 /*  if (pData->iJHDRimgbitdepth == 8) */
18816       {
18817         switch (pData->iJHDRcolortype)
18818         {
18819           case 12 :
18820             { pData->fStorerow = (mng_fptr)mng_store_jpeg_g8_a2;   break; }
18821           case 14 :
18822             { pData->fStorerow = (mng_fptr)mng_store_jpeg_rgb8_a2; break; }
18823         }
18824       }
18825       break;
18826       /* TODO: bitdepth 12 & 20 */
18827     case png_jpeg_a4:
18828 /*  if (pData->iJHDRimgbitdepth == 8) */
18829       {
18830         switch (pData->iJHDRcolortype)
18831         {
18832           case 12 :
18833            { pData->fStorerow = (mng_fptr)mng_store_jpeg_g8_a4;   break; }
18834           case 14 :
18835            { pData->fStorerow = (mng_fptr)mng_store_jpeg_rgb8_a4; break; }
18836         }
18837       }
18838       break;
18839 #endif /* MNG_NO_1_2_4BIT_SUPPORT */
18840       /* TODO: bitdepth 12 & 20 */
18841     case png_jpeg_a8:
18842 /*  if (pData->iJHDRimgbitdepth == 8) */
18843       {
18844         switch (pData->iJHDRcolortype)
18845         {
18846           case 12 :
18847             { pData->fStorerow = (mng_fptr)mng_store_jpeg_g8_a8;   break; }
18848           case 14 :
18849             { pData->fStorerow = (mng_fptr)mng_store_jpeg_rgb8_a8; break; }
18850         }
18851       }
18852       break;
18853       /* TODO: bitdepth 12 & 20 */
18854 #ifndef MNG_NO_16BIT_SUPPORT
18855     case png_jpeg_a16:
18856 /*  if (pData->iJHDRimgbitdepth == 8) */
18857       {
18858         switch (pData->iJHDRcolortype)
18859         {
18860           case 12 :
18861             { pData->fStorerow = (mng_fptr)mng_store_jpeg_g8_a16;   break; }
18862           case 14 :
18863             { pData->fStorerow = (mng_fptr)mng_store_jpeg_rgb8_a16; break; }
18864         }
18865       }
18866       break;
18867       /* TODO: bitdepth 12 & 20 */
18868 #endif
18869 #endif /* MNG_INCLUDE_JNG */
18870     default:
18871       break;
18872     }
18873   }
18874 
18875 #ifdef FILTER192                       /* leveling & differing ? */
18876   if (pData->iFilter == MNG_FILTER_DIFFERING)
18877   switch (pData->ePng_imgtype)
18878   {
18879 #ifndef MNG_NO_1_2_4BIT_SUPPORT
18880     case png_g1:
18881 #ifdef MNG_INCLUDE_JNG
18882     case png_jpeg_a1:
18883 #endif
18884       pData->fDifferrow  = (mng_fptr)mng_differ_g1;
18885       break;
18886     case png_g2:
18887 #ifdef MNG_INCLUDE_JNG
18888     case png_jpeg_a2:
18889 #endif
18890       pData->fDifferrow  = (mng_fptr)mng_differ_g2;
18891       break;
18892     case png_g4:
18893 #ifdef MNG_INCLUDE_JNG
18894     case png_jpeg_a4:
18895 #endif
18896       pData->fDifferrow  = (mng_fptr)mng_differ_g4;
18897       break;
18898 #endif /* MNG_NO_1_2_4BIT_SUPPORT */
18899     case png_g8:
18900 #ifdef MNG_INCLUDE_JNG
18901     case png_jpeg_a8:
18902 #endif
18903       pData->fDifferrow  = (mng_fptr)mng_differ_g8;
18904       break;
18905     case png_rgb8:
18906       pData->fDifferrow  = (mng_fptr)mng_differ_rgb8;
18907       break;
18908 #ifndef MNG_NO_1_2_4BIT_SUPPORT
18909     case png_idx1:
18910       pData->fDifferrow  = (mng_fptr)mng_differ_idx1;
18911       break;
18912     case png_idx2:
18913       pData->fDifferrow  = (mng_fptr)mng_differ_idx2;
18914       break;
18915     case png_idx4:
18916       pData->fDifferrow  = (mng_fptr)mng_differ_idx4;
18917       break;
18918 #endif /* MNG_NO_1_2_4BIT_SUPPORT */
18919     case png_idx8:
18920       pData->fDifferrow  = (mng_fptr)mng_differ_idx8;
18921       break;
18922     case png_ga8:
18923       pData->fDifferrow  = (mng_fptr)mng_differ_ga8;
18924       break;
18925     case png_rgb8:
18926       pData->fDifferrow  = (mng_fptr)mng_differ_rgb8;
18927       break;
18928     case png_rgba8:
18929       pData->fDifferrow  = (mng_fptr)mng_differ_rgba8;
18930       break;
18931 #ifndef MNG_NO_16BIT_SUPPORT
18932     case png_g16:
18933 #ifdef MNG_INCLUDE_JNG
18934     case png_jpeg_a16:
18935 #endif
18936       pData->fDifferrow  = (mng_fptr)mng_differ_g16;
18937       break;
18938     case png_ga16:
18939       pData->fDifferrow  = (mng_fptr)mng_differ_ga16;
18940       break;
18941     case png_rgb16:
18942       pData->fDifferrow  = (mng_fptr)mng_differ_rgb16;
18943       break;
18944     case png_rgba16:
18945       pData->fDifferrow  = (mng_fptr)mng_differ_rgba16;
18946       break;
18947 #endif
18948     default:
18949       break;
18950   }
18951 #endif
18952 
18953   switch (pData->ePng_imgtype)
18954   {
18955 #ifndef MNG_NO_1_2_4BIT_SUPPORT
18956     case png_g1:
18957     case png_idx1:
18958 #ifdef MNG_INCLUDE_JNG
18959     case png_jpeg_a1:
18960 #endif
18961         pData->iSamplemul  = 1;
18962         pData->iSampleofs  = 7;
18963         pData->iSamplediv  = 3;
18964         pData->iFilterbpp  = 1;
18965         break;
18966     case png_g2:
18967     case png_idx2:
18968 #ifdef MNG_INCLUDE_JNG
18969     case png_jpeg_a2:
18970 #endif
18971         pData->iSamplemul  = 1;
18972         pData->iSampleofs  = 3;
18973         pData->iSamplediv  = 2;
18974         pData->iFilterbpp  = 1;
18975         break;
18976     case png_g4:
18977     case png_idx4:
18978 #ifdef MNG_INCLUDE_JNG
18979     case png_jpeg_a4:
18980 #endif
18981         pData->iSamplemul  = 1;
18982         pData->iSampleofs  = 1;
18983         pData->iSamplediv  = 1;
18984         pData->iFilterbpp  = 1;
18985         break;
18986 #endif /* MNG_NO_1_2_4BIT_SUPPORT */
18987     case png_g8:
18988     case png_idx8:
18989 #ifdef MNG_INCLUDE_JNG
18990     case png_jpeg_a8:
18991 #endif
18992         pData->iSamplemul  = 1;
18993         pData->iSampleofs  = 0;
18994         pData->iSamplediv  = 0;
18995         pData->iFilterbpp  = 1;
18996         break;
18997     case png_ga8:
18998 #ifndef MNG_NO_16BIT_SUPPORT
18999     case png_g16:
19000 #ifdef MNG_INCLUDE_JNG
19001     case png_jpeg_a16:
19002 #endif
19003 #endif
19004         pData->iSamplemul  = 2;
19005         pData->iSampleofs  = 0;
19006         pData->iSamplediv  = 0;
19007         pData->iFilterbpp  = 2;
19008         break;
19009     case png_rgb8:
19010         pData->iSamplemul  = 3;
19011         pData->iSampleofs  = 0;
19012         pData->iSamplediv  = 0;
19013         pData->iFilterbpp  = 3;
19014         break;
19015 #ifndef MNG_NO_16BIT_SUPPORT
19016     case png_ga16:
19017 #endif
19018     case png_rgba8:
19019         pData->iSamplemul  = 4;
19020         pData->iSampleofs  = 0;
19021         pData->iSamplediv  = 0;
19022         pData->iFilterbpp  = 4;
19023         break;
19024 #ifndef MNG_NO_16BIT_SUPPORT
19025     case png_rgb16:
19026         pData->iSamplemul  = 6;
19027         pData->iSampleofs  = 0;
19028         pData->iSamplediv  = 0;
19029         pData->iFilterbpp  = 6;
19030         break;
19031     case png_rgba16:
19032         pData->iSamplemul  = 8;
19033         pData->iSampleofs  = 0;
19034         pData->iSamplediv  = 0;
19035         pData->iFilterbpp  = 8;
19036         break;
19037 #endif
19038     default:
19039         break;
19040   }
19041 
19042   if (pData->iInterlace)               /* noninterlaced */
19043   {
19044     pData->iPass       = 0;      /* from 0..6; (1..7 in specification) */
19045     pData->iRow        = interlace_row     [0];
19046     pData->iRowinc     = interlace_rowskip [0];
19047     pData->iCol        = interlace_col     [0];
19048     pData->iColinc     = interlace_colskip [0];
19049     pData->iRowsamples = (pData->iDatawidth + interlace_roundoff [0]) >>
19050        interlace_divider [0];
19051     pData->iRowmax     = ((pData->iDatawidth * pData->iSamplemul +
19052        pData->iSampleofs) >> pData->iSamplediv) + pData->iPixelofs;
19053   }
19054   else                                 /* interlaced */
19055   {
19056     pData->iPass       = -1;
19057     pData->iRow        = 0;
19058     pData->iRowinc     = 1;
19059     pData->iCol        = 0;
19060     pData->iColinc     = 1;
19061     pData->iRowsamples = pData->iDatawidth;
19062   }
19063   if (pData->iSamplediv > 0)
19064      pData->iRowsize    = (pData->iRowsamples + pData->iSampleofs) >>
19065          pData->iSamplediv;
19066   else
19067      pData->iRowsize    = (pData->iRowsamples * pData->iSamplemul);
19068 
19069   if (!pData->iInterlace)               /* noninterlaced */
19070      pData->iRowmax     = pData->iRowsize + pData->iPixelofs;
19071 
19072 #ifdef MNG_NO_16BIT_SUPPORT
19073   pData->bIsRGBA16 = MNG_FALSE;
19074 #else
19075   switch (pData->ePng_imgtype)
19076   {
19077     case png_g16:
19078     case png_ga16:
19079     case png_rgb16:
19080     case png_rgba16:
19081        pData->bIsRGBA16 = MNG_TRUE;
19082        break;
19083     default:
19084        pData->bIsRGBA16 = MNG_FALSE;
19085        break;
19086   }
19087 #endif
19088 
19089   }
19090 #endif /* MNG_OPTIMIZE_FOOTPRINT_INIT */
19091 
19092   if (pData->pStoreobj)                /* storage object selected ? */
19093   {
19094     pData->pStorebuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
19095                                        /* and so it becomes viewable ! */
19096     ((mng_imagep)pData->pStoreobj)->bViewable     = MNG_TRUE;
19097     ((mng_imagedatap)pData->pStorebuf)->bViewable = MNG_TRUE;
19098   }
19099 
19100   /* allocate the buffers; the individual init routines have already
19101      calculated the required maximum size; except in the case of a JNG
19102      without alpha!!! */
19103   if (pData->iRowmax)
19104   {
19105 #if defined(MNG_NO_16BIT_SUPPORT) || defined (MNG_NO_1_2_4BIT_SUPPORT)
19106     mng_uint8 iRowadd = 0;
19107 #ifdef MNG_NO_1_2_4BIT_SUPPORT
19108     if (pData->iPNGdepth < 8)
19109        iRowadd=(pData->iPNGdepth*pData->iRowmax+7)/8;
19110 #endif
19111 #ifdef MNG_NO_16BIT_SUPPORT
19112     if (pData->iPNGdepth > 8)
19113        iRowadd=pData->iRowmax;
19114 #endif
19115     MNG_ALLOC (pData, pData->pWorkrow, pData->iRowmax+iRowadd);
19116     MNG_ALLOC (pData, pData->pPrevrow, pData->iRowmax+iRowadd);
19117 #else
19118     MNG_ALLOC (pData, pData->pWorkrow, pData->iRowmax);
19119     MNG_ALLOC (pData, pData->pPrevrow, pData->iRowmax);
19120 #endif
19121   }
19122 
19123   /* allocate an RGBA16 row for intermediate processing */
19124   MNG_ALLOC (pData, pData->pRGBArow, (pData->iDatawidth << 3));
19125 
19126 #ifndef MNG_NO_CMS
19127   if (pData->fDisplayrow)              /* display "on-the-fly" ? */
19128   {
19129 #if defined(MNG_FULL_CMS)              /* determine color-management initialization */
19130     mng_retcode iRetcode = mng_init_full_cms   (pData, MNG_TRUE, MNG_TRUE, MNG_FALSE);
19131 #elif defined(MNG_GAMMA_ONLY)
19132     mng_retcode iRetcode = mng_init_gamma_only (pData, MNG_TRUE, MNG_TRUE, MNG_FALSE);
19133 #elif defined(MNG_APP_CMS)
19134     mng_retcode iRetcode = mng_init_app_cms    (pData, MNG_TRUE, MNG_TRUE, MNG_FALSE);
19135 #endif
19136     if (iRetcode)                      /* on error bail out */
19137       return iRetcode;
19138   }
19139 #endif /* !MNG_NO_CMS */
19140 
19141 #ifdef MNG_SUPPORT_TRACE
19142   MNG_TRACE (pData, MNG_FN_INIT_ROWPROC, MNG_LC_END);
19143 #endif
19144 
19145   return MNG_NOERROR;
19146 }
19147 
19148 /* ************************************************************************** */
19149 
mng_next_row(mng_datap pData)19150 mng_retcode mng_next_row (mng_datap pData)
19151 {
19152 #ifdef MNG_SUPPORT_TRACE
19153   MNG_TRACE (pData, MNG_FN_NEXT_ROW, MNG_LC_START);
19154 #endif
19155 
19156   pData->iRow += pData->iRowinc;       /* increase the row counter */
19157 
19158   if (pData->iPass >= 0)               /* interlaced ? */
19159   {
19160     while ((pData->iPass < 7) &&       /* went 'outside' the image ? */
19161            ((pData->iRow >= (mng_int32)pData->iDataheight) ||
19162             (pData->iCol >= (mng_int32)pData->iDatawidth )    ))
19163     {
19164       pData->iPass++;                  /* next pass ! */
19165 
19166       if (pData->iPass < 7)            /* there's only 7 passes ! */
19167       {
19168         pData->iRow        = interlace_row     [pData->iPass];
19169         pData->iRowinc     = interlace_rowskip [pData->iPass];
19170         pData->iCol        = interlace_col     [pData->iPass];
19171         pData->iColinc     = interlace_colskip [pData->iPass];
19172         pData->iRowsamples = (pData->iDatawidth - pData->iCol + interlace_roundoff [pData->iPass])
19173                                  >> interlace_divider [pData->iPass];
19174 
19175         if (pData->iSamplemul > 1)     /* recalculate row dimension */
19176           pData->iRowsize  = pData->iRowsamples * pData->iSamplemul;
19177         else
19178         if (pData->iSamplediv > 0)
19179           pData->iRowsize  = (pData->iRowsamples + pData->iSampleofs) >> pData->iSamplediv;
19180         else
19181           pData->iRowsize  = pData->iRowsamples;
19182 
19183       }
19184 
19185       if ((pData->iPass < 7) &&        /* reset previous row to zeroes ? */
19186           (pData->iRow  < (mng_int32)pData->iDataheight) &&
19187           (pData->iCol  < (mng_int32)pData->iDatawidth )    )
19188       {                                /* making sure the filters will work properly! */
19189         mng_int32  iX;
19190         mng_uint8p pTemp = pData->pPrevrow;
19191 
19192 #ifdef MNG_NO_16BIT_SUPPORT
19193 #ifdef MNG_DECREMENT_LOOPS
19194         for (iX = pData->iPNGmult*pData->iRowsize; iX > 0; iX--)
19195 #else
19196         for (iX = 0; iX < pData->iPNGmult*pData->iRowsize; iX++)
19197 #endif
19198 #else
19199 #ifdef MNG_DECREMENT_LOOPS
19200         for (iX = pData->iRowsize; iX > 0; iX--)
19201 #else
19202         for (iX = 0; iX < pData->iRowsize; iX++)
19203 #endif
19204 #endif
19205         {
19206           *pTemp = 0;
19207           pTemp++;
19208         }
19209       }
19210     }
19211   }
19212 
19213 #ifdef MNG_SUPPORT_TRACE
19214   MNG_TRACE (pData, MNG_FN_NEXT_ROW, MNG_LC_END);
19215 #endif
19216 
19217   return MNG_NOERROR;
19218 }
19219 
19220 /* ************************************************************************** */
19221 
mng_cleanup_rowproc(mng_datap pData)19222 mng_retcode mng_cleanup_rowproc (mng_datap pData)
19223 {
19224 #ifdef MNG_SUPPORT_TRACE
19225   MNG_TRACE (pData, MNG_FN_CLEANUP_ROWPROC, MNG_LC_START);
19226 #endif
19227 
19228 #ifdef MNG_INCLUDE_LCMS                /* cleanup cms profile/transform */
19229   {
19230     mng_retcode iRetcode = mng_clear_cms (pData);
19231     if (iRetcode)                      /* on error bail out */
19232       return iRetcode;
19233   }
19234 #endif /* MNG_INCLUDE_LCMS */
19235 
19236   if (pData->pRGBArow)                 /* cleanup buffer for intermediate row */
19237     MNG_FREEX (pData, pData->pRGBArow, (pData->iDatawidth << 3));
19238   if (pData->pPrevrow)                 /* cleanup buffer for previous row */
19239     MNG_FREEX (pData, pData->pPrevrow, pData->iRowmax);
19240   if (pData->pWorkrow)                 /* cleanup buffer for working row */
19241     MNG_FREEX (pData, pData->pWorkrow, pData->iRowmax);
19242 
19243   pData->pWorkrow = MNG_NULL;          /* propogate uninitialized buffers */
19244   pData->pPrevrow = MNG_NULL;
19245   pData->pRGBArow = MNG_NULL;
19246 
19247 #ifdef MNG_SUPPORT_TRACE
19248   MNG_TRACE (pData, MNG_FN_CLEANUP_ROWPROC, MNG_LC_END);
19249 #endif
19250 
19251   return MNG_NOERROR;                  /* woohiii */
19252 }
19253 
19254 /* ************************************************************************** */
19255 /* *                                                                        * */
19256 /* * Generic row processing routines for JNG                                * */
19257 /* *                                                                        * */
19258 /* ************************************************************************** */
19259 
19260 #ifdef MNG_INCLUDE_JNG
19261 
19262 /* ************************************************************************** */
19263 
mng_display_jpeg_rows(mng_datap pData)19264 mng_retcode mng_display_jpeg_rows (mng_datap pData)
19265 {
19266   mng_retcode iRetcode;
19267 
19268 #ifdef MNG_SUPPORT_TRACE
19269   MNG_TRACE (pData, MNG_FN_DISPLAY_JPEG_ROWS, MNG_LC_START);
19270 #endif
19271                                        /* any completed rows ? */
19272   if ((pData->iJPEGrow      > pData->iJPEGdisprow) &&
19273       (pData->iJPEGalpharow > pData->iJPEGdisprow)    )
19274   {
19275     mng_uint32 iX, iMax;
19276     mng_uint32 iSaverow = pData->iRow; /* save alpha decompression row-count */
19277                                        /* determine the highest complete(!) row */
19278     if (pData->iJPEGrow > pData->iJPEGalpharow)
19279       iMax = pData->iJPEGalpharow;
19280     else
19281       iMax = pData->iJPEGrow;
19282                                        /* display the rows */
19283     for (iX = pData->iJPEGdisprow; iX < iMax; iX++)
19284     {
19285       pData->iRow = iX;                /* make sure we all know which row to handle */
19286                                        /* makeup an intermediate row from the buffer */
19287       iRetcode = ((mng_retrieverow)pData->fRetrieverow) (pData);
19288                                        /* color-correct it if necessary */
19289       if ((!iRetcode) && (pData->fCorrectrow))
19290         iRetcode = ((mng_correctrow)pData->fCorrectrow) (pData);
19291 
19292       if (!iRetcode)                   /* and display it */
19293       {
19294         iRetcode = ((mng_displayrow)pData->fDisplayrow) (pData);
19295 
19296         if (!iRetcode)                 /* check progressive display refresh */
19297           iRetcode = mng_display_progressive_check (pData);
19298       }
19299 
19300       if (iRetcode)                    /* on error bail out */
19301         return iRetcode;
19302     }
19303 
19304     pData->iJPEGdisprow = iMax;        /* keep track of the last displayed row */
19305     pData->iRow         = iSaverow;    /* restore alpha decompression row-count */
19306   }
19307 
19308 #ifdef MNG_SUPPORT_TRACE
19309   MNG_TRACE (pData, MNG_FN_DISPLAY_JPEG_ROWS, MNG_LC_END);
19310 #endif
19311 
19312   return MNG_NOERROR;
19313 }
19314 
19315 /* ************************************************************************** */
19316 
mng_next_jpeg_alpharow(mng_datap pData)19317 mng_retcode mng_next_jpeg_alpharow (mng_datap pData)
19318 {
19319   mng_retcode iRetcode;
19320 
19321 #ifdef MNG_SUPPORT_TRACE
19322   MNG_TRACE (pData, MNG_FN_NEXT_JPEG_ALPHAROW, MNG_LC_START);
19323 #endif
19324 
19325   pData->iJPEGalpharow++;              /* count the row */
19326 
19327   if (pData->fDisplayrow)              /* display "on-the-fly" ? */
19328   {                                    /* try to display what you can */
19329     iRetcode = mng_display_jpeg_rows (pData);
19330 
19331     if (iRetcode)                      /* on error bail out */
19332       return iRetcode;
19333   }
19334 
19335 #ifdef MNG_SUPPORT_TRACE
19336   MNG_TRACE (pData, MNG_FN_NEXT_JPEG_ALPHAROW, MNG_LC_END);
19337 #endif
19338 
19339   return MNG_NOERROR;
19340 }
19341 
19342 /* ************************************************************************** */
19343 
mng_next_jpeg_row(mng_datap pData)19344 mng_retcode mng_next_jpeg_row (mng_datap pData)
19345 {
19346   mng_retcode iRetcode;
19347 
19348 #ifdef MNG_SUPPORT_TRACE
19349   MNG_TRACE (pData, MNG_FN_NEXT_JPEG_ROW, MNG_LC_START);
19350 #endif
19351 
19352   pData->iJPEGrow++;                   /* increase the row-counter */
19353 
19354   if (pData->fDisplayrow)              /* display "on-the-fly" ? */
19355   {                                    /* has alpha channel ? */
19356     if ((pData->iJHDRcolortype == MNG_COLORTYPE_JPEGGRAYA ) ||
19357         (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGCOLORA)    )
19358     {                                  /* try to display what you can */
19359       iRetcode = mng_display_jpeg_rows (pData);
19360     }
19361     else
19362     {                                  /* make sure we all know which row to handle */
19363       pData->iRow = pData->iJPEGrow - 1;
19364                                        /* makeup an intermediate row from the buffer */
19365       iRetcode = ((mng_retrieverow)pData->fRetrieverow) (pData);
19366                                        /* color-correct it if necessary */
19367       if ((!iRetcode) && (pData->fCorrectrow))
19368         iRetcode = ((mng_correctrow)pData->fCorrectrow) (pData);
19369 
19370       if (!iRetcode)                   /* and display it */
19371       {
19372         iRetcode = ((mng_displayrow)pData->fDisplayrow) (pData);
19373 
19374         if (!iRetcode)                 /* check progressive display refresh */
19375           iRetcode = mng_display_progressive_check (pData);
19376       }
19377     }
19378 
19379     if (iRetcode)                      /* on error bail out */
19380       return iRetcode;
19381   }
19382 
19383                                        /* surpassed last filled row ? */
19384   if (pData->iJPEGrow > pData->iJPEGrgbrow)
19385     pData->iJPEGrgbrow = pData->iJPEGrow;
19386 
19387 #ifdef MNG_SUPPORT_TRACE
19388   MNG_TRACE (pData, MNG_FN_NEXT_JPEG_ROW, MNG_LC_END);
19389 #endif
19390 
19391   return MNG_NOERROR;
19392 }
19393 
19394 /* ************************************************************************** */
19395 
19396 #endif /* MNG_INCLUDE_JNG */
19397 
19398 /* ************************************************************************** */
19399 
19400 #ifndef MNG_SKIPCHUNK_MAGN
19401 #ifndef MNG_OPTIMIZE_FOOTPRINT_MAGN
19402 #ifndef MNG_NO_GRAY_SUPPORT
mng_magnify_g8_x1(mng_datap pData,mng_uint16 iMX,mng_uint16 iML,mng_uint16 iMR,mng_uint32 iWidth,mng_uint8p pSrcline,mng_uint8p pDstline)19403 mng_retcode mng_magnify_g8_x1 (mng_datap  pData,
19404                                mng_uint16 iMX,
19405                                mng_uint16 iML,
19406                                mng_uint16 iMR,
19407                                mng_uint32 iWidth,
19408                                mng_uint8p pSrcline,
19409                                mng_uint8p pDstline)
19410 {
19411   mng_uint32 iX, iS, iM;
19412   mng_uint8p pTempsrc1;
19413   mng_uint8p pTempdst;
19414 
19415 #ifdef MNG_SUPPORT_TRACE
19416   MNG_TRACE (pData, MNG_FN_MAGNIFY_G8_X1, MNG_LC_START);
19417 #endif
19418 
19419   pTempsrc1 = pSrcline;                /* initialize pixel-loop */
19420   pTempdst  = pDstline;
19421 
19422   for (iX = 0; iX < iWidth; iX++)
19423   {
19424     *pTempdst = *pTempsrc1;            /* copy original source pixel */
19425     pTempdst++;
19426 
19427     if (iX == 0)                       /* first interval ? */
19428       iM = iML;
19429     else
19430     if (iX == (iWidth - 1))            /* last interval ? */
19431       iM = iMR;
19432     else
19433       iM = iMX;
19434 
19435     for (iS = 1; iS < iM; iS++)        /* fill interval */
19436     {
19437       *pTempdst = *pTempsrc1;          /* copy original source pixel */
19438       pTempdst++;
19439     }
19440 
19441     pTempsrc1++;
19442   }
19443 
19444 #ifdef MNG_SUPPORT_TRACE
19445   MNG_TRACE (pData, MNG_FN_MAGNIFY_G8_X1, MNG_LC_END);
19446 #endif
19447 
19448   return MNG_NOERROR;
19449 }
19450 
19451 /* ************************************************************************** */
19452 
mng_magnify_g8_x2(mng_datap pData,mng_uint16 iMX,mng_uint16 iML,mng_uint16 iMR,mng_uint32 iWidth,mng_uint8p pSrcline,mng_uint8p pDstline)19453 mng_retcode mng_magnify_g8_x2 (mng_datap  pData,
19454                                mng_uint16 iMX,
19455                                mng_uint16 iML,
19456                                mng_uint16 iMR,
19457                                mng_uint32 iWidth,
19458                                mng_uint8p pSrcline,
19459                                mng_uint8p pDstline)
19460 {
19461   mng_uint32 iX;
19462   mng_int32  iS, iM;
19463   mng_uint8p pTempsrc1;
19464   mng_uint8p pTempsrc2;
19465   mng_uint8p pTempdst;
19466 
19467 #ifdef MNG_SUPPORT_TRACE
19468   MNG_TRACE (pData, MNG_FN_MAGNIFY_G8_X2, MNG_LC_START);
19469 #endif
19470 
19471   pTempsrc1 = pSrcline;                /* initialize pixel-loop */
19472   pTempdst  = pDstline;
19473 
19474   for (iX = 0; iX < iWidth; iX++)
19475   {
19476     pTempsrc2 = pTempsrc1 + 1;
19477 
19478     *pTempdst = *pTempsrc1;            /* copy original source pixel */
19479     pTempdst++;
19480 
19481     if (iX == 0)                       /* first interval ? */
19482     {
19483       if (iWidth == 1)                 /* single pixel ? */
19484         pTempsrc2 = MNG_NULL;
19485 
19486       iM = iML;
19487     }
19488     else
19489     if (iX == (iWidth - 2))            /* last interval ? */
19490       iM = iMR;
19491     else
19492       iM = iMX;
19493                                        /* fill interval ? */
19494     if ((iX < iWidth - 1) || (iWidth == 1))
19495     {
19496       if (pTempsrc2)                   /* do we have the second pixel ? */
19497       {                                /* is it same as first ? */
19498         if (*pTempsrc1 == *pTempsrc2)
19499         {
19500           for (iS = 1; iS < iM; iS++)  /* then just repeat the first */
19501           {
19502             *pTempdst = *pTempsrc1;
19503             pTempdst++;
19504           }
19505         }
19506         else
19507         {
19508           for (iS = 1; iS < iM; iS++)  /* calculate the distances */
19509           {
19510             *pTempdst = (mng_uint8)(((2 * iS * ( (mng_int32)(*pTempsrc2)     -
19511                                                  (mng_int32)(*pTempsrc1)     ) + iM) /
19512                                      (iM * 2)) + (mng_int32)(*pTempsrc1)             );
19513             pTempdst++;
19514           }
19515         }
19516       }
19517       else
19518       {
19519         for (iS = 1; iS < iM; iS++)
19520         {
19521           *pTempdst = *pTempsrc1;      /* repeat first source pixel */
19522           pTempdst++;
19523         }
19524       }
19525     }
19526 
19527     pTempsrc1++;
19528   }
19529 
19530 #ifdef MNG_SUPPORT_TRACE
19531   MNG_TRACE (pData, MNG_FN_MAGNIFY_G8_X2, MNG_LC_END);
19532 #endif
19533 
19534   return MNG_NOERROR;
19535 }
19536 
19537 /* ************************************************************************** */
19538 
mng_magnify_g8_x3(mng_datap pData,mng_uint16 iMX,mng_uint16 iML,mng_uint16 iMR,mng_uint32 iWidth,mng_uint8p pSrcline,mng_uint8p pDstline)19539 mng_retcode mng_magnify_g8_x3 (mng_datap  pData,
19540                                mng_uint16 iMX,
19541                                mng_uint16 iML,
19542                                mng_uint16 iMR,
19543                                mng_uint32 iWidth,
19544                                mng_uint8p pSrcline,
19545                                mng_uint8p pDstline)
19546 {
19547   mng_uint32 iX;
19548   mng_int32  iS, iM, iH;
19549   mng_uint8p pTempsrc1;
19550   mng_uint8p pTempsrc2;
19551   mng_uint8p pTempdst;
19552 
19553 #ifdef MNG_SUPPORT_TRACE
19554   MNG_TRACE (pData, MNG_FN_MAGNIFY_G8_X3, MNG_LC_START);
19555 #endif
19556 
19557   pTempsrc1 = pSrcline;                /* initialize pixel-loop */
19558   pTempdst  = pDstline;
19559 
19560   for (iX = 0; iX < iWidth; iX++)
19561   {
19562     pTempsrc2 = pTempsrc1 + 1;
19563 
19564     *pTempdst = *pTempsrc1;            /* copy original source pixel */
19565     pTempdst++;
19566 
19567     if (iX == 0)                       /* first interval ? */
19568     {
19569       if (iWidth == 1)                 /* single pixel ? */
19570         pTempsrc2 = MNG_NULL;
19571 
19572       iM = iML;
19573     }
19574     else
19575     if (iX == (iWidth - 2))            /* last interval ? */
19576       iM = iMR;
19577     else
19578       iM = iMX;
19579                                        /* fill interval ? */
19580     if ((iX < iWidth - 1) || (iWidth == 1))
19581     {
19582       if (pTempsrc2)                   /* do we have the second pixel ? */
19583       {                                /* is it same as first ? */
19584         if (*pTempsrc1 == *pTempsrc2)
19585         {
19586           for (iS = 1; iS < iM; iS++)  /* then just repeat the first */
19587           {
19588             *pTempdst = *pTempsrc1;
19589             pTempdst++;
19590           }
19591         }
19592         else
19593         {
19594           iH = (iM+1) / 2;             /* calculate halfway point */
19595 
19596           for (iS = 1; iS < iH; iS++)  /* replicate first half */
19597           {
19598             *pTempdst = *pTempsrc1;
19599             pTempdst++;
19600           }
19601 
19602           for (iS = iH; iS < iM; iS++) /* replicate second half */
19603           {
19604             *pTempdst = *pTempsrc2;
19605             pTempdst++;
19606           }
19607         }
19608       }
19609       else
19610       {
19611         for (iS = 1; iS < iM; iS++)
19612         {
19613           *pTempdst = *pTempsrc1;      /* repeat first source pixel */
19614           pTempdst++;
19615         }
19616       }
19617     }
19618 
19619     pTempsrc1++;
19620   }
19621 
19622 #ifdef MNG_SUPPORT_TRACE
19623   MNG_TRACE (pData, MNG_FN_MAGNIFY_G8_X3, MNG_LC_END);
19624 #endif
19625 
19626   return MNG_NOERROR;
19627 }
19628 #endif /* MNG_NO_GRAY_SUPPORT */
19629 
19630 /* ************************************************************************** */
19631 
mng_magnify_rgb8_x1(mng_datap pData,mng_uint16 iMX,mng_uint16 iML,mng_uint16 iMR,mng_uint32 iWidth,mng_uint8p pSrcline,mng_uint8p pDstline)19632 mng_retcode mng_magnify_rgb8_x1 (mng_datap  pData,
19633                                  mng_uint16 iMX,
19634                                  mng_uint16 iML,
19635                                  mng_uint16 iMR,
19636                                  mng_uint32 iWidth,
19637                                  mng_uint8p pSrcline,
19638                                  mng_uint8p pDstline)
19639 {
19640   mng_uint32 iX, iS, iM;
19641   mng_uint8p pTempsrc1;
19642   mng_uint8p pTempdst;
19643 
19644 #ifdef MNG_SUPPORT_TRACE
19645   MNG_TRACE (pData, MNG_FN_MAGNIFY_RGB8_X1, MNG_LC_START);
19646 #endif
19647 
19648   pTempsrc1 = pSrcline;                /* initialize pixel-loop */
19649   pTempdst  = pDstline;
19650 
19651   for (iX = 0; iX < iWidth; iX++)
19652   {
19653     *pTempdst = *pTempsrc1;            /* copy original source pixel */
19654     pTempdst++;
19655     *pTempdst = *(pTempsrc1+1);
19656     pTempdst++;
19657     *pTempdst = *(pTempsrc1+2);
19658     pTempdst++;
19659 
19660     if (iX == 0)                       /* first interval ? */
19661       iM = iML;
19662     else
19663     if (iX == (iWidth - 1))            /* last interval ? */
19664       iM = iMR;
19665     else
19666       iM = iMX;
19667 
19668     for (iS = 1; iS < iM; iS++)        /* fill interval */
19669     {
19670       *pTempdst = *pTempsrc1;          /* copy original source pixel */
19671       pTempdst++;
19672       *pTempdst = *(pTempsrc1+1);
19673       pTempdst++;
19674       *pTempdst = *(pTempsrc1+2);
19675       pTempdst++;
19676     }
19677 
19678     pTempsrc1 += 3;
19679   }
19680 
19681 #ifdef MNG_SUPPORT_TRACE
19682   MNG_TRACE (pData, MNG_FN_MAGNIFY_RGB8_X1, MNG_LC_END);
19683 #endif
19684 
19685   return MNG_NOERROR;
19686 }
19687 
19688 /* ************************************************************************** */
19689 
mng_magnify_rgb8_x2(mng_datap pData,mng_uint16 iMX,mng_uint16 iML,mng_uint16 iMR,mng_uint32 iWidth,mng_uint8p pSrcline,mng_uint8p pDstline)19690 mng_retcode mng_magnify_rgb8_x2 (mng_datap  pData,
19691                                  mng_uint16 iMX,
19692                                  mng_uint16 iML,
19693                                  mng_uint16 iMR,
19694                                  mng_uint32 iWidth,
19695                                  mng_uint8p pSrcline,
19696                                  mng_uint8p pDstline)
19697 {
19698   mng_uint32 iX;
19699   mng_int32  iS, iM;
19700   mng_uint8p pTempsrc1;
19701   mng_uint8p pTempsrc2;
19702   mng_uint8p pTempdst;
19703 
19704 #ifdef MNG_SUPPORT_TRACE
19705   MNG_TRACE (pData, MNG_FN_MAGNIFY_RGB8_X2, MNG_LC_START);
19706 #endif
19707 
19708   pTempsrc1 = pSrcline;                /* initialize pixel-loop */
19709   pTempdst  = pDstline;
19710 
19711   for (iX = 0; iX < iWidth; iX++)
19712   {
19713     pTempsrc2 = pTempsrc1 + 3;
19714 
19715     *pTempdst = *pTempsrc1;            /* copy original source pixel */
19716     pTempdst++;
19717     *pTempdst = *(pTempsrc1+1);
19718     pTempdst++;
19719     *pTempdst = *(pTempsrc1+2);
19720     pTempdst++;
19721 
19722     if (iX == 0)                       /* first interval ? */
19723     {
19724       if (iWidth == 1)                 /* single pixel ? */
19725         pTempsrc2 = MNG_NULL;
19726 
19727       iM = (mng_int32)iML;
19728     }
19729     else
19730     if (iX == (iWidth - 2))            /* last interval ? */
19731       iM = (mng_int32)iMR;
19732     else
19733       iM = (mng_int32)iMX;
19734                                        /* fill interval ? */
19735     if ((iX < iWidth - 1) || (iWidth == 1))
19736     {
19737       if (pTempsrc2)                   /* do we have the second pixel ? */
19738       {
19739         for (iS = 1; iS < iM; iS++)
19740         {
19741           if (*pTempsrc1 == *pTempsrc2)
19742             *pTempdst = *pTempsrc1;    /* just repeat the first */
19743           else                         /* calculate the distance */
19744             *pTempdst = (mng_uint8)(((2 * iS * ( (mng_int32)(*pTempsrc2)     -
19745                                                  (mng_int32)(*pTempsrc1)     ) + iM) /
19746                                      (iM * 2)) + (mng_int32)(*pTempsrc1)             );
19747 
19748           pTempdst++;
19749 
19750           if (*(pTempsrc1+1) == *(pTempsrc2+1))
19751             *pTempdst = *(pTempsrc1+1);
19752           else
19753             *pTempdst = (mng_uint8)(((2 * iS * ( (mng_int32)(*(pTempsrc2+1)) -
19754                                                  (mng_int32)(*(pTempsrc1+1)) ) + iM) /
19755                                      (iM * 2)) + (mng_int32)(*(pTempsrc1+1))         );
19756 
19757           pTempdst++;
19758 
19759           if (*(pTempsrc1+2) == *(pTempsrc2+2))
19760             *pTempdst = *(pTempsrc1+2);
19761           else
19762             *pTempdst = (mng_uint8)(((2 * iS * ( (mng_int32)(*(pTempsrc2+2)) -
19763                                                  (mng_int32)(*(pTempsrc1+2)) ) + iM) /
19764                                      (iM * 2)) + (mng_int32)(*(pTempsrc1+2))         );
19765 
19766           pTempdst++;
19767         }
19768       }
19769       else
19770       {
19771         for (iS = 1; iS < iM; iS++)
19772         {
19773           *pTempdst = *pTempsrc1;      /* repeat first source pixel */
19774           pTempdst++;
19775           *pTempdst = *(pTempsrc1+1);
19776           pTempdst++;
19777           *pTempdst = *(pTempsrc1+2);
19778           pTempdst++;
19779         }
19780       }
19781     }
19782 
19783     pTempsrc1 += 3;
19784   }
19785 
19786 #ifdef MNG_SUPPORT_TRACE
19787   MNG_TRACE (pData, MNG_FN_MAGNIFY_RGB8_X2, MNG_LC_END);
19788 #endif
19789 
19790   return MNG_NOERROR;
19791 }
19792 
19793 /* ************************************************************************** */
19794 
mng_magnify_rgb8_x3(mng_datap pData,mng_uint16 iMX,mng_uint16 iML,mng_uint16 iMR,mng_uint32 iWidth,mng_uint8p pSrcline,mng_uint8p pDstline)19795 mng_retcode mng_magnify_rgb8_x3 (mng_datap  pData,
19796                                  mng_uint16 iMX,
19797                                  mng_uint16 iML,
19798                                  mng_uint16 iMR,
19799                                  mng_uint32 iWidth,
19800                                  mng_uint8p pSrcline,
19801                                  mng_uint8p pDstline)
19802 {
19803   mng_uint32 iX;
19804   mng_int32  iS, iM, iH;
19805   mng_uint8p pTempsrc1;
19806   mng_uint8p pTempsrc2;
19807   mng_uint8p pTempdst;
19808 
19809 #ifdef MNG_SUPPORT_TRACE
19810   MNG_TRACE (pData, MNG_FN_MAGNIFY_RGB8_X3, MNG_LC_START);
19811 #endif
19812 
19813   pTempsrc1 = pSrcline;                /* initialize pixel-loop */
19814   pTempdst  = pDstline;
19815 
19816   for (iX = 0; iX < iWidth; iX++)
19817   {
19818     pTempsrc2 = pTempsrc1 + 3;
19819 
19820     *pTempdst = *pTempsrc1;            /* copy original source pixel */
19821     pTempdst++;
19822     *pTempdst = *(pTempsrc1+1);
19823     pTempdst++;
19824     *pTempdst = *(pTempsrc1+2);
19825     pTempdst++;
19826 
19827     if (iX == 0)                       /* first interval ? */
19828     {
19829       if (iWidth == 1)                 /* single pixel ? */
19830         pTempsrc2 = MNG_NULL;
19831 
19832       iM = (mng_int32)iML;
19833     }
19834     else
19835     if (iX == (iWidth - 2))            /* last interval ? */
19836       iM = (mng_int32)iMR;
19837     else
19838       iM = (mng_int32)iMX;
19839                                        /* fill interval ? */
19840     if ((iX < iWidth - 1) || (iWidth == 1))
19841     {
19842       if (pTempsrc2)                   /* do we have the second pixel ? */
19843       {
19844         iH = (iM+1) / 2;               /* calculate halfway point */
19845 
19846         for (iS = 1; iS < iH; iS++)    /* replicate first half */
19847         {
19848           *pTempdst     = *pTempsrc1;
19849           *(pTempdst+1) = *(pTempsrc1+1);
19850           *(pTempdst+2) = *(pTempsrc1+2);
19851 
19852           pTempdst += 3;
19853         }
19854 
19855         for (iS = iH; iS < iM; iS++)    /* replicate second half */
19856         {
19857           *pTempdst     = *pTempsrc2;
19858           *(pTempdst+1) = *(pTempsrc2+1);
19859           *(pTempdst+2) = *(pTempsrc2+2);
19860 
19861           pTempdst += 3;
19862         }
19863       }
19864       else
19865       {
19866         for (iS = 1; iS < iM; iS++)
19867         {
19868           *pTempdst = *pTempsrc1;      /* repeat first source pixel */
19869           pTempdst++;
19870           *pTempdst = *(pTempsrc1+1);
19871           pTempdst++;
19872           *pTempdst = *(pTempsrc1+2);
19873           pTempdst++;
19874         }
19875       }
19876     }
19877 
19878     pTempsrc1 += 3;
19879   }
19880 
19881 #ifdef MNG_SUPPORT_TRACE
19882   MNG_TRACE (pData, MNG_FN_MAGNIFY_RGB8_X3, MNG_LC_END);
19883 #endif
19884 
19885   return MNG_NOERROR;
19886 }
19887 
19888 /* ************************************************************************** */
19889 
19890 #ifndef MNG_NO_GRAY_SUPPORT
mng_magnify_ga8_x1(mng_datap pData,mng_uint16 iMX,mng_uint16 iML,mng_uint16 iMR,mng_uint32 iWidth,mng_uint8p pSrcline,mng_uint8p pDstline)19891 mng_retcode mng_magnify_ga8_x1 (mng_datap  pData,
19892                                 mng_uint16 iMX,
19893                                 mng_uint16 iML,
19894                                 mng_uint16 iMR,
19895                                 mng_uint32 iWidth,
19896                                 mng_uint8p pSrcline,
19897                                 mng_uint8p pDstline)
19898 {
19899   mng_uint32 iX, iS, iM;
19900   mng_uint8p pTempsrc1;
19901   mng_uint8p pTempdst;
19902 
19903 #ifdef MNG_SUPPORT_TRACE
19904   MNG_TRACE (pData, MNG_FN_MAGNIFY_GA8_X1, MNG_LC_START);
19905 #endif
19906 
19907   pTempsrc1 = pSrcline;                /* initialize pixel-loop */
19908   pTempdst  = pDstline;
19909 
19910   for (iX = 0; iX < iWidth; iX++)
19911   {
19912     *pTempdst = *pTempsrc1;            /* copy original source pixel */
19913     pTempdst++;
19914     *pTempdst = *(pTempsrc1+1);
19915     pTempdst++;
19916 
19917     if (iX == 0)                       /* first interval ? */
19918       iM = iML;
19919     else
19920     if (iX == (iWidth - 1))            /* last interval ? */
19921       iM = iMR;
19922     else
19923       iM = iMX;
19924 
19925     for (iS = 1; iS < iM; iS++)        /* fill interval */
19926     {
19927       *pTempdst = *pTempsrc1;          /* copy original source pixel */
19928       pTempdst++;
19929       *pTempdst = *(pTempsrc1+1);
19930       pTempdst++;
19931     }
19932 
19933     pTempsrc1 += 2;
19934   }
19935 
19936 #ifdef MNG_SUPPORT_TRACE
19937   MNG_TRACE (pData, MNG_FN_MAGNIFY_GA8_X1, MNG_LC_END);
19938 #endif
19939 
19940   return MNG_NOERROR;
19941 }
19942 
19943 /* ************************************************************************** */
19944 
mng_magnify_ga8_x2(mng_datap pData,mng_uint16 iMX,mng_uint16 iML,mng_uint16 iMR,mng_uint32 iWidth,mng_uint8p pSrcline,mng_uint8p pDstline)19945 mng_retcode mng_magnify_ga8_x2 (mng_datap  pData,
19946                                 mng_uint16 iMX,
19947                                 mng_uint16 iML,
19948                                 mng_uint16 iMR,
19949                                 mng_uint32 iWidth,
19950                                 mng_uint8p pSrcline,
19951                                 mng_uint8p pDstline)
19952 {
19953   mng_uint32 iX;
19954   mng_int32  iS, iM;
19955   mng_uint8p pTempsrc1;
19956   mng_uint8p pTempsrc2;
19957   mng_uint8p pTempdst;
19958 
19959 #ifdef MNG_SUPPORT_TRACE
19960   MNG_TRACE (pData, MNG_FN_MAGNIFY_GA8_X2, MNG_LC_START);
19961 #endif
19962 
19963   pTempsrc1 = pSrcline;                /* initialize pixel-loop */
19964   pTempdst  = pDstline;
19965 
19966   for (iX = 0; iX < iWidth; iX++)
19967   {
19968     pTempsrc2 = pTempsrc1 + 2;
19969 
19970     *pTempdst = *pTempsrc1;            /* copy original source pixel */
19971     pTempdst++;
19972     *pTempdst = *(pTempsrc1+1);
19973     pTempdst++;
19974 
19975     if (iX == 0)                       /* first interval ? */
19976     {
19977       if (iWidth == 1)                 /* single pixel ? */
19978         pTempsrc2 = MNG_NULL;
19979 
19980       iM = iML;
19981     }
19982     else
19983     if (iX == (iWidth - 2))            /* last interval ? */
19984       iM = iMR;
19985     else
19986       iM = iMX;
19987                                        /* fill interval ? */
19988     if ((iX < iWidth - 1) || (iWidth == 1))
19989     {
19990       if (pTempsrc2)                   /* do we have the second pixel ? */
19991       {
19992         for (iS = 1; iS < iM; iS++)
19993         {
19994           if (*pTempsrc1 == *pTempsrc2)
19995             *pTempdst = *pTempsrc1;    /* just repeat the first */
19996           else                         /* calculate the distance */
19997             *pTempdst = (mng_uint8)(((2 * iS * ( (mng_int32)(*pTempsrc2)     -
19998                                                  (mng_int32)(*pTempsrc1)     ) + iM) /
19999                                      (iM * 2)) + (mng_int32)(*pTempsrc1)             );
20000 
20001           pTempdst++;
20002 
20003           if (*(pTempsrc1+1) == *(pTempsrc2+1))
20004             *pTempdst = *(pTempsrc1+1);
20005           else
20006             *pTempdst = (mng_uint8)(((2 * iS * ( (mng_int32)(*(pTempsrc2+1)) -
20007                                                  (mng_int32)(*(pTempsrc1+1)) ) + iM) /
20008                                      (iM * 2)) + (mng_int32)(*(pTempsrc1+1))         );
20009 
20010           pTempdst++;
20011         }
20012       }
20013       else
20014       {
20015         for (iS = 1; iS < iM; iS++)
20016         {
20017           *pTempdst = *pTempsrc1;      /* repeat first source pixel */
20018           pTempdst++;
20019           *pTempdst = *(pTempsrc1+1);
20020           pTempdst++;
20021         }
20022       }
20023     }
20024 
20025     pTempsrc1 += 2;
20026   }
20027 
20028 #ifdef MNG_SUPPORT_TRACE
20029   MNG_TRACE (pData, MNG_FN_MAGNIFY_GA8_X2, MNG_LC_END);
20030 #endif
20031 
20032   return MNG_NOERROR;
20033 }
20034 
20035 /* ************************************************************************** */
20036 
mng_magnify_ga8_x3(mng_datap pData,mng_uint16 iMX,mng_uint16 iML,mng_uint16 iMR,mng_uint32 iWidth,mng_uint8p pSrcline,mng_uint8p pDstline)20037 mng_retcode mng_magnify_ga8_x3 (mng_datap  pData,
20038                                 mng_uint16 iMX,
20039                                 mng_uint16 iML,
20040                                 mng_uint16 iMR,
20041                                 mng_uint32 iWidth,
20042                                 mng_uint8p pSrcline,
20043                                 mng_uint8p pDstline)
20044 {
20045   mng_uint32 iX;
20046   mng_int32  iS, iM, iH;
20047   mng_uint8p pTempsrc1;
20048   mng_uint8p pTempsrc2;
20049   mng_uint8p pTempdst;
20050 
20051 #ifdef MNG_SUPPORT_TRACE
20052   MNG_TRACE (pData, MNG_FN_MAGNIFY_GA8_X3, MNG_LC_START);
20053 #endif
20054 
20055   pTempsrc1 = pSrcline;                /* initialize pixel-loop */
20056   pTempdst  = pDstline;
20057 
20058   for (iX = 0; iX < iWidth; iX++)
20059   {
20060     pTempsrc2 = pTempsrc1 + 2;
20061 
20062     *pTempdst = *pTempsrc1;            /* copy original source pixel */
20063     pTempdst++;
20064     *pTempdst = *(pTempsrc1+1);
20065     pTempdst++;
20066 
20067     if (iX == 0)                       /* first interval ? */
20068     {
20069       if (iWidth == 1)                 /* single pixel ? */
20070         pTempsrc2 = MNG_NULL;
20071 
20072       iM = iML;
20073     }
20074     else
20075     if (iX == (iWidth - 2))            /* last interval ? */
20076       iM = iMR;
20077     else
20078       iM = iMX;
20079                                        /* fill interval ? */
20080     if ((iX < iWidth - 1) || (iWidth == 1))
20081     {
20082       if (pTempsrc2)                   /* do we have the second pixel ? */
20083       {
20084         iH = (iM+1) / 2;               /* calculate halfway point */
20085 
20086         for (iS = 1; iS < iH; iS++)    /* replicate first half */
20087         {
20088           *pTempdst     = *pTempsrc1;
20089           *(pTempdst+1) = *(pTempsrc1+1);
20090 
20091           pTempdst += 2;
20092         }
20093 
20094         for (iS = iH; iS < iM; iS++)   /* replicate second half */
20095         {
20096           *pTempdst     = *pTempsrc2;
20097           *(pTempdst+1) = *(pTempsrc2+1);
20098 
20099           pTempdst += 2;
20100         }
20101       }
20102       else
20103       {
20104         for (iS = 1; iS < iM; iS++)
20105         {
20106           *pTempdst = *pTempsrc1;      /* repeat first source pixel */
20107           pTempdst++;
20108           *pTempdst = *(pTempsrc1+1);
20109           pTempdst++;
20110         }
20111       }
20112     }
20113 
20114     pTempsrc1 += 2;
20115   }
20116 
20117 #ifdef MNG_SUPPORT_TRACE
20118   MNG_TRACE (pData, MNG_FN_MAGNIFY_GA8_X3, MNG_LC_END);
20119 #endif
20120 
20121   return MNG_NOERROR;
20122 }
20123 
20124 /* ************************************************************************** */
20125 
mng_magnify_ga8_x4(mng_datap pData,mng_uint16 iMX,mng_uint16 iML,mng_uint16 iMR,mng_uint32 iWidth,mng_uint8p pSrcline,mng_uint8p pDstline)20126 mng_retcode mng_magnify_ga8_x4 (mng_datap  pData,
20127                                 mng_uint16 iMX,
20128                                 mng_uint16 iML,
20129                                 mng_uint16 iMR,
20130                                 mng_uint32 iWidth,
20131                                 mng_uint8p pSrcline,
20132                                 mng_uint8p pDstline)
20133 {
20134   mng_uint32 iX;
20135   mng_int32  iS, iM, iH;
20136   mng_uint8p pTempsrc1;
20137   mng_uint8p pTempsrc2;
20138   mng_uint8p pTempdst;
20139 
20140 #ifdef MNG_SUPPORT_TRACE
20141   MNG_TRACE (pData, MNG_FN_MAGNIFY_GA8_X4, MNG_LC_START);
20142 #endif
20143 
20144   pTempsrc1 = pSrcline;                /* initialize pixel-loop */
20145   pTempdst  = pDstline;
20146 
20147   for (iX = 0; iX < iWidth; iX++)
20148   {
20149     pTempsrc2 = pTempsrc1 + 2;
20150 
20151     *pTempdst = *pTempsrc1;            /* copy original source pixel */
20152     pTempdst++;
20153     *pTempdst = *(pTempsrc1+1);
20154     pTempdst++;
20155 
20156     if (iX == 0)                       /* first interval ? */
20157     {
20158       if (iWidth == 1)                 /* single pixel ? */
20159         pTempsrc2 = MNG_NULL;
20160 
20161       iM = iML;
20162     }
20163     else
20164     if (iX == (iWidth - 2))            /* last interval ? */
20165       iM = iMR;
20166     else
20167       iM = iMX;
20168                                        /* fill interval ? */
20169     if ((iX < iWidth - 1) || (iWidth == 1))
20170     {
20171       if (pTempsrc2)                   /* do we have the second pixel ? */
20172       {
20173         iH = (iM+1) / 2;               /* calculate halfway point */
20174 
20175         for (iS = 1; iS < iH; iS++)    /* first half */
20176         {
20177           if (*pTempsrc1 == *pTempsrc2)
20178             *pTempdst = *pTempsrc1;    /* just repeat the first */
20179           else                         /* calculate the distance */
20180             *pTempdst = (mng_uint8)(((2 * iS * ( (mng_int32)(*pTempsrc2)     -
20181                                                  (mng_int32)(*pTempsrc1)     ) + iM) /
20182                                      (iM * 2)) + (mng_int32)(*pTempsrc1)             );
20183 
20184           pTempdst++;
20185 
20186           *pTempdst = *(pTempsrc1+1);  /* replicate alpha from left */
20187 
20188           pTempdst++;
20189         }
20190 
20191         for (iS = iH; iS < iM; iS++)   /* second half */
20192         {
20193           if (*pTempsrc1 == *pTempsrc2)
20194             *pTempdst = *pTempsrc1;    /* just repeat the first */
20195           else                         /* calculate the distance */
20196             *pTempdst = (mng_uint8)(((2 * iS * ( (mng_int32)(*pTempsrc2)     -
20197                                                  (mng_int32)(*pTempsrc1)     ) + iM) /
20198                                      (iM * 2)) + (mng_int32)(*pTempsrc1)             );
20199 
20200           pTempdst++;
20201 
20202           *pTempdst = *(pTempsrc2+1);  /* replicate alpha from right */
20203 
20204           pTempdst++;
20205         }
20206       }
20207       else
20208       {
20209         for (iS = 1; iS < iM; iS++)
20210         {
20211           *pTempdst = *pTempsrc1;      /* repeat first source pixel */
20212           pTempdst++;
20213           *pTempdst = *(pTempsrc1+1);
20214           pTempdst++;
20215         }
20216       }
20217     }
20218 
20219     pTempsrc1 += 2;
20220   }
20221 
20222 #ifdef MNG_SUPPORT_TRACE
20223   MNG_TRACE (pData, MNG_FN_MAGNIFY_GA8_X4, MNG_LC_END);
20224 #endif
20225 
20226   return MNG_NOERROR;
20227 }
20228 
20229 /* ************************************************************************** */
20230 
mng_magnify_ga8_x5(mng_datap pData,mng_uint16 iMX,mng_uint16 iML,mng_uint16 iMR,mng_uint32 iWidth,mng_uint8p pSrcline,mng_uint8p pDstline)20231 mng_retcode mng_magnify_ga8_x5 (mng_datap  pData,
20232                                 mng_uint16 iMX,
20233                                 mng_uint16 iML,
20234                                 mng_uint16 iMR,
20235                                 mng_uint32 iWidth,
20236                                 mng_uint8p pSrcline,
20237                                 mng_uint8p pDstline)
20238 {
20239   mng_uint32 iX;
20240   mng_int32  iS, iM, iH;
20241   mng_uint8p pTempsrc1;
20242   mng_uint8p pTempsrc2;
20243   mng_uint8p pTempdst;
20244 
20245 #ifdef MNG_SUPPORT_TRACE
20246   MNG_TRACE (pData, MNG_FN_MAGNIFY_GA8_X5, MNG_LC_START);
20247 #endif
20248 
20249   pTempsrc1 = pSrcline;                /* initialize pixel-loop */
20250   pTempdst  = pDstline;
20251 
20252   for (iX = 0; iX < iWidth; iX++)
20253   {
20254     pTempsrc2 = pTempsrc1 + 2;
20255 
20256     *pTempdst = *pTempsrc1;            /* copy original source pixel */
20257     pTempdst++;
20258     *pTempdst = *(pTempsrc1+1);
20259     pTempdst++;
20260 
20261     if (iX == 0)                       /* first interval ? */
20262     {
20263       if (iWidth == 1)                 /* single pixel ? */
20264         pTempsrc2 = MNG_NULL;
20265 
20266       iM = iML;
20267     }
20268     else
20269     if (iX == (iWidth - 2))            /* last interval ? */
20270       iM = iMR;
20271     else
20272       iM = iMX;
20273                                        /* fill interval ? */
20274     if ((iX < iWidth - 1) || (iWidth == 1))
20275     {
20276       if (pTempsrc2)                   /* do we have the second pixel ? */
20277       {
20278         iH = (iM+1) / 2;               /* calculate halfway point */
20279 
20280         for (iS = 1; iS < iH; iS++)    /* first half */
20281         {
20282           *pTempdst = *pTempsrc1;      /* replicate gray from left */
20283 
20284           pTempdst++;
20285 
20286           if (*(pTempsrc1+1) == *(pTempsrc2+1))
20287             *pTempdst = *(pTempsrc1+1);/* just repeat the first */
20288           else                         /* calculate the distance */
20289             *pTempdst = (mng_uint8)(((2 * iS * ( (mng_int32)(*(pTempsrc2+1))     -
20290                                                  (mng_int32)(*(pTempsrc1+1))     ) + iM) /
20291                                      (iM * 2)) + (mng_int32)(*(pTempsrc1+1))             );
20292 
20293           pTempdst++;
20294         }
20295 
20296         for (iS = iH; iS < iM; iS++)   /* second half */
20297         {
20298           *pTempdst = *pTempsrc2;      /* replicate gray from right */
20299 
20300           pTempdst++;
20301 
20302           if (*(pTempsrc1+1) == *(pTempsrc2+1))
20303             *pTempdst = *(pTempsrc1+1);/* just repeat the first */
20304           else                         /* calculate the distance */
20305             *pTempdst = (mng_uint8)(((2 * iS * ( (mng_int32)(*(pTempsrc2+1))     -
20306                                                  (mng_int32)(*(pTempsrc1+1))     ) + iM) /
20307                                      (iM * 2)) + (mng_int32)(*(pTempsrc1+1))             );
20308 
20309           pTempdst++;
20310         }
20311       }
20312       else
20313       {
20314         for (iS = 1; iS < iM; iS++)
20315         {
20316           *pTempdst = *pTempsrc1;      /* repeat first source pixel */
20317           pTempdst++;
20318           *pTempdst = *(pTempsrc1+1);
20319           pTempdst++;
20320         }
20321       }
20322     }
20323 
20324     pTempsrc1 += 2;
20325   }
20326 
20327 #ifdef MNG_SUPPORT_TRACE
20328   MNG_TRACE (pData, MNG_FN_MAGNIFY_GA8_X5, MNG_LC_END);
20329 #endif
20330 
20331   return MNG_NOERROR;
20332 }
20333 #endif /* MNG_NO_GRAY_SUPPORT */
20334 #endif /* MNG_OPTIMIZE_FOOTPRINT_MAGN */
20335 
20336 /* ************************************************************************** */
20337 
mng_magnify_rgba8_x1(mng_datap pData,mng_uint16 iMX,mng_uint16 iML,mng_uint16 iMR,mng_uint32 iWidth,mng_uint8p pSrcline,mng_uint8p pDstline)20338 mng_retcode mng_magnify_rgba8_x1 (mng_datap  pData,
20339                                   mng_uint16 iMX,
20340                                   mng_uint16 iML,
20341                                   mng_uint16 iMR,
20342                                   mng_uint32 iWidth,
20343                                   mng_uint8p pSrcline,
20344                                   mng_uint8p pDstline)
20345 {
20346   mng_uint32 iX, iS, iM;
20347   mng_uint8p pTempsrc1;
20348   mng_uint8p pTempdst;
20349 
20350 #ifdef MNG_SUPPORT_TRACE
20351   MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA8_X1, MNG_LC_START);
20352 #endif
20353 
20354   pTempsrc1 = pSrcline;                /* initialize pixel-loop */
20355   pTempdst  = pDstline;
20356 
20357   for (iX = 0; iX < iWidth; iX++)
20358   {
20359     *pTempdst = *pTempsrc1;            /* copy original source pixel */
20360     pTempdst++;
20361     *pTempdst = *(pTempsrc1+1);
20362     pTempdst++;
20363     *pTempdst = *(pTempsrc1+2);
20364     pTempdst++;
20365     *pTempdst = *(pTempsrc1+3);
20366     pTempdst++;
20367 
20368     if (iX == 0)                       /* first interval ? */
20369       iM = iML;
20370     else
20371     if (iX == (iWidth - 1))            /* last interval ? */
20372       iM = iMR;
20373     else
20374       iM = iMX;
20375 
20376     for (iS = 1; iS < iM; iS++)        /* fill interval */
20377     {
20378       *pTempdst = *pTempsrc1;          /* copy original source pixel */
20379       pTempdst++;
20380       *pTempdst = *(pTempsrc1+1);
20381       pTempdst++;
20382       *pTempdst = *(pTempsrc1+2);
20383       pTempdst++;
20384       *pTempdst = *(pTempsrc1+3);
20385       pTempdst++;
20386     }
20387 
20388     pTempsrc1 += 4;
20389   }
20390 
20391 #ifdef MNG_SUPPORT_TRACE
20392   MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA8_X1, MNG_LC_END);
20393 #endif
20394 
20395   return MNG_NOERROR;
20396 }
20397 
20398 /* ************************************************************************** */
20399 
mng_magnify_rgba8_x2(mng_datap pData,mng_uint16 iMX,mng_uint16 iML,mng_uint16 iMR,mng_uint32 iWidth,mng_uint8p pSrcline,mng_uint8p pDstline)20400 mng_retcode mng_magnify_rgba8_x2 (mng_datap  pData,
20401                                   mng_uint16 iMX,
20402                                   mng_uint16 iML,
20403                                   mng_uint16 iMR,
20404                                   mng_uint32 iWidth,
20405                                   mng_uint8p pSrcline,
20406                                   mng_uint8p pDstline)
20407 {
20408   mng_uint32 iX;
20409   mng_int32  iS, iM;
20410   mng_uint8p pTempsrc1;
20411   mng_uint8p pTempsrc2;
20412   mng_uint8p pTempdst;
20413 
20414 #ifdef MNG_SUPPORT_TRACE
20415   MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA8_X2, MNG_LC_START);
20416 #endif
20417 
20418   pTempsrc1 = pSrcline;                /* initialize pixel-loop */
20419   pTempdst  = pDstline;
20420 
20421   for (iX = 0; iX < iWidth; iX++)
20422   {
20423     pTempsrc2 = pTempsrc1 + 4;
20424 
20425     *pTempdst = *pTempsrc1;            /* copy original source pixel */
20426     pTempdst++;
20427     *pTempdst = *(pTempsrc1+1);
20428     pTempdst++;
20429     *pTempdst = *(pTempsrc1+2);
20430     pTempdst++;
20431     *pTempdst = *(pTempsrc1+3);
20432     pTempdst++;
20433 
20434     if (iX == 0)                       /* first interval ? */
20435     {
20436       if (iWidth == 1)                 /* single pixel ? */
20437         pTempsrc2 = MNG_NULL;
20438 
20439       iM = (mng_int32)iML;
20440     }
20441     else
20442     if (iX == (iWidth - 2))            /* last interval ? */
20443       iM = (mng_int32)iMR;
20444     else
20445       iM = (mng_int32)iMX;
20446                                        /* fill interval ? */
20447     if ((iX < iWidth - 1) || (iWidth == 1))
20448     {
20449       if (pTempsrc2)                   /* do we have the second pixel ? */
20450       {
20451         for (iS = 1; iS < iM; iS++)
20452         {
20453           if (*pTempsrc1 == *pTempsrc2)
20454             *pTempdst = *pTempsrc1;    /* just repeat the first */
20455           else                         /* calculate the distance */
20456             *pTempdst = (mng_uint8)(((2 * iS * ( (mng_int32)(*pTempsrc2)     -
20457                                                  (mng_int32)(*pTempsrc1)     ) + iM) /
20458                                      (iM * 2)) + (mng_int32)(*pTempsrc1)             );
20459 
20460           pTempdst++;
20461 
20462           if (*(pTempsrc1+1) == *(pTempsrc2+1))
20463             *pTempdst = *(pTempsrc1+1);
20464           else
20465             *pTempdst = (mng_uint8)(((2 * iS * ( (mng_int32)(*(pTempsrc2+1)) -
20466                                                  (mng_int32)(*(pTempsrc1+1)) ) + iM) /
20467                                      (iM * 2)) + (mng_int32)(*(pTempsrc1+1))         );
20468 
20469           pTempdst++;
20470 
20471           if (*(pTempsrc1+2) == *(pTempsrc2+2))
20472             *pTempdst = *(pTempsrc1+2);
20473           else
20474             *pTempdst = (mng_uint8)(((2 * iS * ( (mng_int32)(*(pTempsrc2+2)) -
20475                                                  (mng_int32)(*(pTempsrc1+2)) ) + iM) /
20476                                      (iM * 2)) + (mng_int32)(*(pTempsrc1+2))         );
20477 
20478           pTempdst++;
20479 
20480           if (*(pTempsrc1+3) == *(pTempsrc2+3))
20481             *pTempdst = *(pTempsrc1+3);
20482           else
20483             *pTempdst = (mng_uint8)(((2 * iS * ( (mng_int32)(*(pTempsrc2+3)) -
20484                                                  (mng_int32)(*(pTempsrc1+3)) ) + iM) /
20485                                      (iM * 2)) + (mng_int32)(*(pTempsrc1+3))         );
20486 
20487           pTempdst++;
20488         }
20489       }
20490       else
20491       {
20492         for (iS = 1; iS < iM; iS++)
20493         {
20494           *pTempdst = *pTempsrc1;      /* repeat first source pixel */
20495           pTempdst++;
20496           *pTempdst = *(pTempsrc1+1);
20497           pTempdst++;
20498           *pTempdst = *(pTempsrc1+2);
20499           pTempdst++;
20500           *pTempdst = *(pTempsrc1+3);
20501           pTempdst++;
20502         }
20503       }
20504     }
20505 
20506     pTempsrc1 += 4;
20507   }
20508 
20509 #ifdef MNG_SUPPORT_TRACE
20510   MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA8_X2, MNG_LC_END);
20511 #endif
20512 
20513   return MNG_NOERROR;
20514 }
20515 
20516 /* ************************************************************************** */
20517 
mng_magnify_rgba8_x3(mng_datap pData,mng_uint16 iMX,mng_uint16 iML,mng_uint16 iMR,mng_uint32 iWidth,mng_uint8p pSrcline,mng_uint8p pDstline)20518 mng_retcode mng_magnify_rgba8_x3 (mng_datap  pData,
20519                                   mng_uint16 iMX,
20520                                   mng_uint16 iML,
20521                                   mng_uint16 iMR,
20522                                   mng_uint32 iWidth,
20523                                   mng_uint8p pSrcline,
20524                                   mng_uint8p pDstline)
20525 {
20526   mng_uint32 iX;
20527   mng_int32  iS, iM, iH;
20528   mng_uint8p pTempsrc1;
20529   mng_uint8p pTempsrc2;
20530   mng_uint8p pTempdst;
20531 
20532 #ifdef MNG_SUPPORT_TRACE
20533   MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA8_X3, MNG_LC_START);
20534 #endif
20535 
20536   pTempsrc1 = pSrcline;                /* initialize pixel-loop */
20537   pTempdst  = pDstline;
20538 
20539   for (iX = 0; iX < iWidth; iX++)
20540   {
20541     pTempsrc2 = pTempsrc1 + 4;
20542 
20543     *pTempdst = *pTempsrc1;            /* copy original source pixel */
20544     pTempdst++;
20545     *pTempdst = *(pTempsrc1+1);
20546     pTempdst++;
20547     *pTempdst = *(pTempsrc1+2);
20548     pTempdst++;
20549     *pTempdst = *(pTempsrc1+3);
20550     pTempdst++;
20551 
20552     if (iX == 0)                       /* first interval ? */
20553     {
20554       if (iWidth == 1)                 /* single pixel ? */
20555         pTempsrc2 = MNG_NULL;
20556 
20557       iM = (mng_int32)iML;
20558     }
20559     else
20560     if (iX == (iWidth - 2))            /* last interval ? */
20561       iM = (mng_int32)iMR;
20562     else
20563       iM = (mng_int32)iMX;
20564                                        /* fill interval ? */
20565     if ((iX < iWidth - 1) || (iWidth == 1))
20566     {
20567       if (pTempsrc2)                   /* do we have the second pixel ? */
20568       {
20569         iH = (iM+1) / 2;               /* calculate halfway point */
20570 
20571         for (iS = 1; iS < iH; iS++)    /* replicate first half */
20572         {
20573           *pTempdst     = *pTempsrc1;
20574           *(pTempdst+1) = *(pTempsrc1+1);
20575           *(pTempdst+2) = *(pTempsrc1+2);
20576           *(pTempdst+3) = *(pTempsrc1+3);
20577 
20578           pTempdst += 4;
20579         }
20580 
20581         for (iS = iH; iS < iM; iS++)   /* replicate second half */
20582         {
20583           *pTempdst     = *pTempsrc2;
20584           *(pTempdst+1) = *(pTempsrc2+1);
20585           *(pTempdst+2) = *(pTempsrc2+2);
20586           *(pTempdst+3) = *(pTempsrc2+3);
20587 
20588           pTempdst += 4;
20589         }
20590       }
20591       else
20592       {
20593         for (iS = 1; iS < iM; iS++)
20594         {
20595           *pTempdst = *pTempsrc1;      /* repeat first source pixel */
20596           pTempdst++;
20597           *pTempdst = *(pTempsrc1+1);
20598           pTempdst++;
20599           *pTempdst = *(pTempsrc1+2);
20600           pTempdst++;
20601           *pTempdst = *(pTempsrc1+3);
20602           pTempdst++;
20603         }
20604       }
20605     }
20606 
20607     pTempsrc1 += 4;
20608   }
20609 
20610 #ifdef MNG_SUPPORT_TRACE
20611   MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA8_X3, MNG_LC_END);
20612 #endif
20613 
20614   return MNG_NOERROR;
20615 }
20616 
20617 /* ************************************************************************** */
20618 
mng_magnify_rgba8_x4(mng_datap pData,mng_uint16 iMX,mng_uint16 iML,mng_uint16 iMR,mng_uint32 iWidth,mng_uint8p pSrcline,mng_uint8p pDstline)20619 mng_retcode mng_magnify_rgba8_x4 (mng_datap  pData,
20620                                   mng_uint16 iMX,
20621                                   mng_uint16 iML,
20622                                   mng_uint16 iMR,
20623                                   mng_uint32 iWidth,
20624                                   mng_uint8p pSrcline,
20625                                   mng_uint8p pDstline)
20626 {
20627   mng_uint32 iX;
20628   mng_int32  iS, iM, iH;
20629   mng_uint8p pTempsrc1;
20630   mng_uint8p pTempsrc2;
20631   mng_uint8p pTempdst;
20632 
20633 #ifdef MNG_SUPPORT_TRACE
20634   MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA8_X4, MNG_LC_START);
20635 #endif
20636 
20637   pTempsrc1 = pSrcline;                /* initialize pixel-loop */
20638   pTempdst  = pDstline;
20639 
20640   for (iX = 0; iX < iWidth; iX++)
20641   {
20642     pTempsrc2 = pTempsrc1 + 4;
20643 
20644     *pTempdst = *pTempsrc1;            /* copy original source pixel */
20645     pTempdst++;
20646     *pTempdst = *(pTempsrc1+1);
20647     pTempdst++;
20648     *pTempdst = *(pTempsrc1+2);
20649     pTempdst++;
20650     *pTempdst = *(pTempsrc1+3);
20651     pTempdst++;
20652 
20653     if (iX == 0)                       /* first interval ? */
20654     {
20655       if (iWidth == 1)                 /* single pixel ? */
20656         pTempsrc2 = MNG_NULL;
20657 
20658       iM = (mng_int32)iML;
20659     }
20660     else
20661     if (iX == (iWidth - 2))            /* last interval ? */
20662       iM = (mng_int32)iMR;
20663     else
20664       iM = (mng_int32)iMX;
20665                                        /* fill interval ? */
20666     if ((iX < iWidth - 1) || (iWidth == 1))
20667     {
20668       if (pTempsrc2)                   /* do we have the second pixel ? */
20669       {
20670         iH = (iM+1) / 2;               /* calculate halfway point */
20671 
20672         for (iS = 1; iS < iH; iS++)    /* first half */
20673         {
20674           if (*pTempsrc1 == *pTempsrc2)
20675             *pTempdst = *pTempsrc1;    /* just repeat the first */
20676           else                         /* calculate the distance */
20677             *pTempdst = (mng_uint8)(((2 * iS * ( (mng_int32)(*pTempsrc2)     -
20678                                                  (mng_int32)(*pTempsrc1)     ) + iM) /
20679                                      (iM * 2)) + (mng_int32)(*pTempsrc1)             );
20680 
20681           pTempdst++;
20682 
20683           if (*(pTempsrc1+1) == *(pTempsrc2+1))
20684             *pTempdst = *(pTempsrc1+1);
20685           else
20686             *pTempdst = (mng_uint8)(((2 * iS * ( (mng_int32)(*(pTempsrc2+1)) -
20687                                                  (mng_int32)(*(pTempsrc1+1)) ) + iM) /
20688                                      (iM * 2)) + (mng_int32)(*(pTempsrc1+1))         );
20689 
20690           pTempdst++;
20691 
20692           if (*(pTempsrc1+2) == *(pTempsrc2+2))
20693             *pTempdst = *(pTempsrc1+2);
20694           else
20695             *pTempdst = (mng_uint8)(((2 * iS * ( (mng_int32)(*(pTempsrc2+2)) -
20696                                                  (mng_int32)(*(pTempsrc1+2)) ) + iM) /
20697                                      (iM * 2)) + (mng_int32)(*(pTempsrc1+2))         );
20698 
20699           pTempdst++;
20700                                        /* replicate alpha from left */
20701           *pTempdst     = *(pTempsrc1+3);
20702 
20703           pTempdst++;
20704         }
20705 
20706         for (iS = iH; iS < iM; iS++)   /* second half */
20707         {
20708           if (*pTempsrc1 == *pTempsrc2)
20709             *pTempdst = *pTempsrc1;    /* just repeat the first */
20710           else                         /* calculate the distance */
20711             *pTempdst = (mng_uint8)(((2 * iS * ( (mng_int32)(*pTempsrc2)     -
20712                                                  (mng_int32)(*pTempsrc1)     ) + iM) /
20713                                      (iM * 2)) + (mng_int32)(*pTempsrc1)             );
20714 
20715           pTempdst++;
20716 
20717           if (*(pTempsrc1+1) == *(pTempsrc2+1))
20718             *pTempdst = *(pTempsrc1+1);
20719           else
20720             *pTempdst = (mng_uint8)(((2 * iS * ( (mng_int32)(*(pTempsrc2+1)) -
20721                                                  (mng_int32)(*(pTempsrc1+1)) ) + iM) /
20722                                      (iM * 2)) + (mng_int32)(*(pTempsrc1+1))         );
20723 
20724           pTempdst++;
20725 
20726           if (*(pTempsrc1+2) == *(pTempsrc2+2))
20727             *pTempdst = *(pTempsrc1+2);
20728           else
20729             *pTempdst = (mng_uint8)(((2 * iS * ( (mng_int32)(*(pTempsrc2+2)) -
20730                                                  (mng_int32)(*(pTempsrc1+2)) ) + iM) /
20731                                      (iM * 2)) + (mng_int32)(*(pTempsrc1+2))         );
20732 
20733           pTempdst++;
20734                                        /* replicate alpha from right */
20735           *pTempdst     = *(pTempsrc2+3);
20736 
20737           pTempdst++;
20738         }
20739       }
20740       else
20741       {
20742         for (iS = 1; iS < iM; iS++)
20743         {
20744           *pTempdst = *pTempsrc1;      /* repeat first source pixel */
20745           pTempdst++;
20746           *pTempdst = *(pTempsrc1+1);
20747           pTempdst++;
20748           *pTempdst = *(pTempsrc1+2);
20749           pTempdst++;
20750           *pTempdst = *(pTempsrc1+3);
20751           pTempdst++;
20752         }
20753       }
20754     }
20755 
20756     pTempsrc1 += 4;
20757   }
20758 
20759 #ifdef MNG_SUPPORT_TRACE
20760   MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA8_X4, MNG_LC_END);
20761 #endif
20762 
20763   return MNG_NOERROR;
20764 }
20765 
20766 /* ************************************************************************** */
20767 
mng_magnify_rgba8_x5(mng_datap pData,mng_uint16 iMX,mng_uint16 iML,mng_uint16 iMR,mng_uint32 iWidth,mng_uint8p pSrcline,mng_uint8p pDstline)20768 mng_retcode mng_magnify_rgba8_x5 (mng_datap  pData,
20769                                   mng_uint16 iMX,
20770                                   mng_uint16 iML,
20771                                   mng_uint16 iMR,
20772                                   mng_uint32 iWidth,
20773                                   mng_uint8p pSrcline,
20774                                   mng_uint8p pDstline)
20775 {
20776   mng_uint32 iX;
20777   mng_int32  iS, iM, iH;
20778   mng_uint8p pTempsrc1;
20779   mng_uint8p pTempsrc2;
20780   mng_uint8p pTempdst;
20781 
20782 #ifdef MNG_SUPPORT_TRACE
20783   MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA8_X5, MNG_LC_START);
20784 #endif
20785 
20786   pTempsrc1 = pSrcline;                /* initialize pixel-loop */
20787   pTempdst  = pDstline;
20788 
20789   for (iX = 0; iX < iWidth; iX++)
20790   {
20791     pTempsrc2 = pTempsrc1 + 4;
20792 
20793     *pTempdst = *pTempsrc1;            /* copy original source pixel */
20794     pTempdst++;
20795     *pTempdst = *(pTempsrc1+1);
20796     pTempdst++;
20797     *pTempdst = *(pTempsrc1+2);
20798     pTempdst++;
20799     *pTempdst = *(pTempsrc1+3);
20800     pTempdst++;
20801 
20802     if (iX == 0)                       /* first interval ? */
20803     {
20804       if (iWidth == 1)                 /* single pixel ? */
20805         pTempsrc2 = MNG_NULL;
20806 
20807       iM = (mng_int32)iML;
20808     }
20809     else
20810     if (iX == (iWidth - 2))            /* last interval ? */
20811       iM = (mng_int32)iMR;
20812     else
20813       iM = (mng_int32)iMX;
20814                                        /* fill interval ? */
20815     if ((iX < iWidth - 1) || (iWidth == 1))
20816     {
20817       if (pTempsrc2)                   /* do we have the second pixel ? */
20818       {
20819         iH = (iM+1) / 2;               /* calculate halfway point */
20820 
20821         for (iS = 1; iS < iH; iS++)    /* first half */
20822         {
20823           *pTempdst     = *pTempsrc1;  /* replicate color from left */
20824           *(pTempdst+1) = *(pTempsrc1+1);
20825           *(pTempdst+2) = *(pTempsrc1+2);
20826 
20827           if (*(pTempsrc1+3) == *(pTempsrc2+3))
20828             *(pTempdst+3) = *(pTempsrc1+3);
20829           else
20830             *(pTempdst+3) = (mng_uint8)(((2 * iS * ( (mng_int32)(*(pTempsrc2+3)) -
20831                                                    (mng_int32)(*(pTempsrc1+3)) ) + iM) /
20832                                        (iM * 2)) + (mng_int32)(*(pTempsrc1+3))         );
20833 
20834           pTempdst += 4;
20835         }
20836 
20837         for (iS = iH; iS < iM; iS++)   /* second half */
20838         {
20839           *pTempdst     = *pTempsrc2;  /* replicate color from right */
20840           *(pTempdst+1) = *(pTempsrc2+1);
20841           *(pTempdst+2) = *(pTempsrc2+2);
20842 
20843           if (*(pTempsrc1+3) == *(pTempsrc2+3))
20844             *(pTempdst+3) = *(pTempsrc1+3);
20845           else
20846             *(pTempdst+3) = (mng_uint8)(((2 * iS * ( (mng_int32)(*(pTempsrc2+3)) -
20847                                                    (mng_int32)(*(pTempsrc1+3)) ) + iM) /
20848                                        (iM * 2)) + (mng_int32)(*(pTempsrc1+3))         );
20849 
20850           pTempdst += 4;
20851         }
20852       }
20853       else
20854       {
20855         for (iS = 1; iS < iM; iS++)
20856         {
20857           *pTempdst = *pTempsrc1;      /* repeat first source pixel */
20858           pTempdst++;
20859           *pTempdst = *(pTempsrc1+1);
20860           pTempdst++;
20861           *pTempdst = *(pTempsrc1+2);
20862           pTempdst++;
20863           *pTempdst = *(pTempsrc1+3);
20864           pTempdst++;
20865         }
20866       }
20867     }
20868 
20869     pTempsrc1 += 4;
20870   }
20871 
20872 #ifdef MNG_SUPPORT_TRACE
20873   MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA8_X4, MNG_LC_END);
20874 #endif
20875 
20876   return MNG_NOERROR;
20877 }
20878 
20879 /* ************************************************************************** */
20880 
20881 #ifndef MNG_OPTIMIZE_FOOTPRINT_MAGN
20882 #ifndef MNG_NO_GRAY_SUPPORT
mng_magnify_g8_y1(mng_datap pData,mng_int32 iS,mng_int32 iM,mng_uint32 iWidth,mng_uint8p pSrcline1,mng_uint8p pSrcline2,mng_uint8p pDstline)20883 mng_retcode mng_magnify_g8_y1 (mng_datap  pData,
20884                                mng_int32  iS,
20885                                mng_int32  iM,
20886                                mng_uint32 iWidth,
20887                                mng_uint8p pSrcline1,
20888                                mng_uint8p pSrcline2,
20889                                mng_uint8p pDstline)
20890 {
20891 #ifdef MNG_SUPPORT_TRACE
20892   MNG_TRACE (pData, MNG_FN_MAGNIFY_G8_Y1, MNG_LC_START);
20893 #endif
20894 
20895   MNG_COPY (pDstline, pSrcline1, iWidth);
20896 
20897 #ifdef MNG_SUPPORT_TRACE
20898   MNG_TRACE (pData, MNG_FN_MAGNIFY_G8_Y1, MNG_LC_END);
20899 #endif
20900 
20901   return MNG_NOERROR;
20902 }
20903 
20904 /* ************************************************************************** */
mng_magnify_g8_y2(mng_datap pData,mng_int32 iS,mng_int32 iM,mng_uint32 iWidth,mng_uint8p pSrcline1,mng_uint8p pSrcline2,mng_uint8p pDstline)20905 mng_retcode mng_magnify_g8_y2 (mng_datap  pData,
20906                                mng_int32  iS,
20907                                mng_int32  iM,
20908                                mng_uint32 iWidth,
20909                                mng_uint8p pSrcline1,
20910                                mng_uint8p pSrcline2,
20911                                mng_uint8p pDstline)
20912 {
20913   mng_uint32 iX;
20914   mng_uint8p pTempsrc1;
20915   mng_uint8p pTempsrc2;
20916   mng_uint8p pTempdst;
20917 
20918 #ifdef MNG_SUPPORT_TRACE
20919   MNG_TRACE (pData, MNG_FN_MAGNIFY_G8_Y2, MNG_LC_START);
20920 #endif
20921 
20922   pTempsrc1 = pSrcline1;               /* initialize pixel-loop */
20923   pTempsrc2 = pSrcline2;
20924   pTempdst  = pDstline;
20925 
20926   if (pTempsrc2)                       /* do we have a second line ? */
20927   {
20928     for (iX = 0; iX < iWidth; iX++)
20929     {                                  /* calculate the distances */
20930       if (*pTempsrc1 == *pTempsrc2)
20931         *pTempdst = *pTempsrc1;
20932       else
20933         *pTempdst = (mng_uint8)( ( (2 * iS * ( (mng_int32)(*pTempsrc2) -
20934                                                (mng_int32)(*pTempsrc1) ) + iM) /
20935                                    (iM * 2) ) + (mng_int32)(*pTempsrc1) );
20936 
20937       pTempdst++;
20938       pTempsrc1++;
20939       pTempsrc2++;
20940     }
20941   }
20942   else
20943   {                                    /* just repeat the entire line */
20944     MNG_COPY (pTempdst, pTempsrc1, iWidth);
20945   }
20946 
20947 #ifdef MNG_SUPPORT_TRACE
20948   MNG_TRACE (pData, MNG_FN_MAGNIFY_G8_Y2, MNG_LC_END);
20949 #endif
20950 
20951   return MNG_NOERROR;
20952 }
20953 
20954 /* ************************************************************************** */
20955 
mng_magnify_g8_y3(mng_datap pData,mng_int32 iS,mng_int32 iM,mng_uint32 iWidth,mng_uint8p pSrcline1,mng_uint8p pSrcline2,mng_uint8p pDstline)20956 mng_retcode mng_magnify_g8_y3 (mng_datap  pData,
20957                                mng_int32  iS,
20958                                mng_int32  iM,
20959                                mng_uint32 iWidth,
20960                                mng_uint8p pSrcline1,
20961                                mng_uint8p pSrcline2,
20962                                mng_uint8p pDstline)
20963 {
20964 #ifdef MNG_SUPPORT_TRACE
20965   MNG_TRACE (pData, MNG_FN_MAGNIFY_G8_Y3, MNG_LC_START);
20966 #endif
20967 
20968   if (pSrcline2)                       /* do we have a second line ? */
20969   {
20970     if (iS < (iM+1) / 2)               /* top half ? */
20971       MNG_COPY (pDstline, pSrcline1, iWidth)
20972     else
20973       MNG_COPY (pDstline, pSrcline2, iWidth);
20974   }
20975   else
20976   {                                    /* just repeat the entire line */
20977     MNG_COPY (pDstline, pSrcline1, iWidth);
20978   }
20979 
20980 #ifdef MNG_SUPPORT_TRACE
20981   MNG_TRACE (pData, MNG_FN_MAGNIFY_G8_Y3, MNG_LC_END);
20982 #endif
20983 
20984   return MNG_NOERROR;
20985 }
20986 #endif /* MNG_NO_GRAY_SUPPORT */
20987 
20988 /* ************************************************************************** */
20989 
mng_magnify_rgb8_y1(mng_datap pData,mng_int32 iS,mng_int32 iM,mng_uint32 iWidth,mng_uint8p pSrcline1,mng_uint8p pSrcline2,mng_uint8p pDstline)20990 mng_retcode mng_magnify_rgb8_y1 (mng_datap  pData,
20991                                  mng_int32  iS,
20992                                  mng_int32  iM,
20993                                  mng_uint32 iWidth,
20994                                  mng_uint8p pSrcline1,
20995                                  mng_uint8p pSrcline2,
20996                                  mng_uint8p pDstline)
20997 {
20998 #ifdef MNG_SUPPORT_TRACE
20999   MNG_TRACE (pData, MNG_FN_MAGNIFY_RGB8_Y1, MNG_LC_START);
21000 #endif
21001 
21002   MNG_COPY (pDstline, pSrcline1, iWidth * 3);
21003 
21004 #ifdef MNG_SUPPORT_TRACE
21005   MNG_TRACE (pData, MNG_FN_MAGNIFY_RGB8_Y1, MNG_LC_END);
21006 #endif
21007 
21008   return MNG_NOERROR;
21009 }
21010 
21011 /* ************************************************************************** */
21012 
mng_magnify_rgb8_y2(mng_datap pData,mng_int32 iS,mng_int32 iM,mng_uint32 iWidth,mng_uint8p pSrcline1,mng_uint8p pSrcline2,mng_uint8p pDstline)21013 mng_retcode mng_magnify_rgb8_y2 (mng_datap  pData,
21014                                  mng_int32  iS,
21015                                  mng_int32  iM,
21016                                  mng_uint32 iWidth,
21017                                  mng_uint8p pSrcline1,
21018                                  mng_uint8p pSrcline2,
21019                                  mng_uint8p pDstline)
21020 {
21021   mng_uint32 iX;
21022   mng_uint8p pTempsrc1;
21023   mng_uint8p pTempsrc2;
21024   mng_uint8p pTempdst;
21025 
21026 #ifdef MNG_SUPPORT_TRACE
21027   MNG_TRACE (pData, MNG_FN_MAGNIFY_RGB8_Y2, MNG_LC_START);
21028 #endif
21029 
21030   pTempsrc1 = pSrcline1;               /* initialize pixel-loop */
21031   pTempsrc2 = pSrcline2;
21032   pTempdst  = pDstline;
21033 
21034   if (pTempsrc2)                       /* do we have a second line ? */
21035   {
21036     for (iX = 0; iX < iWidth; iX++)
21037     {                                  /* calculate the distances */
21038       if (*pTempsrc1 == *pTempsrc2)
21039         *pTempdst = *pTempsrc1;
21040       else
21041         *pTempdst = (mng_uint8)( ( (2 * iS * ( (mng_int32)(*pTempsrc2) -
21042                                                (mng_int32)(*pTempsrc1) ) + iM) /
21043                                    (iM * 2) ) + (mng_int32)(*pTempsrc1) );
21044 
21045       pTempdst++;
21046       pTempsrc1++;
21047       pTempsrc2++;
21048 
21049       if (*pTempsrc1 == *pTempsrc2)
21050         *pTempdst = *pTempsrc1;
21051       else
21052         *pTempdst = (mng_uint8)( ( (2 * iS * ( (mng_int32)(*pTempsrc2) -
21053                                                (mng_int32)(*pTempsrc1) ) + iM) /
21054                                    (iM * 2) ) + (mng_int32)(*pTempsrc1) );
21055 
21056       pTempdst++;
21057       pTempsrc1++;
21058       pTempsrc2++;
21059 
21060       if (*pTempsrc1 == *pTempsrc2)
21061         *pTempdst = *pTempsrc1;
21062       else
21063         *pTempdst = (mng_uint8)( ( (2 * iS * ( (mng_int32)(*pTempsrc2) -
21064                                                (mng_int32)(*pTempsrc1) ) + iM) /
21065                                    (iM * 2) ) + (mng_int32)(*pTempsrc1) );
21066 
21067       pTempdst++;
21068       pTempsrc1++;
21069       pTempsrc2++;
21070     }
21071   }
21072   else
21073   {                                    /* just repeat the entire line */
21074     MNG_COPY (pTempdst, pTempsrc1, iWidth * 3);
21075   }
21076 
21077 #ifdef MNG_SUPPORT_TRACE
21078   MNG_TRACE (pData, MNG_FN_MAGNIFY_RGB8_Y2, MNG_LC_END);
21079 #endif
21080 
21081   return MNG_NOERROR;
21082 }
21083 
21084 /* ************************************************************************** */
21085 
mng_magnify_rgb8_y3(mng_datap pData,mng_int32 iS,mng_int32 iM,mng_uint32 iWidth,mng_uint8p pSrcline1,mng_uint8p pSrcline2,mng_uint8p pDstline)21086 mng_retcode mng_magnify_rgb8_y3 (mng_datap  pData,
21087                                  mng_int32  iS,
21088                                  mng_int32  iM,
21089                                  mng_uint32 iWidth,
21090                                  mng_uint8p pSrcline1,
21091                                  mng_uint8p pSrcline2,
21092                                  mng_uint8p pDstline)
21093 {
21094 #ifdef MNG_SUPPORT_TRACE
21095   MNG_TRACE (pData, MNG_FN_MAGNIFY_RGB8_Y3, MNG_LC_START);
21096 #endif
21097 
21098   if (pSrcline2)                       /* do we have a second line ? */
21099   {
21100     if (iS < (iM+1) / 2)               /* top half ? */
21101       MNG_COPY (pDstline, pSrcline1, iWidth * 3)
21102     else
21103       MNG_COPY (pDstline, pSrcline2, iWidth * 3);
21104   }
21105   else
21106   {                                    /* just repeat the entire line */
21107     MNG_COPY (pDstline, pSrcline1, iWidth * 3);
21108   }
21109 
21110 #ifdef MNG_SUPPORT_TRACE
21111   MNG_TRACE (pData, MNG_FN_MAGNIFY_RGB8_Y3, MNG_LC_END);
21112 #endif
21113 
21114   return MNG_NOERROR;
21115 }
21116 
21117 /* ************************************************************************** */
21118 
21119 #ifndef MNG_NO_GRAY_SUPPORT
mng_magnify_ga8_y1(mng_datap pData,mng_int32 iS,mng_int32 iM,mng_uint32 iWidth,mng_uint8p pSrcline1,mng_uint8p pSrcline2,mng_uint8p pDstline)21120 mng_retcode mng_magnify_ga8_y1 (mng_datap  pData,
21121                                 mng_int32  iS,
21122                                 mng_int32  iM,
21123                                 mng_uint32 iWidth,
21124                                 mng_uint8p pSrcline1,
21125                                 mng_uint8p pSrcline2,
21126                                 mng_uint8p pDstline)
21127 {
21128 #ifdef MNG_SUPPORT_TRACE
21129   MNG_TRACE (pData, MNG_FN_MAGNIFY_GA8_Y1, MNG_LC_START);
21130 #endif
21131 
21132   MNG_COPY (pDstline, pSrcline1, iWidth << 1);
21133 
21134 #ifdef MNG_SUPPORT_TRACE
21135   MNG_TRACE (pData, MNG_FN_MAGNIFY_GA8_Y1, MNG_LC_END);
21136 #endif
21137 
21138   return MNG_NOERROR;
21139 }
21140 
21141 /* ************************************************************************** */
21142 
mng_magnify_ga8_y2(mng_datap pData,mng_int32 iS,mng_int32 iM,mng_uint32 iWidth,mng_uint8p pSrcline1,mng_uint8p pSrcline2,mng_uint8p pDstline)21143 mng_retcode mng_magnify_ga8_y2 (mng_datap  pData,
21144                                 mng_int32  iS,
21145                                 mng_int32  iM,
21146                                 mng_uint32 iWidth,
21147                                 mng_uint8p pSrcline1,
21148                                 mng_uint8p pSrcline2,
21149                                 mng_uint8p pDstline)
21150 {
21151   mng_uint32 iX;
21152   mng_uint8p pTempsrc1;
21153   mng_uint8p pTempsrc2;
21154   mng_uint8p pTempdst;
21155 
21156 #ifdef MNG_SUPPORT_TRACE
21157   MNG_TRACE (pData, MNG_FN_MAGNIFY_GA8_Y2, MNG_LC_START);
21158 #endif
21159 
21160   pTempsrc1 = pSrcline1;               /* initialize pixel-loop */
21161   pTempsrc2 = pSrcline2;
21162   pTempdst  = pDstline;
21163 
21164   if (pTempsrc2)                       /* do we have a second line ? */
21165   {
21166     for (iX = 0; iX < iWidth; iX++)
21167     {                                  /* calculate the distances */
21168       if (*pTempsrc1 == *pTempsrc2)
21169         *pTempdst = *pTempsrc1;
21170       else
21171         *pTempdst = (mng_uint8)( ( (2 * iS * ( (mng_int32)(*pTempsrc2) -
21172                                                (mng_int32)(*pTempsrc1) ) + iM) /
21173                                    (iM * 2) ) + (mng_int32)(*pTempsrc1) );
21174 
21175       pTempdst++;
21176       pTempsrc1++;
21177       pTempsrc2++;
21178 
21179       if (*pTempsrc1 == *pTempsrc2)
21180         *pTempdst = *pTempsrc1;
21181       else
21182         *pTempdst = (mng_uint8)( ( (2 * iS * ( (mng_int32)(*pTempsrc2) -
21183                                                (mng_int32)(*pTempsrc1) ) + iM) /
21184                                    (iM * 2) ) + (mng_int32)(*pTempsrc1) );
21185 
21186       pTempdst++;
21187       pTempsrc1++;
21188       pTempsrc2++;
21189     }
21190   }
21191   else
21192   {                                    /* just repeat the entire line */
21193     MNG_COPY (pTempdst, pTempsrc1, iWidth << 1);
21194   }
21195 
21196 #ifdef MNG_SUPPORT_TRACE
21197   MNG_TRACE (pData, MNG_FN_MAGNIFY_GA8_Y2, MNG_LC_END);
21198 #endif
21199 
21200   return MNG_NOERROR;
21201 }
21202 
21203 /* ************************************************************************** */
21204 
mng_magnify_ga8_y3(mng_datap pData,mng_int32 iS,mng_int32 iM,mng_uint32 iWidth,mng_uint8p pSrcline1,mng_uint8p pSrcline2,mng_uint8p pDstline)21205 mng_retcode mng_magnify_ga8_y3 (mng_datap  pData,
21206                                 mng_int32  iS,
21207                                 mng_int32  iM,
21208                                 mng_uint32 iWidth,
21209                                 mng_uint8p pSrcline1,
21210                                 mng_uint8p pSrcline2,
21211                                 mng_uint8p pDstline)
21212 {
21213 #ifdef MNG_SUPPORT_TRACE
21214   MNG_TRACE (pData, MNG_FN_MAGNIFY_GA8_Y3, MNG_LC_START);
21215 #endif
21216 
21217   if (pSrcline2)                       /* do we have a second line ? */
21218   {
21219     if (iS < (iM+1) / 2)               /* top half ? */
21220       MNG_COPY (pDstline, pSrcline1, iWidth << 1)
21221     else
21222       MNG_COPY (pDstline, pSrcline2, iWidth << 1);
21223   }
21224   else
21225   {                                    /* just repeat the entire line */
21226     MNG_COPY (pDstline, pSrcline1, iWidth << 1);
21227   }
21228 
21229 #ifdef MNG_SUPPORT_TRACE
21230   MNG_TRACE (pData, MNG_FN_MAGNIFY_GA8_Y2, MNG_LC_END);
21231 #endif
21232 
21233   return MNG_NOERROR;
21234 }
21235 
21236 /* ************************************************************************** */
21237 
mng_magnify_ga8_y4(mng_datap pData,mng_int32 iS,mng_int32 iM,mng_uint32 iWidth,mng_uint8p pSrcline1,mng_uint8p pSrcline2,mng_uint8p pDstline)21238 mng_retcode mng_magnify_ga8_y4 (mng_datap  pData,
21239                                 mng_int32  iS,
21240                                 mng_int32  iM,
21241                                 mng_uint32 iWidth,
21242                                 mng_uint8p pSrcline1,
21243                                 mng_uint8p pSrcline2,
21244                                 mng_uint8p pDstline)
21245 {
21246   mng_uint32 iX;
21247   mng_uint8p pTempsrc1;
21248   mng_uint8p pTempsrc2;
21249   mng_uint8p pTempdst;
21250 
21251 #ifdef MNG_SUPPORT_TRACE
21252   MNG_TRACE (pData, MNG_FN_MAGNIFY_GA8_Y4, MNG_LC_START);
21253 #endif
21254 
21255   pTempsrc1 = pSrcline1;               /* initialize pixel-loop */
21256   pTempsrc2 = pSrcline2;
21257   pTempdst  = pDstline;
21258 
21259   if (pTempsrc2)                       /* do we have a second line ? */
21260   {
21261     if (iS < (iM+1) / 2)               /* top half ? */
21262     {
21263       for (iX = 0; iX < iWidth; iX++)
21264       {                                /* calculate the distances */
21265         if (*pTempsrc1 == *pTempsrc2)
21266           *pTempdst = *pTempsrc1;
21267         else
21268           *pTempdst = (mng_uint8)( ( (2 * iS * ( (mng_int32)(*pTempsrc2) -
21269                                                  (mng_int32)(*pTempsrc1) ) + iM) /
21270                                      (iM * 2) ) + (mng_int32)(*pTempsrc1) );
21271 
21272         pTempdst++;
21273         pTempsrc1++;
21274         pTempsrc2 += 2;
21275 
21276         *pTempdst++ = *pTempsrc1++;    /* replicate alpha from top */
21277       }
21278     }
21279     else
21280     {
21281       for (iX = 0; iX < iWidth; iX++)
21282       {                                /* calculate the distances */
21283         if (*pTempsrc1 == *pTempsrc2)
21284           *pTempdst = *pTempsrc1;
21285         else
21286           *pTempdst = (mng_uint8)( ( (2 * iS * ( (mng_int32)(*pTempsrc2) -
21287                                                  (mng_int32)(*pTempsrc1) ) + iM) /
21288                                      (iM * 2) ) + (mng_int32)(*pTempsrc1) );
21289 
21290         pTempdst++;
21291         pTempsrc1 += 2;
21292         pTempsrc2++;
21293 
21294         *pTempdst++ = *pTempsrc2++;    /* replicate alpha from bottom */
21295       }
21296     }
21297   }
21298   else
21299   {                                    /* just repeat the entire line */
21300     MNG_COPY (pTempdst, pTempsrc1, iWidth << 1);
21301   }
21302 
21303 #ifdef MNG_SUPPORT_TRACE
21304   MNG_TRACE (pData, MNG_FN_MAGNIFY_GA8_Y4, MNG_LC_END);
21305 #endif
21306 
21307   return MNG_NOERROR;
21308 }
21309 
21310 /* ************************************************************************** */
21311 
mng_magnify_ga8_y5(mng_datap pData,mng_int32 iS,mng_int32 iM,mng_uint32 iWidth,mng_uint8p pSrcline1,mng_uint8p pSrcline2,mng_uint8p pDstline)21312 mng_retcode mng_magnify_ga8_y5 (mng_datap  pData,
21313                                 mng_int32  iS,
21314                                 mng_int32  iM,
21315                                 mng_uint32 iWidth,
21316                                 mng_uint8p pSrcline1,
21317                                 mng_uint8p pSrcline2,
21318                                 mng_uint8p pDstline)
21319 {
21320   mng_uint32 iX;
21321   mng_uint8p pTempsrc1;
21322   mng_uint8p pTempsrc2;
21323   mng_uint8p pTempdst;
21324 
21325 #ifdef MNG_SUPPORT_TRACE
21326   MNG_TRACE (pData, MNG_FN_MAGNIFY_GA8_Y5, MNG_LC_START);
21327 #endif
21328 
21329   pTempsrc1 = pSrcline1;               /* initialize pixel-loop */
21330   pTempsrc2 = pSrcline2;
21331   pTempdst  = pDstline;
21332 
21333   if (pTempsrc2)                       /* do we have a second line ? */
21334   {
21335     if (iS < (iM+1) / 2)               /* top half ? */
21336     {
21337       for (iX = 0; iX < iWidth; iX++)
21338       {
21339         *pTempdst = *pTempsrc1;        /* replicate gray from top */
21340 
21341         pTempdst++;
21342         pTempsrc1++;
21343         pTempsrc2++;
21344 
21345         if (*pTempsrc1 == *pTempsrc2)  /* calculate the distances */
21346           *pTempdst = *pTempsrc1;
21347         else
21348           *pTempdst = (mng_uint8)( ( (2 * iS * ( (mng_int32)(*pTempsrc2) -
21349                                                  (mng_int32)(*pTempsrc1) ) + iM) /
21350                                      (iM * 2) ) + (mng_int32)(*pTempsrc1) );
21351 
21352         pTempdst++;
21353         pTempsrc1++;
21354         pTempsrc2++;
21355       }
21356     }
21357     else
21358     {
21359       for (iX = 0; iX < iWidth; iX++)
21360       {
21361         *pTempdst = *pTempsrc2;        /* replicate gray from bottom */
21362 
21363         pTempdst++;
21364         pTempsrc1++;
21365         pTempsrc2++;
21366 
21367         if (*pTempsrc1 == *pTempsrc2)  /* calculate the distances */
21368           *pTempdst = *pTempsrc1;
21369         else
21370           *pTempdst = (mng_uint8)( ( (2 * iS * ( (mng_int32)(*pTempsrc2) -
21371                                                  (mng_int32)(*pTempsrc1) ) + iM) /
21372                                      (iM * 2) ) + (mng_int32)(*pTempsrc1) );
21373 
21374         pTempdst++;
21375         pTempsrc1++;
21376         pTempsrc2++;
21377       }
21378     }
21379   }
21380   else
21381   {                                    /* just repeat the entire line */
21382     MNG_COPY (pTempdst, pTempsrc1, iWidth << 1);
21383   }
21384 
21385 #ifdef MNG_SUPPORT_TRACE
21386   MNG_TRACE (pData, MNG_FN_MAGNIFY_GA8_Y5, MNG_LC_END);
21387 #endif
21388 
21389   return MNG_NOERROR;
21390 }
21391 #endif /* MNG_NO_GRAY_SUPPORT */
21392 #endif /* MNG_OPTIMIZE_FOOTPRINT_MAGN */
21393 
21394 /* ************************************************************************** */
21395 
mng_magnify_rgba8_y1(mng_datap pData,mng_int32 iS,mng_int32 iM,mng_uint32 iWidth,mng_uint8p pSrcline1,mng_uint8p pSrcline2,mng_uint8p pDstline)21396 mng_retcode mng_magnify_rgba8_y1 (mng_datap  pData,
21397                                   mng_int32  iS,
21398                                   mng_int32  iM,
21399                                   mng_uint32 iWidth,
21400                                   mng_uint8p pSrcline1,
21401                                   mng_uint8p pSrcline2,
21402                                   mng_uint8p pDstline)
21403 {
21404 #ifdef MNG_SUPPORT_TRACE
21405   MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA8_Y1, MNG_LC_START);
21406 #endif
21407 
21408   MNG_COPY (pDstline, pSrcline1, iWidth << 2);
21409 
21410 #ifdef MNG_SUPPORT_TRACE
21411   MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA8_Y1, MNG_LC_END);
21412 #endif
21413 
21414   return MNG_NOERROR;
21415 }
21416 
21417 /* ************************************************************************** */
21418 
mng_magnify_rgba8_y2(mng_datap pData,mng_int32 iS,mng_int32 iM,mng_uint32 iWidth,mng_uint8p pSrcline1,mng_uint8p pSrcline2,mng_uint8p pDstline)21419 mng_retcode mng_magnify_rgba8_y2 (mng_datap  pData,
21420                                   mng_int32  iS,
21421                                   mng_int32  iM,
21422                                   mng_uint32 iWidth,
21423                                   mng_uint8p pSrcline1,
21424                                   mng_uint8p pSrcline2,
21425                                   mng_uint8p pDstline)
21426 {
21427   mng_uint32 iX;
21428   mng_uint8p pTempsrc1;
21429   mng_uint8p pTempsrc2;
21430   mng_uint8p pTempdst;
21431 
21432 #ifdef MNG_SUPPORT_TRACE
21433   MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA8_Y2, MNG_LC_START);
21434 #endif
21435 
21436   pTempsrc1 = pSrcline1;               /* initialize pixel-loop */
21437   pTempsrc2 = pSrcline2;
21438   pTempdst  = pDstline;
21439 
21440   if (pTempsrc2)                       /* do we have a second line ? */
21441   {
21442     for (iX = 0; iX < iWidth; iX++)
21443     {                                  /* calculate the distances */
21444       if (*pTempsrc1 == *pTempsrc2)
21445         *pTempdst = *pTempsrc1;
21446       else
21447         *pTempdst = (mng_uint8)( ( (2 * iS * ( (mng_int32)(*pTempsrc2) -
21448                                                (mng_int32)(*pTempsrc1) ) + iM) /
21449                                    (iM * 2) ) + (mng_int32)(*pTempsrc1) );
21450 
21451       pTempdst++;
21452       pTempsrc1++;
21453       pTempsrc2++;
21454 
21455       if (*pTempsrc1 == *pTempsrc2)
21456         *pTempdst = *pTempsrc1;
21457       else
21458         *pTempdst = (mng_uint8)( ( (2 * iS * ( (mng_int32)(*pTempsrc2) -
21459                                                (mng_int32)(*pTempsrc1) ) + iM) /
21460                                    (iM * 2) ) + (mng_int32)(*pTempsrc1) );
21461 
21462       pTempdst++;
21463       pTempsrc1++;
21464       pTempsrc2++;
21465 
21466       if (*pTempsrc1 == *pTempsrc2)
21467         *pTempdst = *pTempsrc1;
21468       else
21469         *pTempdst = (mng_uint8)( ( (2 * iS * ( (mng_int32)(*pTempsrc2) -
21470                                                (mng_int32)(*pTempsrc1) ) + iM) /
21471                                    (iM * 2) ) + (mng_int32)(*pTempsrc1) );
21472 
21473       pTempdst++;
21474       pTempsrc1++;
21475       pTempsrc2++;
21476 
21477       if (*pTempsrc1 == *pTempsrc2)
21478         *pTempdst = *pTempsrc1;
21479       else
21480         *pTempdst = (mng_uint8)( ( (2 * iS * ( (mng_int32)(*pTempsrc2) -
21481                                                (mng_int32)(*pTempsrc1) ) + iM) /
21482                                    (iM * 2) ) + (mng_int32)(*pTempsrc1) );
21483 
21484       pTempdst++;
21485       pTempsrc1++;
21486       pTempsrc2++;
21487     }
21488   }
21489   else
21490   {                                    /* just repeat the entire line */
21491     MNG_COPY (pTempdst, pTempsrc1, iWidth << 2);
21492   }
21493 
21494 #ifdef MNG_SUPPORT_TRACE
21495   MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA8_Y2, MNG_LC_END);
21496 #endif
21497 
21498   return MNG_NOERROR;
21499 }
21500 
21501 /* ************************************************************************** */
21502 
mng_magnify_rgba8_y3(mng_datap pData,mng_int32 iS,mng_int32 iM,mng_uint32 iWidth,mng_uint8p pSrcline1,mng_uint8p pSrcline2,mng_uint8p pDstline)21503 mng_retcode mng_magnify_rgba8_y3 (mng_datap  pData,
21504                                   mng_int32  iS,
21505                                   mng_int32  iM,
21506                                   mng_uint32 iWidth,
21507                                   mng_uint8p pSrcline1,
21508                                   mng_uint8p pSrcline2,
21509                                   mng_uint8p pDstline)
21510 {
21511 #ifdef MNG_SUPPORT_TRACE
21512   MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA8_Y3, MNG_LC_START);
21513 #endif
21514 
21515   if (pSrcline2)                       /* do we have a second line ? */
21516   {
21517     if (iS < (iM+1) / 2)               /* top half ? */
21518       MNG_COPY (pDstline, pSrcline1, iWidth << 2)
21519     else
21520       MNG_COPY (pDstline, pSrcline2, iWidth << 2);
21521   }
21522   else
21523   {                                    /* just repeat the entire line */
21524     MNG_COPY (pDstline, pSrcline1, iWidth << 2);
21525   }
21526 
21527 #ifdef MNG_SUPPORT_TRACE
21528   MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA8_Y2, MNG_LC_END);
21529 #endif
21530 
21531   return MNG_NOERROR;
21532 }
21533 
21534 /* ************************************************************************** */
21535 
mng_magnify_rgba8_y4(mng_datap pData,mng_int32 iS,mng_int32 iM,mng_uint32 iWidth,mng_uint8p pSrcline1,mng_uint8p pSrcline2,mng_uint8p pDstline)21536 mng_retcode mng_magnify_rgba8_y4 (mng_datap  pData,
21537                                   mng_int32  iS,
21538                                   mng_int32  iM,
21539                                   mng_uint32 iWidth,
21540                                   mng_uint8p pSrcline1,
21541                                   mng_uint8p pSrcline2,
21542                                   mng_uint8p pDstline)
21543 {
21544   mng_uint32 iX;
21545   mng_uint8p pTempsrc1;
21546   mng_uint8p pTempsrc2;
21547   mng_uint8p pTempdst;
21548 
21549 #ifdef MNG_SUPPORT_TRACE
21550   MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA8_Y4, MNG_LC_START);
21551 #endif
21552 
21553   pTempsrc1 = pSrcline1;               /* initialize pixel-loop */
21554   pTempsrc2 = pSrcline2;
21555   pTempdst  = pDstline;
21556 
21557   if (pTempsrc2)                       /* do we have a second line ? */
21558   {
21559     if (iS < (iM+1) / 2)               /* top half ? */
21560     {
21561       for (iX = 0; iX < iWidth; iX++)
21562       {                                /* calculate the distances */
21563         if (*pTempsrc1 == *pTempsrc2)
21564           *pTempdst = *pTempsrc1;
21565         else
21566           *pTempdst = (mng_uint8)( ( (2 * iS * ( (mng_int32)(*pTempsrc2) -
21567                                                  (mng_int32)(*pTempsrc1) ) + iM) /
21568                                      (iM * 2) ) + (mng_int32)(*pTempsrc1) );
21569 
21570         pTempdst++;
21571         pTempsrc1++;
21572         pTempsrc2++;
21573 
21574         if (*pTempsrc1 == *pTempsrc2)
21575           *pTempdst = *pTempsrc1;
21576         else
21577           *pTempdst = (mng_uint8)( ( (2 * iS * ( (mng_int32)(*pTempsrc2) -
21578                                                  (mng_int32)(*pTempsrc1) ) + iM) /
21579                                      (iM * 2) ) + (mng_int32)(*pTempsrc1) );
21580 
21581         pTempdst++;
21582         pTempsrc1++;
21583         pTempsrc2++;
21584 
21585         if (*pTempsrc1 == *pTempsrc2)
21586           *pTempdst = *pTempsrc1;
21587         else
21588           *pTempdst = (mng_uint8)( ( (2 * iS * ( (mng_int32)(*pTempsrc2) -
21589                                                  (mng_int32)(*pTempsrc1) ) + iM) /
21590                                      (iM * 2) ) + (mng_int32)(*pTempsrc1) );
21591 
21592         pTempdst++;
21593         pTempsrc1++;
21594         pTempsrc2 += 2;
21595 
21596         *pTempdst++ = *pTempsrc1++;    /* replicate alpha from top */
21597       }
21598     }
21599     else
21600     {
21601       for (iX = 0; iX < iWidth; iX++)
21602       {                                /* calculate the distances */
21603         if (*pTempsrc1 == *pTempsrc2)
21604           *pTempdst = *pTempsrc1;
21605         else
21606           *pTempdst = (mng_uint8)( ( (2 * iS * ( (mng_int32)(*pTempsrc2) -
21607                                                  (mng_int32)(*pTempsrc1) ) + iM) /
21608                                      (iM * 2) ) + (mng_int32)(*pTempsrc1) );
21609 
21610         pTempdst++;
21611         pTempsrc1++;
21612         pTempsrc2++;
21613 
21614         if (*pTempsrc1 == *pTempsrc2)
21615           *pTempdst = *pTempsrc1;
21616         else
21617           *pTempdst = (mng_uint8)( ( (2 * iS * ( (mng_int32)(*pTempsrc2) -
21618                                                  (mng_int32)(*pTempsrc1) ) + iM) /
21619                                      (iM * 2) ) + (mng_int32)(*pTempsrc1) );
21620 
21621         pTempdst++;
21622         pTempsrc1++;
21623         pTempsrc2++;
21624 
21625         if (*pTempsrc1 == *pTempsrc2)
21626           *pTempdst = *pTempsrc1;
21627         else
21628           *pTempdst = (mng_uint8)( ( (2 * iS * ( (mng_int32)(*pTempsrc2) -
21629                                                  (mng_int32)(*pTempsrc1) ) + iM) /
21630                                      (iM * 2) ) + (mng_int32)(*pTempsrc1) );
21631 
21632         pTempdst++;
21633         pTempsrc1 += 2;
21634         pTempsrc2++;
21635 
21636         *pTempdst++ = *pTempsrc2++;    /* replicate alpha from bottom */
21637       }
21638     }
21639   }
21640   else
21641   {                                    /* just repeat the entire line */
21642     MNG_COPY (pTempdst, pTempsrc1, iWidth << 2);
21643   }
21644 
21645 #ifdef MNG_SUPPORT_TRACE
21646   MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA8_Y4, MNG_LC_END);
21647 #endif
21648 
21649   return MNG_NOERROR;
21650 }
21651 
21652 /* ************************************************************************** */
21653 
mng_magnify_rgba8_y5(mng_datap pData,mng_int32 iS,mng_int32 iM,mng_uint32 iWidth,mng_uint8p pSrcline1,mng_uint8p pSrcline2,mng_uint8p pDstline)21654 mng_retcode mng_magnify_rgba8_y5 (mng_datap  pData,
21655                                   mng_int32  iS,
21656                                   mng_int32  iM,
21657                                   mng_uint32 iWidth,
21658                                   mng_uint8p pSrcline1,
21659                                   mng_uint8p pSrcline2,
21660                                   mng_uint8p pDstline)
21661 {
21662   mng_uint32 iX;
21663   mng_uint8p pTempsrc1;
21664   mng_uint8p pTempsrc2;
21665   mng_uint8p pTempdst;
21666 
21667 #ifdef MNG_SUPPORT_TRACE
21668   MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA8_Y5, MNG_LC_START);
21669 #endif
21670 
21671   pTempsrc1 = pSrcline1;               /* initialize pixel-loop */
21672   pTempsrc2 = pSrcline2;
21673   pTempdst  = pDstline;
21674 
21675   if (pTempsrc2)                       /* do we have a second line ? */
21676   {
21677     if (iS < (iM+1) / 2)               /* top half ? */
21678     {
21679       for (iX = 0; iX < iWidth; iX++)
21680       {
21681         *pTempdst++ = *pTempsrc1++;    /* replicate color from top */
21682         *pTempdst++ = *pTempsrc1++;
21683         *pTempdst++ = *pTempsrc1++;
21684 
21685         pTempsrc2 += 3;
21686 
21687         if (*pTempsrc1 == *pTempsrc2)  /* calculate the distances */
21688           *pTempdst = *pTempsrc1;
21689         else
21690           *pTempdst = (mng_uint8)( ( (2 * iS * ( (mng_int32)(*pTempsrc2) -
21691                                                  (mng_int32)(*pTempsrc1) ) + iM) /
21692                                      (iM * 2) ) + (mng_int32)(*pTempsrc1) );
21693 
21694         pTempdst++;
21695         pTempsrc1++;
21696         pTempsrc2++;
21697       }
21698     }
21699     else
21700     {
21701       for (iX = 0; iX < iWidth; iX++)
21702       {
21703         *pTempdst++ = *pTempsrc2++;    /* replicate color from bottom */
21704         *pTempdst++ = *pTempsrc2++;
21705         *pTempdst++ = *pTempsrc2++;
21706 
21707         pTempsrc1 += 3;
21708 
21709         if (*pTempsrc1 == *pTempsrc2)  /* calculate the distances */
21710           *pTempdst = *pTempsrc1;
21711         else
21712           *pTempdst = (mng_uint8)( ( (2 * iS * ( (mng_int32)(*pTempsrc2) -
21713                                                  (mng_int32)(*pTempsrc1) ) + iM) /
21714                                      (iM * 2) ) + (mng_int32)(*pTempsrc1) );
21715 
21716         pTempdst++;
21717         pTempsrc1++;
21718         pTempsrc2++;
21719       }
21720     }
21721   }
21722   else
21723   {                                    /* just repeat the entire line */
21724     MNG_COPY (pTempdst, pTempsrc1, iWidth << 2);
21725   }
21726 
21727 #ifdef MNG_SUPPORT_TRACE
21728   MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA8_Y5, MNG_LC_END);
21729 #endif
21730 
21731   return MNG_NOERROR;
21732 }
21733 
21734 /* ************************************************************************** */
21735 
21736 #ifndef MNG_OPTIMIZE_FOOTPRINT_MAGN
21737 #ifndef MNG_NO_16BIT_SUPPORT
21738 #ifndef MNG_NO_GRAY_SUPPORT
mng_magnify_g16_x1(mng_datap pData,mng_uint16 iMX,mng_uint16 iML,mng_uint16 iMR,mng_uint32 iWidth,mng_uint8p pSrcline,mng_uint8p pDstline)21739 mng_retcode mng_magnify_g16_x1 (mng_datap  pData,
21740                                 mng_uint16 iMX,
21741                                 mng_uint16 iML,
21742                                 mng_uint16 iMR,
21743                                 mng_uint32 iWidth,
21744                                 mng_uint8p pSrcline,
21745                                 mng_uint8p pDstline)
21746 {
21747   mng_uint32  iX, iS, iM;
21748   mng_uint16p pTempsrc1;
21749   mng_uint16p pTempdst;
21750 
21751 #ifdef MNG_SUPPORT_TRACE
21752   MNG_TRACE (pData, MNG_FN_MAGNIFY_G16_X1, MNG_LC_START);
21753 #endif
21754 
21755   pTempsrc1 = (mng_uint16p)pSrcline;   /* initialize pixel-loop */
21756   pTempdst  = (mng_uint16p)pDstline;
21757 
21758   for (iX = 0; iX < iWidth; iX++)
21759   {
21760     *pTempdst = *pTempsrc1;            /* copy original source pixel */
21761     pTempdst++;
21762 
21763     if (iX == 0)                       /* first interval ? */
21764       iM = iML;
21765     else
21766     if (iX == (iWidth - 1))            /* last interval ? */
21767       iM = iMR;
21768     else
21769       iM = iMX;
21770 
21771     for (iS = 1; iS < iM; iS++)        /* fill interval */
21772     {
21773       *pTempdst = *pTempsrc1;          /* copy original source pixel */
21774       pTempdst++;
21775     }
21776 
21777     pTempsrc1++;
21778   }
21779 
21780 #ifdef MNG_SUPPORT_TRACE
21781   MNG_TRACE (pData, MNG_FN_MAGNIFY_G16_X1, MNG_LC_END);
21782 #endif
21783 
21784   return MNG_NOERROR;
21785 }
21786 
21787 /* ************************************************************************** */
21788 
mng_magnify_g16_x2(mng_datap pData,mng_uint16 iMX,mng_uint16 iML,mng_uint16 iMR,mng_uint32 iWidth,mng_uint8p pSrcline,mng_uint8p pDstline)21789 mng_retcode mng_magnify_g16_x2 (mng_datap  pData,
21790                                 mng_uint16 iMX,
21791                                 mng_uint16 iML,
21792                                 mng_uint16 iMR,
21793                                 mng_uint32 iWidth,
21794                                 mng_uint8p pSrcline,
21795                                 mng_uint8p pDstline)
21796 {
21797   mng_uint32  iX;
21798   mng_int32   iS, iM;
21799   mng_uint16p pTempsrc1;
21800   mng_uint16p pTempsrc2;
21801   mng_uint16p pTempdst;
21802 
21803 #ifdef MNG_SUPPORT_TRACE
21804   MNG_TRACE (pData, MNG_FN_MAGNIFY_G16_X2, MNG_LC_START);
21805 #endif
21806 
21807   pTempsrc1 = (mng_uint16p)pSrcline;   /* initialize pixel-loop */
21808   pTempdst  = (mng_uint16p)pDstline;
21809 
21810   for (iX = 0; iX < iWidth; iX++)
21811   {
21812     pTempsrc2 = pTempsrc1 + 1;
21813 
21814     *pTempdst = *pTempsrc1;            /* copy original source pixel */
21815     pTempdst++;
21816 
21817     if (iX == 0)                       /* first interval ? */
21818     {
21819       if (iWidth == 1)                 /* single pixel ? */
21820         pTempsrc2 = MNG_NULL;
21821 
21822       iM = iML;
21823     }
21824     else
21825     if (iX == (iWidth - 2))            /* last interval ? */
21826       iM = iMR;
21827     else
21828       iM = iMX;
21829                                        /* fill interval ? */
21830     if ((iX < iWidth - 1) || (iWidth == 1))
21831     {
21832       if (pTempsrc2)                   /* do we have the second pixel ? */
21833       {                                /* is it same as first ? */
21834         if (*pTempsrc1 == *pTempsrc2)
21835         {
21836           for (iS = 1; iS < iM; iS++)  /* then just repeat the first */
21837           {
21838             *pTempdst = *pTempsrc1;
21839             pTempdst++;
21840           }
21841         }
21842         else
21843         {
21844           for (iS = 1; iS < iM; iS++)  /* calculate the distances */
21845           {
21846             mng_put_uint16 ((mng_uint8p)pTempdst,
21847                             (mng_uint16)(((2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc2))   -
21848                                                       (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1)) ) + iM) /
21849                                           (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1))          ));
21850             pTempdst++;
21851           }
21852         }
21853       }
21854       else
21855       {
21856         for (iS = 1; iS < iM; iS++)
21857         {
21858           *pTempdst = *pTempsrc1;      /* repeat first source pixel */
21859           pTempdst++;
21860         }
21861       }
21862     }
21863 
21864     pTempsrc1++;
21865   }
21866 
21867 #ifdef MNG_SUPPORT_TRACE
21868   MNG_TRACE (pData, MNG_FN_MAGNIFY_G16_X2, MNG_LC_END);
21869 #endif
21870 
21871   return MNG_NOERROR;
21872 }
21873 
21874 /* ************************************************************************** */
21875 
mng_magnify_g16_x3(mng_datap pData,mng_uint16 iMX,mng_uint16 iML,mng_uint16 iMR,mng_uint32 iWidth,mng_uint8p pSrcline,mng_uint8p pDstline)21876 mng_retcode mng_magnify_g16_x3 (mng_datap  pData,
21877                                 mng_uint16 iMX,
21878                                 mng_uint16 iML,
21879                                 mng_uint16 iMR,
21880                                 mng_uint32 iWidth,
21881                                 mng_uint8p pSrcline,
21882                                 mng_uint8p pDstline)
21883 {
21884   mng_uint32  iX;
21885   mng_int32   iS, iM, iH;
21886   mng_uint16p pTempsrc1;
21887   mng_uint16p pTempsrc2;
21888   mng_uint16p pTempdst;
21889 
21890 #ifdef MNG_SUPPORT_TRACE
21891   MNG_TRACE (pData, MNG_FN_MAGNIFY_G16_X3, MNG_LC_START);
21892 #endif
21893 
21894   pTempsrc1 = (mng_uint16p)pSrcline;   /* initialize pixel-loop */
21895   pTempdst  = (mng_uint16p)pDstline;
21896 
21897   for (iX = 0; iX < iWidth; iX++)
21898   {
21899     pTempsrc2 = pTempsrc1 + 1;
21900 
21901     *pTempdst = *pTempsrc1;            /* copy original source pixel */
21902     pTempdst++;
21903 
21904     if (iX == 0)                       /* first interval ? */
21905     {
21906       if (iWidth == 1)                 /* single pixel ? */
21907         pTempsrc2 = MNG_NULL;
21908 
21909       iM = iML;
21910     }
21911     else
21912     if (iX == (iWidth - 2))            /* last interval ? */
21913       iM = iMR;
21914     else
21915       iM = iMX;
21916                                        /* fill interval ? */
21917     if ((iX < iWidth - 1) || (iWidth == 1))
21918     {
21919       if (pTempsrc2)                   /* do we have the second pixel ? */
21920       {                                /* is it same as first ? */
21921         if (*pTempsrc1 == *pTempsrc2)
21922         {
21923           for (iS = 1; iS < iM; iS++)  /* then just repeat the first */
21924           {
21925             *pTempdst = *pTempsrc1;
21926             pTempdst++;
21927           }
21928         }
21929         else
21930         {
21931           iH = (iM+1) / 2;             /* calculate halfway point */
21932 
21933           for (iS = 1; iS < iH; iS++)  /* replicate first half */
21934           {
21935             *pTempdst = *pTempsrc1;
21936             pTempdst++;
21937           }
21938 
21939           for (iS = iH; iS < iM; iS++) /* replicate second half */
21940           {
21941             *pTempdst = *pTempsrc2;
21942             pTempdst++;
21943           }
21944         }
21945       }
21946       else
21947       {
21948         for (iS = 1; iS < iM; iS++)
21949         {
21950           *pTempdst = *pTempsrc1;      /* repeat first source pixel */
21951           pTempdst++;
21952         }
21953       }
21954     }
21955 
21956     pTempsrc1++;
21957   }
21958 
21959 #ifdef MNG_SUPPORT_TRACE
21960   MNG_TRACE (pData, MNG_FN_MAGNIFY_G16_X3, MNG_LC_END);
21961 #endif
21962 
21963   return MNG_NOERROR;
21964 }
21965 #endif /* MNG_NO_GRAY_SUPPORT */
21966 
21967 /* ************************************************************************** */
21968 
mng_magnify_rgb16_x1(mng_datap pData,mng_uint16 iMX,mng_uint16 iML,mng_uint16 iMR,mng_uint32 iWidth,mng_uint8p pSrcline,mng_uint8p pDstline)21969 mng_retcode mng_magnify_rgb16_x1 (mng_datap  pData,
21970                                   mng_uint16 iMX,
21971                                   mng_uint16 iML,
21972                                   mng_uint16 iMR,
21973                                   mng_uint32 iWidth,
21974                                   mng_uint8p pSrcline,
21975                                   mng_uint8p pDstline)
21976 {
21977   mng_uint32  iX, iS, iM;
21978   mng_uint16p pTempsrc1;
21979   mng_uint16p pTempdst;
21980 
21981 #ifdef MNG_SUPPORT_TRACE
21982   MNG_TRACE (pData, MNG_FN_MAGNIFY_RGB16_X1, MNG_LC_START);
21983 #endif
21984 
21985   pTempsrc1 = (mng_uint16p)pSrcline;   /* initialize pixel-loop */
21986   pTempdst  = (mng_uint16p)pDstline;
21987 
21988   for (iX = 0; iX < iWidth; iX++)
21989   {
21990     *pTempdst = *pTempsrc1;            /* copy original source pixel */
21991     pTempdst++;
21992     *pTempdst = *(pTempsrc1+1);
21993     pTempdst++;
21994     *pTempdst = *(pTempsrc1+2);
21995     pTempdst++;
21996 
21997     if (iX == 0)                       /* first interval ? */
21998       iM = iML;
21999     else
22000     if (iX == (iWidth - 1))            /* last interval ? */
22001       iM = iMR;
22002     else
22003       iM = iMX;
22004 
22005     for (iS = 1; iS < iM; iS++)        /* fill interval */
22006     {
22007       *pTempdst = *pTempsrc1;          /* copy original source pixel */
22008       pTempdst++;
22009       *pTempdst = *(pTempsrc1+1);
22010       pTempdst++;
22011       *pTempdst = *(pTempsrc1+2);
22012       pTempdst++;
22013     }
22014 
22015     pTempsrc1 += 3;
22016   }
22017 
22018 #ifdef MNG_SUPPORT_TRACE
22019   MNG_TRACE (pData, MNG_FN_MAGNIFY_RGB16_X1, MNG_LC_END);
22020 #endif
22021 
22022   return MNG_NOERROR;
22023 }
22024 
22025 /* ************************************************************************** */
22026 
mng_magnify_rgb16_x2(mng_datap pData,mng_uint16 iMX,mng_uint16 iML,mng_uint16 iMR,mng_uint32 iWidth,mng_uint8p pSrcline,mng_uint8p pDstline)22027 mng_retcode mng_magnify_rgb16_x2 (mng_datap  pData,
22028                                   mng_uint16 iMX,
22029                                   mng_uint16 iML,
22030                                   mng_uint16 iMR,
22031                                   mng_uint32 iWidth,
22032                                   mng_uint8p pSrcline,
22033                                   mng_uint8p pDstline)
22034 {
22035   mng_uint32  iX;
22036   mng_int32   iS, iM;
22037   mng_uint16p pTempsrc1;
22038   mng_uint16p pTempsrc2;
22039   mng_uint16p pTempdst;
22040 
22041 #ifdef MNG_SUPPORT_TRACE
22042   MNG_TRACE (pData, MNG_FN_MAGNIFY_RGB16_X2, MNG_LC_START);
22043 #endif
22044 
22045   pTempsrc1 = (mng_uint16p)pSrcline;   /* initialize pixel-loop */
22046   pTempdst  = (mng_uint16p)pDstline;
22047 
22048   for (iX = 0; iX < iWidth; iX++)
22049   {
22050     pTempsrc2 = pTempsrc1 + 3;
22051 
22052     *pTempdst = *pTempsrc1;            /* copy original source pixel */
22053     pTempdst++;
22054     *pTempdst = *(pTempsrc1+1);
22055     pTempdst++;
22056     *pTempdst = *(pTempsrc1+2);
22057     pTempdst++;
22058 
22059     if (iX == 0)                       /* first interval ? */
22060     {
22061       if (iWidth == 1)                 /* single pixel ? */
22062         pTempsrc2 = MNG_NULL;
22063 
22064       iM = (mng_int32)iML;
22065     }
22066     else
22067     if (iX == (iWidth - 2))            /* last interval ? */
22068       iM = (mng_int32)iMR;
22069     else
22070       iM = (mng_int32)iMX;
22071                                        /* fill interval ? */
22072     if ((iX < iWidth - 1) || (iWidth == 1))
22073     {
22074       if (pTempsrc2)                   /* do we have the second pixel ? */
22075       {
22076         for (iS = 1; iS < iM; iS++)
22077         {
22078           if (*pTempsrc1 == *pTempsrc2)
22079             *pTempdst = *pTempsrc1;    /* just repeat the first */
22080           else                         /* calculate the distance */
22081             mng_put_uint16 ((mng_uint8p)pTempdst,
22082                             (mng_uint16)(((2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc2)) -
22083                                                       (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1)) ) + iM) /
22084                                           (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1))         ) );
22085 
22086           pTempdst++;
22087 
22088           if (*(pTempsrc1+1) == *(pTempsrc2+1))
22089             *pTempdst = *(pTempsrc1+1);
22090           else
22091             mng_put_uint16 ((mng_uint8p)pTempdst,
22092                             (mng_uint16)(((2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc2+1))) -
22093                                                       (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc1+1))) ) + iM) /
22094                                           (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc1+1)))         ) );
22095 
22096           pTempdst++;
22097 
22098           if (*(pTempsrc1+2) == *(pTempsrc2+2))
22099             *pTempdst = *(pTempsrc1+2);
22100           else
22101             mng_put_uint16 ((mng_uint8p)pTempdst,
22102                             (mng_uint16)(((2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc2+2))) -
22103                                                       (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc1+2))) ) + iM) /
22104                                           (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc1+2)))         ) );
22105 
22106           pTempdst++;
22107         }
22108       }
22109       else
22110       {
22111         for (iS = 1; iS < iM; iS++)
22112         {
22113           *pTempdst = *pTempsrc1;      /* repeat first source pixel */
22114           pTempdst++;
22115           *pTempdst = *(pTempsrc1+1);
22116           pTempdst++;
22117           *pTempdst = *(pTempsrc1+2);
22118           pTempdst++;
22119         }
22120       }
22121     }
22122 
22123     pTempsrc1 += 3;
22124   }
22125 
22126 #ifdef MNG_SUPPORT_TRACE
22127   MNG_TRACE (pData, MNG_FN_MAGNIFY_RGB16_X2, MNG_LC_END);
22128 #endif
22129 
22130   return MNG_NOERROR;
22131 }
22132 
22133 /* ************************************************************************** */
22134 
mng_magnify_rgb16_x3(mng_datap pData,mng_uint16 iMX,mng_uint16 iML,mng_uint16 iMR,mng_uint32 iWidth,mng_uint8p pSrcline,mng_uint8p pDstline)22135 mng_retcode mng_magnify_rgb16_x3 (mng_datap  pData,
22136                                   mng_uint16 iMX,
22137                                   mng_uint16 iML,
22138                                   mng_uint16 iMR,
22139                                   mng_uint32 iWidth,
22140                                   mng_uint8p pSrcline,
22141                                   mng_uint8p pDstline)
22142 {
22143   mng_uint32  iX;
22144   mng_int32   iS, iM, iH;
22145   mng_uint16p pTempsrc1;
22146   mng_uint16p pTempsrc2;
22147   mng_uint16p pTempdst;
22148 
22149 #ifdef MNG_SUPPORT_TRACE
22150   MNG_TRACE (pData, MNG_FN_MAGNIFY_RGB16_X3, MNG_LC_START);
22151 #endif
22152 
22153   pTempsrc1 = (mng_uint16p)pSrcline;   /* initialize pixel-loop */
22154   pTempdst  = (mng_uint16p)pDstline;
22155 
22156   for (iX = 0; iX < iWidth; iX++)
22157   {
22158     pTempsrc2 = pTempsrc1 + 3;
22159 
22160     *pTempdst = *pTempsrc1;            /* copy original source pixel */
22161     pTempdst++;
22162     *pTempdst = *(pTempsrc1+1);
22163     pTempdst++;
22164     *pTempdst = *(pTempsrc1+2);
22165     pTempdst++;
22166 
22167     if (iX == 0)                       /* first interval ? */
22168     {
22169       if (iWidth == 1)                 /* single pixel ? */
22170         pTempsrc2 = MNG_NULL;
22171 
22172       iM = (mng_int32)iML;
22173     }
22174     else
22175     if (iX == (iWidth - 2))            /* last interval ? */
22176       iM = (mng_int32)iMR;
22177     else
22178       iM = (mng_int32)iMX;
22179                                        /* fill interval ? */
22180     if ((iX < iWidth - 1) || (iWidth == 1))
22181     {
22182       if (pTempsrc2)                   /* do we have the second pixel ? */
22183       {
22184         iH = (iM+1) / 2;               /* calculate halfway point */
22185 
22186         for (iS = 1; iS < iH; iS++)    /* replicate first half */
22187         {
22188           *pTempdst     = *pTempsrc1;
22189           *(pTempdst+1) = *(pTempsrc1+1);
22190           *(pTempdst+2) = *(pTempsrc1+2);
22191 
22192           pTempdst += 3;
22193         }
22194 
22195         for (iS = iH; iS < iM; iS++)    /* replicate second half */
22196         {
22197           *pTempdst     = *pTempsrc2;
22198           *(pTempdst+1) = *(pTempsrc2+1);
22199           *(pTempdst+2) = *(pTempsrc2+2);
22200 
22201           pTempdst += 3;
22202         }
22203       }
22204       else
22205       {
22206         for (iS = 1; iS < iM; iS++)
22207         {
22208           *pTempdst = *pTempsrc1;      /* repeat first source pixel */
22209           pTempdst++;
22210           *pTempdst = *(pTempsrc1+1);
22211           pTempdst++;
22212           *pTempdst = *(pTempsrc1+2);
22213           pTempdst++;
22214         }
22215       }
22216     }
22217 
22218     pTempsrc1 += 3;
22219   }
22220 
22221 #ifdef MNG_SUPPORT_TRACE
22222   MNG_TRACE (pData, MNG_FN_MAGNIFY_RGB16_X3, MNG_LC_END);
22223 #endif
22224 
22225   return MNG_NOERROR;
22226 }
22227 
22228 /* ************************************************************************** */
22229 
22230 #ifndef MNG_NO_GRAY_SUPPORT
mng_magnify_ga16_x1(mng_datap pData,mng_uint16 iMX,mng_uint16 iML,mng_uint16 iMR,mng_uint32 iWidth,mng_uint8p pSrcline,mng_uint8p pDstline)22231 mng_retcode mng_magnify_ga16_x1 (mng_datap  pData,
22232                                  mng_uint16 iMX,
22233                                  mng_uint16 iML,
22234                                  mng_uint16 iMR,
22235                                  mng_uint32 iWidth,
22236                                  mng_uint8p pSrcline,
22237                                  mng_uint8p pDstline)
22238 {
22239   mng_uint32  iX, iS, iM;
22240   mng_uint16p pTempsrc1;
22241   mng_uint16p pTempdst;
22242 
22243 #ifdef MNG_SUPPORT_TRACE
22244   MNG_TRACE (pData, MNG_FN_MAGNIFY_GA16_X1, MNG_LC_START);
22245 #endif
22246 
22247   pTempsrc1 = (mng_uint16p) pSrcline;  /* initialize pixel-loop */
22248   pTempdst  = (mng_uint16p)pDstline;
22249 
22250   for (iX = 0; iX < iWidth; iX++)
22251   {
22252     *pTempdst = *pTempsrc1;            /* copy original source pixel */
22253     pTempdst++;
22254     *pTempdst = *(pTempsrc1+1);
22255     pTempdst++;
22256 
22257     if (iX == 0)                       /* first interval ? */
22258       iM = iML;
22259     else
22260     if (iX == (iWidth - 1))            /* last interval ? */
22261       iM = iMR;
22262     else
22263       iM = iMX;
22264 
22265     for (iS = 1; iS < iM; iS++)        /* fill interval */
22266     {
22267       *pTempdst = *pTempsrc1;          /* copy original source pixel */
22268       pTempdst++;
22269       *pTempdst = *(pTempsrc1+1);
22270       pTempdst++;
22271     }
22272 
22273     pTempsrc1 += 2;
22274   }
22275 
22276 #ifdef MNG_SUPPORT_TRACE
22277   MNG_TRACE (pData, MNG_FN_MAGNIFY_GA16_X1, MNG_LC_END);
22278 #endif
22279 
22280   return MNG_NOERROR;
22281 }
22282 
22283 /* ************************************************************************** */
22284 
mng_magnify_ga16_x2(mng_datap pData,mng_uint16 iMX,mng_uint16 iML,mng_uint16 iMR,mng_uint32 iWidth,mng_uint8p pSrcline,mng_uint8p pDstline)22285 mng_retcode mng_magnify_ga16_x2 (mng_datap  pData,
22286                                  mng_uint16 iMX,
22287                                  mng_uint16 iML,
22288                                  mng_uint16 iMR,
22289                                  mng_uint32 iWidth,
22290                                  mng_uint8p pSrcline,
22291                                  mng_uint8p pDstline)
22292 {
22293   mng_uint32  iX;
22294   mng_int32   iS, iM;
22295   mng_uint16p pTempsrc1;
22296   mng_uint16p pTempsrc2;
22297   mng_uint16p pTempdst;
22298 
22299 #ifdef MNG_SUPPORT_TRACE
22300   MNG_TRACE (pData, MNG_FN_MAGNIFY_GA16_X2, MNG_LC_START);
22301 #endif
22302 
22303   pTempsrc1 = (mng_uint16p)pSrcline;   /* initialize pixel-loop */
22304   pTempdst  = (mng_uint16p)pDstline;
22305 
22306   for (iX = 0; iX < iWidth; iX++)
22307   {
22308     pTempsrc2 = pTempsrc1 + 2;
22309 
22310     *pTempdst = *pTempsrc1;            /* copy original source pixel */
22311     pTempdst++;
22312     *pTempdst = *(pTempsrc1+1);
22313     pTempdst++;
22314 
22315     if (iX == 0)                       /* first interval ? */
22316     {
22317       if (iWidth == 1)                 /* single pixel ? */
22318         pTempsrc2 = MNG_NULL;
22319 
22320       iM = iML;
22321     }
22322     else
22323     if (iX == (iWidth - 2))            /* last interval ? */
22324       iM = iMR;
22325     else
22326       iM = iMX;
22327                                        /* fill interval ? */
22328     if ((iX < iWidth - 1) || (iWidth == 1))
22329     {
22330       if (pTempsrc2)                   /* do we have the second pixel ? */
22331       {
22332         for (iS = 1; iS < iM; iS++)
22333         {
22334           if (*pTempsrc1 == *pTempsrc2)
22335             *pTempdst = *pTempsrc1;    /* just repeat the first */
22336           else                         /* calculate the distance */
22337             mng_put_uint16 ((mng_uint8p)pTempdst,
22338                             (mng_uint16)(((2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc2)) -
22339                                                       (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1)) ) + iM) /
22340                                           (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1))         ) );
22341 
22342           pTempdst++;
22343 
22344           if (*(pTempsrc1+1) == *(pTempsrc2+1))
22345             *pTempdst = *(pTempsrc1+1);
22346           else
22347             mng_put_uint16 ((mng_uint8p)pTempdst,
22348                             (mng_uint16)(((2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc2+1))) -
22349                                                       (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc1+1))) ) + iM) /
22350                                           (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc1+1)))         ) );
22351 
22352           pTempdst++;
22353         }
22354       }
22355       else
22356       {
22357         for (iS = 1; iS < iM; iS++)
22358         {
22359           *pTempdst = *pTempsrc1;      /* repeat first source pixel */
22360           pTempdst++;
22361           *pTempdst = *(pTempsrc1+1);
22362           pTempdst++;
22363         }
22364       }
22365     }
22366 
22367     pTempsrc1 += 2;
22368   }
22369 
22370 #ifdef MNG_SUPPORT_TRACE
22371   MNG_TRACE (pData, MNG_FN_MAGNIFY_GA16_X2, MNG_LC_END);
22372 #endif
22373 
22374   return MNG_NOERROR;
22375 }
22376 
22377 /* ************************************************************************** */
22378 
mng_magnify_ga16_x3(mng_datap pData,mng_uint16 iMX,mng_uint16 iML,mng_uint16 iMR,mng_uint32 iWidth,mng_uint8p pSrcline,mng_uint8p pDstline)22379 mng_retcode mng_magnify_ga16_x3 (mng_datap  pData,
22380                                  mng_uint16 iMX,
22381                                  mng_uint16 iML,
22382                                  mng_uint16 iMR,
22383                                  mng_uint32 iWidth,
22384                                  mng_uint8p pSrcline,
22385                                  mng_uint8p pDstline)
22386 {
22387   mng_uint32  iX;
22388   mng_int32   iS, iM, iH;
22389   mng_uint16p pTempsrc1;
22390   mng_uint16p pTempsrc2;
22391   mng_uint16p pTempdst;
22392 
22393 #ifdef MNG_SUPPORT_TRACE
22394   MNG_TRACE (pData, MNG_FN_MAGNIFY_GA16_X3, MNG_LC_START);
22395 #endif
22396 
22397   pTempsrc1 = (mng_uint16p)pSrcline;   /* initialize pixel-loop */
22398   pTempdst  = (mng_uint16p)pDstline;
22399 
22400   for (iX = 0; iX < iWidth; iX++)
22401   {
22402     pTempsrc2 = pTempsrc1 + 2;
22403 
22404     *pTempdst = *pTempsrc1;            /* copy original source pixel */
22405     pTempdst++;
22406     *pTempdst = *(pTempsrc1+1);
22407     pTempdst++;
22408 
22409     if (iX == 0)                       /* first interval ? */
22410     {
22411       if (iWidth == 1)                 /* single pixel ? */
22412         pTempsrc2 = MNG_NULL;
22413 
22414       iM = iML;
22415     }
22416     else
22417     if (iX == (iWidth - 2))            /* last interval ? */
22418       iM = iMR;
22419     else
22420       iM = iMX;
22421                                        /* fill interval ? */
22422     if ((iX < iWidth - 1) || (iWidth == 1))
22423     {
22424       if (pTempsrc2)                   /* do we have the second pixel ? */
22425       {
22426         iH = (iM+1) / 2;               /* calculate halfway point */
22427 
22428         for (iS = 1; iS < iH; iS++)    /* replicate first half */
22429         {
22430           *pTempdst     = *pTempsrc1;
22431           *(pTempdst+1) = *(pTempsrc1+1);
22432 
22433           pTempdst += 2;
22434         }
22435 
22436         for (iS = iH; iS < iM; iS++)   /* replicate second half */
22437         {
22438           *pTempdst     = *pTempsrc2;
22439           *(pTempdst+1) = *(pTempsrc2+1);
22440 
22441           pTempdst += 2;
22442         }
22443       }
22444       else
22445       {
22446         for (iS = 1; iS < iM; iS++)
22447         {
22448           *pTempdst = *pTempsrc1;      /* repeat first source pixel */
22449           pTempdst++;
22450           *pTempdst = *(pTempsrc1+1);
22451           pTempdst++;
22452         }
22453       }
22454     }
22455 
22456     pTempsrc1 += 2;
22457   }
22458 
22459 #ifdef MNG_SUPPORT_TRACE
22460   MNG_TRACE (pData, MNG_FN_MAGNIFY_GA16_X3, MNG_LC_END);
22461 #endif
22462 
22463   return MNG_NOERROR;
22464 }
22465 
22466 /* ************************************************************************** */
22467 
mng_magnify_ga16_x4(mng_datap pData,mng_uint16 iMX,mng_uint16 iML,mng_uint16 iMR,mng_uint32 iWidth,mng_uint8p pSrcline,mng_uint8p pDstline)22468 mng_retcode mng_magnify_ga16_x4 (mng_datap  pData,
22469                                  mng_uint16 iMX,
22470                                  mng_uint16 iML,
22471                                  mng_uint16 iMR,
22472                                  mng_uint32 iWidth,
22473                                  mng_uint8p pSrcline,
22474                                  mng_uint8p pDstline)
22475 {
22476   mng_uint32  iX;
22477   mng_int32   iS, iM, iH;
22478   mng_uint16p pTempsrc1;
22479   mng_uint16p pTempsrc2;
22480   mng_uint16p pTempdst;
22481 
22482 #ifdef MNG_SUPPORT_TRACE
22483   MNG_TRACE (pData, MNG_FN_MAGNIFY_GA16_X4, MNG_LC_START);
22484 #endif
22485 
22486   pTempsrc1 = (mng_uint16p)pSrcline;   /* initialize pixel-loop */
22487   pTempdst  = (mng_uint16p)pDstline;
22488 
22489   for (iX = 0; iX < iWidth; iX++)
22490   {
22491     pTempsrc2 = pTempsrc1 + 2;
22492 
22493     *pTempdst = *pTempsrc1;            /* copy original source pixel */
22494     pTempdst++;
22495     *pTempdst = *(pTempsrc1+1);
22496     pTempdst++;
22497 
22498     if (iX == 0)                       /* first interval ? */
22499     {
22500       if (iWidth == 1)                 /* single pixel ? */
22501         pTempsrc2 = MNG_NULL;
22502 
22503       iM = iML;
22504     }
22505     else
22506     if (iX == (iWidth - 2))            /* last interval ? */
22507       iM = iMR;
22508     else
22509       iM = iMX;
22510                                        /* fill interval ? */
22511     if ((iX < iWidth - 1) || (iWidth == 1))
22512     {
22513       if (pTempsrc2)                   /* do we have the second pixel ? */
22514       {
22515         iH = (iM+1) / 2;               /* calculate halfway point */
22516 
22517         for (iS = 1; iS < iH; iS++)    /* first half */
22518         {
22519           if (*pTempsrc1 == *pTempsrc2)
22520             *pTempdst = *pTempsrc1;    /* just repeat the first */
22521           else                         /* calculate the distance */
22522             mng_put_uint16 ((mng_uint8p)pTempdst,
22523                             (mng_uint16)(((2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc2)) -
22524                                                       (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1)) ) + iM) /
22525                                           (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1))         ) );
22526 
22527           pTempdst++;
22528 
22529           *pTempdst = *(pTempsrc1+1);  /* replicate alpha from left */
22530 
22531           pTempdst++;
22532         }
22533 
22534         for (iS = iH; iS < iM; iS++)   /* second half */
22535         {
22536           if (*pTempsrc1 == *pTempsrc2)
22537             *pTempdst = *pTempsrc1;    /* just repeat the first */
22538           else                         /* calculate the distance */
22539             mng_put_uint16 ((mng_uint8p)pTempdst,
22540                             (mng_uint16)(((2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc2)) -
22541                                                       (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1)) ) + iM) /
22542                                           (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1))         ) );
22543 
22544           pTempdst++;
22545 
22546           *pTempdst = *(pTempsrc2+1);  /* replicate alpha from right */
22547 
22548           pTempdst++;
22549         }
22550       }
22551       else
22552       {
22553         for (iS = 1; iS < iM; iS++)
22554         {
22555           *pTempdst = *pTempsrc1;      /* repeat first source pixel */
22556           pTempdst++;
22557           *pTempdst = *(pTempsrc1+1);
22558           pTempdst++;
22559         }
22560       }
22561     }
22562 
22563     pTempsrc1 += 2;
22564   }
22565 
22566 #ifdef MNG_SUPPORT_TRACE
22567   MNG_TRACE (pData, MNG_FN_MAGNIFY_GA16_X4, MNG_LC_END);
22568 #endif
22569 
22570   return MNG_NOERROR;
22571 }
22572 
22573 /* ************************************************************************** */
22574 
mng_magnify_ga16_x5(mng_datap pData,mng_uint16 iMX,mng_uint16 iML,mng_uint16 iMR,mng_uint32 iWidth,mng_uint8p pSrcline,mng_uint8p pDstline)22575 mng_retcode mng_magnify_ga16_x5 (mng_datap  pData,
22576                                  mng_uint16 iMX,
22577                                  mng_uint16 iML,
22578                                  mng_uint16 iMR,
22579                                  mng_uint32 iWidth,
22580                                  mng_uint8p pSrcline,
22581                                  mng_uint8p pDstline)
22582 {
22583   mng_uint32  iX;
22584   mng_int32   iS, iM, iH;
22585   mng_uint16p pTempsrc1;
22586   mng_uint16p pTempsrc2;
22587   mng_uint16p pTempdst;
22588 
22589 #ifdef MNG_SUPPORT_TRACE
22590   MNG_TRACE (pData, MNG_FN_MAGNIFY_GA16_X5, MNG_LC_START);
22591 #endif
22592 
22593   pTempsrc1 = (mng_uint16p)pSrcline;   /* initialize pixel-loop */
22594   pTempdst  = (mng_uint16p)pDstline;
22595 
22596   for (iX = 0; iX < iWidth; iX++)
22597   {
22598     pTempsrc2 = pTempsrc1 + 2;
22599 
22600     *pTempdst = *pTempsrc1;            /* copy original source pixel */
22601     pTempdst++;
22602     *pTempdst = *(pTempsrc1+1);
22603     pTempdst++;
22604 
22605     if (iX == 0)                       /* first interval ? */
22606     {
22607       if (iWidth == 1)                 /* single pixel ? */
22608         pTempsrc2 = MNG_NULL;
22609 
22610       iM = iML;
22611     }
22612     else
22613     if (iX == (iWidth - 2))            /* last interval ? */
22614       iM = iMR;
22615     else
22616       iM = iMX;
22617                                        /* fill interval ? */
22618     if ((iX < iWidth - 1) || (iWidth == 1))
22619     {
22620       if (pTempsrc2)                   /* do we have the second pixel ? */
22621       {
22622         iH = (iM+1) / 2;               /* calculate halfway point */
22623 
22624         for (iS = 1; iS < iH; iS++)    /* first half */
22625         {
22626           *pTempdst = *pTempsrc1;      /* replicate gray from left */
22627 
22628           pTempdst++;
22629 
22630           if (*(pTempsrc1+1) == *(pTempsrc2+1))
22631             *pTempdst = *(pTempsrc1+1);/* just repeat the first */
22632           else                         /* calculate the distance */
22633             mng_put_uint16 ((mng_uint8p)pTempdst,
22634                             (mng_uint16)(((2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc2+1))) -
22635                                                       (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc1+1))) ) + iM) /
22636                                           (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc1+1)))         ) );
22637 
22638           pTempdst++;
22639         }
22640 
22641         for (iS = iH; iS < iM; iS++)   /* second half */
22642         {
22643           *pTempdst = *pTempsrc2;      /* replicate gray from right */
22644 
22645           pTempdst++;
22646 
22647           if (*(pTempsrc1+1) == *(pTempsrc2+1))
22648             *pTempdst = *(pTempsrc1+1);/* just repeat the first */
22649           else                         /* calculate the distance */
22650             mng_put_uint16 ((mng_uint8p)pTempdst,
22651                             (mng_uint16)(((2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc2+1))) -
22652                                                       (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc1+1))) ) + iM) /
22653                                           (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc1+1)))         ) );
22654 
22655           pTempdst++;
22656         }
22657       }
22658       else
22659       {
22660         for (iS = 1; iS < iM; iS++)
22661         {
22662           *pTempdst = *pTempsrc1;      /* repeat first source pixel */
22663           pTempdst++;
22664           *pTempdst = *(pTempsrc1+1);
22665           pTempdst++;
22666         }
22667       }
22668     }
22669 
22670     pTempsrc1 += 2;
22671   }
22672 
22673 #ifdef MNG_SUPPORT_TRACE
22674   MNG_TRACE (pData, MNG_FN_MAGNIFY_GA16_X5, MNG_LC_END);
22675 #endif
22676 
22677   return MNG_NOERROR;
22678 }
22679 #endif /* MNG_NO_GRAY_SUPPORT */
22680 
22681 /* ************************************************************************** */
22682 
mng_magnify_rgba16_x1(mng_datap pData,mng_uint16 iMX,mng_uint16 iML,mng_uint16 iMR,mng_uint32 iWidth,mng_uint8p pSrcline,mng_uint8p pDstline)22683 mng_retcode mng_magnify_rgba16_x1 (mng_datap  pData,
22684                                    mng_uint16 iMX,
22685                                    mng_uint16 iML,
22686                                    mng_uint16 iMR,
22687                                    mng_uint32 iWidth,
22688                                    mng_uint8p pSrcline,
22689                                    mng_uint8p pDstline)
22690 {
22691   mng_uint32  iX, iS, iM;
22692   mng_uint16p pTempsrc1;
22693   mng_uint16p pTempdst;
22694 
22695 #ifdef MNG_SUPPORT_TRACE
22696   MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA16_X1, MNG_LC_START);
22697 #endif
22698 
22699   pTempsrc1 = (mng_uint16p)pSrcline;   /* initialize pixel-loop */
22700   pTempdst  = (mng_uint16p)pDstline;
22701 
22702   for (iX = 0; iX < iWidth; iX++)
22703   {
22704     *pTempdst = *pTempsrc1;            /* copy original source pixel */
22705     pTempdst++;
22706     *pTempdst = *(pTempsrc1+1);
22707     pTempdst++;
22708     *pTempdst = *(pTempsrc1+2);
22709     pTempdst++;
22710     *pTempdst = *(pTempsrc1+3);
22711     pTempdst++;
22712 
22713     if (iX == 0)                       /* first interval ? */
22714       iM = iML;
22715     else
22716     if (iX == (iWidth - 1))            /* last interval ? */
22717       iM = iMR;
22718     else
22719       iM = iMX;
22720 
22721     for (iS = 1; iS < iM; iS++)        /* fill interval */
22722     {
22723       *pTempdst = *pTempsrc1;          /* copy original source pixel */
22724       pTempdst++;
22725       *pTempdst = *(pTempsrc1+1);
22726       pTempdst++;
22727       *pTempdst = *(pTempsrc1+2);
22728       pTempdst++;
22729       *pTempdst = *(pTempsrc1+3);
22730       pTempdst++;
22731     }
22732 
22733     pTempsrc1 += 4;
22734   }
22735 
22736 #ifdef MNG_SUPPORT_TRACE
22737   MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA16_X1, MNG_LC_END);
22738 #endif
22739 
22740   return MNG_NOERROR;
22741 }
22742 
22743 /* ************************************************************************** */
22744 
mng_magnify_rgba16_x2(mng_datap pData,mng_uint16 iMX,mng_uint16 iML,mng_uint16 iMR,mng_uint32 iWidth,mng_uint8p pSrcline,mng_uint8p pDstline)22745 mng_retcode mng_magnify_rgba16_x2 (mng_datap  pData,
22746                                    mng_uint16 iMX,
22747                                    mng_uint16 iML,
22748                                    mng_uint16 iMR,
22749                                    mng_uint32 iWidth,
22750                                    mng_uint8p pSrcline,
22751                                    mng_uint8p pDstline)
22752 {
22753   mng_uint32  iX;
22754   mng_int32   iS, iM;
22755   mng_uint16p pTempsrc1;
22756   mng_uint16p pTempsrc2;
22757   mng_uint16p pTempdst;
22758 
22759 #ifdef MNG_SUPPORT_TRACE
22760   MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA16_X2, MNG_LC_START);
22761 #endif
22762 
22763   pTempsrc1 = (mng_uint16p)pSrcline;   /* initialize pixel-loop */
22764   pTempdst  = (mng_uint16p)pDstline;
22765 
22766   for (iX = 0; iX < iWidth; iX++)
22767   {
22768     pTempsrc2 = pTempsrc1 + 4;
22769 
22770     *pTempdst = *pTempsrc1;            /* copy original source pixel */
22771     pTempdst++;
22772     *pTempdst = *(pTempsrc1+1);
22773     pTempdst++;
22774     *pTempdst = *(pTempsrc1+2);
22775     pTempdst++;
22776     *pTempdst = *(pTempsrc1+3);
22777     pTempdst++;
22778 
22779     if (iX == 0)                       /* first interval ? */
22780     {
22781       if (iWidth == 1)                 /* single pixel ? */
22782         pTempsrc2 = MNG_NULL;
22783 
22784       iM = (mng_int32)iML;
22785     }
22786     else
22787     if (iX == (iWidth - 2))            /* last interval ? */
22788       iM = (mng_int32)iMR;
22789     else
22790       iM = (mng_int32)iMX;
22791                                        /* fill interval ? */
22792     if ((iX < iWidth - 1) || (iWidth == 1))
22793     {
22794       if (pTempsrc2)                   /* do we have the second pixel ? */
22795       {
22796         for (iS = 1; iS < iM; iS++)
22797         {
22798           if (*pTempsrc1 == *pTempsrc2)
22799             *pTempdst = *pTempsrc1;    /* just repeat the first */
22800           else                         /* calculate the distance */
22801             mng_put_uint16 ((mng_uint8p)pTempdst,
22802                             (mng_uint16)(((2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc2)) -
22803                                                       (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1)) ) + iM) /
22804                                           (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1))         ) );
22805 
22806           pTempdst++;
22807 
22808           if (*(pTempsrc1+1) == *(pTempsrc2+1))
22809             *pTempdst = *(pTempsrc1+1);
22810           else
22811             mng_put_uint16 ((mng_uint8p)pTempdst,
22812                             (mng_uint16)(((2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc2+1))) -
22813                                                       (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc1+1))) ) + iM) /
22814                                           (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc1+1)))         ) );
22815 
22816           pTempdst++;
22817 
22818           if (*(pTempsrc1+2) == *(pTempsrc2+2))
22819             *pTempdst = *(pTempsrc1+2);
22820           else
22821             mng_put_uint16 ((mng_uint8p)pTempdst,
22822                             (mng_uint16)(((2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc2+2))) -
22823                                                       (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc1+2))) ) + iM) /
22824                                           (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc1+2)))         ) );
22825 
22826           pTempdst++;
22827 
22828           if (*(pTempsrc1+3) == *(pTempsrc2+3))
22829             *pTempdst = *(pTempsrc1+3);
22830           else
22831             mng_put_uint16 ((mng_uint8p)pTempdst,
22832                             (mng_uint16)(((2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc2+3))) -
22833                                                       (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc1+3))) ) + iM) /
22834                                           (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc1+3)))         ) );
22835 
22836           pTempdst++;
22837         }
22838       }
22839       else
22840       {
22841         for (iS = 1; iS < iM; iS++)
22842         {
22843           *pTempdst = *pTempsrc1;      /* repeat first source pixel */
22844           pTempdst++;
22845           *pTempdst = *(pTempsrc1+1);
22846           pTempdst++;
22847           *pTempdst = *(pTempsrc1+2);
22848           pTempdst++;
22849           *pTempdst = *(pTempsrc1+3);
22850           pTempdst++;
22851         }
22852       }
22853     }
22854 
22855     pTempsrc1 += 4;
22856   }
22857 
22858 #ifdef MNG_SUPPORT_TRACE
22859   MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA16_X2, MNG_LC_END);
22860 #endif
22861 
22862   return MNG_NOERROR;
22863 }
22864 
22865 /* ************************************************************************** */
22866 
mng_magnify_rgba16_x3(mng_datap pData,mng_uint16 iMX,mng_uint16 iML,mng_uint16 iMR,mng_uint32 iWidth,mng_uint8p pSrcline,mng_uint8p pDstline)22867 mng_retcode mng_magnify_rgba16_x3 (mng_datap  pData,
22868                                    mng_uint16 iMX,
22869                                    mng_uint16 iML,
22870                                    mng_uint16 iMR,
22871                                    mng_uint32 iWidth,
22872                                    mng_uint8p pSrcline,
22873                                    mng_uint8p pDstline)
22874 {
22875   mng_uint32  iX;
22876   mng_int32   iS, iM, iH;
22877   mng_uint16p pTempsrc1;
22878   mng_uint16p pTempsrc2;
22879   mng_uint16p pTempdst;
22880 
22881 #ifdef MNG_SUPPORT_TRACE
22882   MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA16_X3, MNG_LC_START);
22883 #endif
22884 
22885   pTempsrc1 = (mng_uint16p)pSrcline;   /* initialize pixel-loop */
22886   pTempdst  = (mng_uint16p)pDstline;
22887 
22888   for (iX = 0; iX < iWidth; iX++)
22889   {
22890     pTempsrc2 = pTempsrc1 + 4;
22891 
22892     *pTempdst = *pTempsrc1;            /* copy original source pixel */
22893     pTempdst++;
22894     *pTempdst = *(pTempsrc1+1);
22895     pTempdst++;
22896     *pTempdst = *(pTempsrc1+2);
22897     pTempdst++;
22898     *pTempdst = *(pTempsrc1+3);
22899     pTempdst++;
22900 
22901     if (iX == 0)                       /* first interval ? */
22902     {
22903       if (iWidth == 1)                 /* single pixel ? */
22904         pTempsrc2 = MNG_NULL;
22905 
22906       iM = (mng_int32)iML;
22907     }
22908     else
22909     if (iX == (iWidth - 2))            /* last interval ? */
22910       iM = (mng_int32)iMR;
22911     else
22912       iM = (mng_int32)iMX;
22913                                        /* fill interval ? */
22914     if ((iX < iWidth - 1) || (iWidth == 1))
22915     {
22916       if (pTempsrc2)                   /* do we have the second pixel ? */
22917       {
22918         iH = (iM+1) / 2;               /* calculate halfway point */
22919 
22920         for (iS = 1; iS < iH; iS++)    /* replicate first half */
22921         {
22922           *pTempdst     = *pTempsrc1;
22923           *(pTempdst+1) = *(pTempsrc1+1);
22924           *(pTempdst+2) = *(pTempsrc1+2);
22925           *(pTempdst+3) = *(pTempsrc1+3);
22926 
22927           pTempdst += 4;
22928         }
22929 
22930         for (iS = iH; iS < iM; iS++)   /* replicate second half */
22931         {
22932           *pTempdst     = *pTempsrc2;
22933           *(pTempdst+1) = *(pTempsrc2+1);
22934           *(pTempdst+2) = *(pTempsrc2+2);
22935           *(pTempdst+3) = *(pTempsrc2+3);
22936 
22937           pTempdst += 4;
22938         }
22939       }
22940       else
22941       {
22942         for (iS = 1; iS < iM; iS++)
22943         {
22944           *pTempdst = *pTempsrc1;      /* repeat first source pixel */
22945           pTempdst++;
22946           *pTempdst = *(pTempsrc1+1);
22947           pTempdst++;
22948           *pTempdst = *(pTempsrc1+2);
22949           pTempdst++;
22950           *pTempdst = *(pTempsrc1+3);
22951           pTempdst++;
22952         }
22953       }
22954     }
22955 
22956     pTempsrc1 += 4;
22957   }
22958 
22959 #ifdef MNG_SUPPORT_TRACE
22960   MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA16_X3, MNG_LC_END);
22961 #endif
22962 
22963   return MNG_NOERROR;
22964 }
22965 
22966 /* ************************************************************************** */
22967 
mng_magnify_rgba16_x4(mng_datap pData,mng_uint16 iMX,mng_uint16 iML,mng_uint16 iMR,mng_uint32 iWidth,mng_uint8p pSrcline,mng_uint8p pDstline)22968 mng_retcode mng_magnify_rgba16_x4 (mng_datap  pData,
22969                                    mng_uint16 iMX,
22970                                    mng_uint16 iML,
22971                                    mng_uint16 iMR,
22972                                    mng_uint32 iWidth,
22973                                    mng_uint8p pSrcline,
22974                                    mng_uint8p pDstline)
22975 {
22976   mng_uint32  iX;
22977   mng_int32   iS, iM, iH;
22978   mng_uint16p pTempsrc1;
22979   mng_uint16p pTempsrc2;
22980   mng_uint16p pTempdst;
22981 
22982 #ifdef MNG_SUPPORT_TRACE
22983   MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA16_X4, MNG_LC_START);
22984 #endif
22985 
22986   pTempsrc1 = (mng_uint16p)pSrcline;   /* initialize pixel-loop */
22987   pTempdst  = (mng_uint16p)pDstline;
22988 
22989   for (iX = 0; iX < iWidth; iX++)
22990   {
22991     pTempsrc2 = pTempsrc1 + 4;
22992 
22993     *pTempdst = *pTempsrc1;            /* copy original source pixel */
22994     pTempdst++;
22995     *pTempdst = *(pTempsrc1+1);
22996     pTempdst++;
22997     *pTempdst = *(pTempsrc1+2);
22998     pTempdst++;
22999     *pTempdst = *(pTempsrc1+3);
23000     pTempdst++;
23001 
23002     if (iX == 0)                       /* first interval ? */
23003     {
23004       if (iWidth == 1)                 /* single pixel ? */
23005         pTempsrc2 = MNG_NULL;
23006 
23007       iM = (mng_int32)iML;
23008     }
23009     else
23010     if (iX == (iWidth - 2))            /* last interval ? */
23011       iM = (mng_int32)iMR;
23012     else
23013       iM = (mng_int32)iMX;
23014                                        /* fill interval ? */
23015     if ((iX < iWidth - 1) || (iWidth == 1))
23016     {
23017       if (pTempsrc2)                   /* do we have the second pixel ? */
23018       {
23019         iH = (iM+1) / 2;               /* calculate halfway point */
23020 
23021         for (iS = 1; iS < iH; iS++)    /* first half */
23022         {
23023           if (*pTempsrc1 == *pTempsrc2)
23024             *pTempdst = *pTempsrc1;    /* just repeat the first */
23025           else                         /* calculate the distance */
23026             mng_put_uint16 ((mng_uint8p)pTempdst,
23027                             (mng_uint16)(((2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc2)) -
23028                                                       (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1)) ) + iM) /
23029                                           (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1))         ) );
23030 
23031           pTempdst++;
23032 
23033           if (*(pTempsrc1+1) == *(pTempsrc2+1))
23034             *pTempdst = *(pTempsrc1+1);
23035           else
23036             mng_put_uint16 ((mng_uint8p)pTempdst,
23037                             (mng_uint16)(((2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc2+1))) -
23038                                                       (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc1+1))) ) + iM) /
23039                                           (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc1+1)))         ) );
23040 
23041           pTempdst++;
23042 
23043           if (*(pTempsrc1+2) == *(pTempsrc2+2))
23044             *pTempdst = *(pTempsrc1+2);
23045           else
23046             mng_put_uint16 ((mng_uint8p)pTempdst,
23047                             (mng_uint16)(((2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc2+2))) -
23048                                                       (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc1+2))) ) + iM) /
23049                                           (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc1+2)))         ) );
23050 
23051           pTempdst++;
23052                                        /* replicate alpha from left */
23053           *pTempdst     = *(pTempsrc1+3);
23054 
23055           pTempdst++;
23056         }
23057 
23058         for (iS = iH; iS < iM; iS++)   /* second half */
23059         {
23060           if (*pTempsrc1 == *pTempsrc2)
23061             *pTempdst = *pTempsrc1;    /* just repeat the first */
23062           else                         /* calculate the distance */
23063             mng_put_uint16 ((mng_uint8p)pTempdst,
23064                             (mng_uint16)(((2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc2)) -
23065                                                       (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1)) ) + iM) /
23066                                           (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1))         ) );
23067 
23068           pTempdst++;
23069 
23070           if (*(pTempsrc1+1) == *(pTempsrc2+1))
23071             *pTempdst = *(pTempsrc1+1);
23072           else
23073             mng_put_uint16 ((mng_uint8p)pTempdst,
23074                             (mng_uint16)(((2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc2+1))) -
23075                                                       (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc1+1))) ) + iM) /
23076                                           (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc1+1)))         ) );
23077 
23078           pTempdst++;
23079 
23080           if (*(pTempsrc1+2) == *(pTempsrc2+2))
23081             *pTempdst = *(pTempsrc1+2);
23082           else
23083             mng_put_uint16 ((mng_uint8p)pTempdst,
23084                             (mng_uint16)(((2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc2+2))) -
23085                                                       (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc1+2))) ) + iM) /
23086                                           (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc1+2)))         ) );
23087 
23088           pTempdst++;
23089                                        /* replicate alpha from right */
23090           *pTempdst     = *(pTempsrc2+3);
23091 
23092           pTempdst++;
23093         }
23094       }
23095       else
23096       {
23097         for (iS = 1; iS < iM; iS++)
23098         {
23099           *pTempdst = *pTempsrc1;      /* repeat first source pixel */
23100           pTempdst++;
23101           *pTempdst = *(pTempsrc1+1);
23102           pTempdst++;
23103           *pTempdst = *(pTempsrc1+2);
23104           pTempdst++;
23105           *pTempdst = *(pTempsrc1+3);
23106           pTempdst++;
23107         }
23108       }
23109     }
23110 
23111     pTempsrc1 += 4;
23112   }
23113 
23114 #ifdef MNG_SUPPORT_TRACE
23115   MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA16_X4, MNG_LC_END);
23116 #endif
23117 
23118   return MNG_NOERROR;
23119 }
23120 
23121 /* ************************************************************************** */
23122 
mng_magnify_rgba16_x5(mng_datap pData,mng_uint16 iMX,mng_uint16 iML,mng_uint16 iMR,mng_uint32 iWidth,mng_uint8p pSrcline,mng_uint8p pDstline)23123 mng_retcode mng_magnify_rgba16_x5 (mng_datap  pData,
23124                                    mng_uint16 iMX,
23125                                    mng_uint16 iML,
23126                                    mng_uint16 iMR,
23127                                    mng_uint32 iWidth,
23128                                    mng_uint8p pSrcline,
23129                                    mng_uint8p pDstline)
23130 {
23131   mng_uint32  iX;
23132   mng_int32   iS, iM, iH;
23133   mng_uint16p pTempsrc1;
23134   mng_uint16p pTempsrc2;
23135   mng_uint16p pTempdst;
23136 
23137 #ifdef MNG_SUPPORT_TRACE
23138   MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA16_X5, MNG_LC_START);
23139 #endif
23140 
23141   pTempsrc1 = (mng_uint16p)pSrcline;   /* initialize pixel-loop */
23142   pTempdst  = (mng_uint16p)pDstline;
23143 
23144   for (iX = 0; iX < iWidth; iX++)
23145   {
23146     pTempsrc2 = pTempsrc1 + 4;
23147 
23148     *pTempdst = *pTempsrc1;            /* copy original source pixel */
23149     pTempdst++;
23150     *pTempdst = *(pTempsrc1+1);
23151     pTempdst++;
23152     *pTempdst = *(pTempsrc1+2);
23153     pTempdst++;
23154     *pTempdst = *(pTempsrc1+3);
23155     pTempdst++;
23156 
23157     if (iX == 0)                       /* first interval ? */
23158     {
23159       if (iWidth == 1)                 /* single pixel ? */
23160         pTempsrc2 = MNG_NULL;
23161 
23162       iM = (mng_int32)iML;
23163     }
23164     else
23165     if (iX == (iWidth - 2))            /* last interval ? */
23166       iM = (mng_int32)iMR;
23167     else
23168       iM = (mng_int32)iMX;
23169                                        /* fill interval ? */
23170     if ((iX < iWidth - 1) || (iWidth == 1))
23171     {
23172       if (pTempsrc2)                   /* do we have the second pixel ? */
23173       {
23174         iH = (iM+1) / 2;               /* calculate halfway point */
23175 
23176         for (iS = 1; iS < iH; iS++)    /* first half */
23177         {
23178           *pTempdst     = *pTempsrc1;  /* replicate color from left */
23179           *(pTempdst+1) = *(pTempsrc1+1);
23180           *(pTempdst+2) = *(pTempsrc1+2);
23181 
23182           if (*(pTempsrc1+3) == *(pTempsrc2+3))
23183             *(pTempdst+3) = *(pTempsrc1+3);
23184           else
23185             mng_put_uint16 ((mng_uint8p)(pTempdst+3),
23186                             (mng_uint16)(((2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc2+3))) -
23187                                                       (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc1+3))) ) + iM) /
23188                                           (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc1+3)))         ) );
23189 
23190           pTempdst += 4;
23191         }
23192 
23193         for (iS = iH; iS < iM; iS++)   /* second half */
23194         {
23195           *pTempdst     = *pTempsrc2;  /* replicate color from right */
23196           *(pTempdst+1) = *(pTempsrc2+1);
23197           *(pTempdst+2) = *(pTempsrc2+2);
23198 
23199           if (*(pTempsrc1+3) == *(pTempsrc2+3))
23200             *(pTempdst+3) = *(pTempsrc1+3);
23201           else
23202             mng_put_uint16 ((mng_uint8p)(pTempdst+3),
23203                             (mng_uint16)(((2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc2+3))) -
23204                                                       (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc1+3))) ) + iM) /
23205                                           (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)(pTempsrc1+3)))         ) );
23206 
23207           pTempdst += 4;
23208         }
23209       }
23210       else
23211       {
23212         for (iS = 1; iS < iM; iS++)
23213         {
23214           *pTempdst = *pTempsrc1;      /* repeat first source pixel */
23215           pTempdst++;
23216           *pTempdst = *(pTempsrc1+1);
23217           pTempdst++;
23218           *pTempdst = *(pTempsrc1+2);
23219           pTempdst++;
23220           *pTempdst = *(pTempsrc1+3);
23221           pTempdst++;
23222         }
23223       }
23224     }
23225 
23226     pTempsrc1 += 4;
23227   }
23228 
23229 #ifdef MNG_SUPPORT_TRACE
23230   MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA16_X4, MNG_LC_END);
23231 #endif
23232 
23233   return MNG_NOERROR;
23234 }
23235 
23236 /* ************************************************************************** */
23237 
23238 #ifndef MNG_NO_GRAY_SUPPORT
mng_magnify_g16_y1(mng_datap pData,mng_int32 iS,mng_int32 iM,mng_uint32 iWidth,mng_uint8p pSrcline1,mng_uint8p pSrcline2,mng_uint8p pDstline)23239 mng_retcode mng_magnify_g16_y1 (mng_datap  pData,
23240                                 mng_int32  iS,
23241                                 mng_int32  iM,
23242                                 mng_uint32 iWidth,
23243                                 mng_uint8p pSrcline1,
23244                                 mng_uint8p pSrcline2,
23245                                 mng_uint8p pDstline)
23246 {
23247 #ifdef MNG_SUPPORT_TRACE
23248   MNG_TRACE (pData, MNG_FN_MAGNIFY_G16_Y1, MNG_LC_START);
23249 #endif
23250 
23251   MNG_COPY (pDstline, pSrcline1, (iWidth << 1));
23252 
23253 #ifdef MNG_SUPPORT_TRACE
23254   MNG_TRACE (pData, MNG_FN_MAGNIFY_G16_Y1, MNG_LC_END);
23255 #endif
23256 
23257   return MNG_NOERROR;
23258 }
23259 
23260 /* ************************************************************************** */
23261 
mng_magnify_g16_y2(mng_datap pData,mng_int32 iS,mng_int32 iM,mng_uint32 iWidth,mng_uint8p pSrcline1,mng_uint8p pSrcline2,mng_uint8p pDstline)23262 mng_retcode mng_magnify_g16_y2 (mng_datap  pData,
23263                                 mng_int32  iS,
23264                                 mng_int32  iM,
23265                                 mng_uint32 iWidth,
23266                                 mng_uint8p pSrcline1,
23267                                 mng_uint8p pSrcline2,
23268                                 mng_uint8p pDstline)
23269 {
23270   mng_uint32  iX;
23271   mng_uint16p pTempsrc1;
23272   mng_uint16p pTempsrc2;
23273   mng_uint16p pTempdst;
23274 
23275 #ifdef MNG_SUPPORT_TRACE
23276   MNG_TRACE (pData, MNG_FN_MAGNIFY_G16_Y2, MNG_LC_START);
23277 #endif
23278 
23279   pTempsrc1 = (mng_uint16p)pSrcline1;  /* initialize pixel-loop */
23280   pTempsrc2 = (mng_uint16p)pSrcline2;
23281   pTempdst  = (mng_uint16p)pDstline;
23282 
23283   if (pTempsrc2)                       /* do we have a second line ? */
23284   {
23285     for (iX = 0; iX < iWidth; iX++)
23286     {                                  /* calculate the distances */
23287       if (*pTempsrc1 == *pTempsrc2)
23288         *pTempdst = *pTempsrc1;
23289       else
23290         mng_put_uint16 ((mng_uint8p)pTempdst,
23291                         (mng_uint16)( ( (2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc2)) -
23292                                                     (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1)) ) + iM) /
23293                                         (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1))         ) );
23294 
23295       pTempdst++;
23296       pTempsrc1++;
23297       pTempsrc2++;
23298     }
23299   }
23300   else
23301   {                                    /* just repeat the entire line */
23302     MNG_COPY (pTempdst, pTempsrc1, (iWidth << 1));
23303   }
23304 
23305 #ifdef MNG_SUPPORT_TRACE
23306   MNG_TRACE (pData, MNG_FN_MAGNIFY_G16_Y2, MNG_LC_END);
23307 #endif
23308 
23309   return MNG_NOERROR;
23310 }
23311 
23312 /* ************************************************************************** */
23313 
mng_magnify_g16_y3(mng_datap pData,mng_int32 iS,mng_int32 iM,mng_uint32 iWidth,mng_uint8p pSrcline1,mng_uint8p pSrcline2,mng_uint8p pDstline)23314 mng_retcode mng_magnify_g16_y3 (mng_datap  pData,
23315                                 mng_int32  iS,
23316                                 mng_int32  iM,
23317                                 mng_uint32 iWidth,
23318                                 mng_uint8p pSrcline1,
23319                                 mng_uint8p pSrcline2,
23320                                 mng_uint8p pDstline)
23321 {
23322 #ifdef MNG_SUPPORT_TRACE
23323   MNG_TRACE (pData, MNG_FN_MAGNIFY_G16_Y3, MNG_LC_START);
23324 #endif
23325 
23326   if (pSrcline2)                       /* do we have a second line ? */
23327   {
23328     if (iS < (iM+1) / 2)               /* top half ? */
23329       MNG_COPY (pDstline, pSrcline1, (iWidth << 1))
23330     else
23331       MNG_COPY (pDstline, pSrcline2, (iWidth << 1));
23332   }
23333   else
23334   {                                    /* just repeat the entire line */
23335     MNG_COPY (pDstline, pSrcline1, (iWidth << 1));
23336   }
23337 
23338 #ifdef MNG_SUPPORT_TRACE
23339   MNG_TRACE (pData, MNG_FN_MAGNIFY_G16_Y3, MNG_LC_END);
23340 #endif
23341 
23342   return MNG_NOERROR;
23343 }
23344 #endif /* MNG_NO_GRAY_SUPPORT */
23345 
23346 /* ************************************************************************** */
23347 
mng_magnify_rgb16_y1(mng_datap pData,mng_int32 iS,mng_int32 iM,mng_uint32 iWidth,mng_uint8p pSrcline1,mng_uint8p pSrcline2,mng_uint8p pDstline)23348 mng_retcode mng_magnify_rgb16_y1 (mng_datap  pData,
23349                                   mng_int32  iS,
23350                                   mng_int32  iM,
23351                                   mng_uint32 iWidth,
23352                                   mng_uint8p pSrcline1,
23353                                   mng_uint8p pSrcline2,
23354                                   mng_uint8p pDstline)
23355 {
23356 #ifdef MNG_SUPPORT_TRACE
23357   MNG_TRACE (pData, MNG_FN_MAGNIFY_RGB16_Y1, MNG_LC_START);
23358 #endif
23359 
23360   MNG_COPY (pDstline, pSrcline1, iWidth * 6);
23361 
23362 #ifdef MNG_SUPPORT_TRACE
23363   MNG_TRACE (pData, MNG_FN_MAGNIFY_RGB16_Y1, MNG_LC_END);
23364 #endif
23365 
23366   return MNG_NOERROR;
23367 }
23368 
23369 /* ************************************************************************** */
23370 
mng_magnify_rgb16_y2(mng_datap pData,mng_int32 iS,mng_int32 iM,mng_uint32 iWidth,mng_uint8p pSrcline1,mng_uint8p pSrcline2,mng_uint8p pDstline)23371 mng_retcode mng_magnify_rgb16_y2 (mng_datap  pData,
23372                                   mng_int32  iS,
23373                                   mng_int32  iM,
23374                                   mng_uint32 iWidth,
23375                                   mng_uint8p pSrcline1,
23376                                   mng_uint8p pSrcline2,
23377                                   mng_uint8p pDstline)
23378 {
23379   mng_uint32  iX;
23380   mng_uint16p pTempsrc1;
23381   mng_uint16p pTempsrc2;
23382   mng_uint16p pTempdst;
23383 
23384 #ifdef MNG_SUPPORT_TRACE
23385   MNG_TRACE (pData, MNG_FN_MAGNIFY_RGB16_Y2, MNG_LC_START);
23386 #endif
23387 
23388   pTempsrc1 = (mng_uint16p)pSrcline1;  /* initialize pixel-loop */
23389   pTempsrc2 = (mng_uint16p)pSrcline2;
23390   pTempdst  = (mng_uint16p)pDstline;
23391 
23392   if (pTempsrc2)                       /* do we have a second line ? */
23393   {
23394     for (iX = 0; iX < iWidth; iX++)
23395     {                                  /* calculate the distances */
23396       if (*pTempsrc1 == *pTempsrc2)
23397         *pTempdst = *pTempsrc1;
23398       else
23399         mng_put_uint16 ((mng_uint8p)pTempdst,
23400                         (mng_uint16)( ( (2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc2)) -
23401                                                     (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1)) ) + iM) /
23402                                         (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1))         ) );
23403 
23404       pTempdst++;
23405       pTempsrc1++;
23406       pTempsrc2++;
23407 
23408       if (*pTempsrc1 == *pTempsrc2)
23409         *pTempdst = *pTempsrc1;
23410       else
23411         mng_put_uint16 ((mng_uint8p)pTempdst,
23412                         (mng_uint16)( ( (2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc2)) -
23413                                                     (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1)) ) + iM) /
23414                                         (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1))         ) );
23415 
23416       pTempdst++;
23417       pTempsrc1++;
23418       pTempsrc2++;
23419 
23420       if (*pTempsrc1 == *pTempsrc2)
23421         *pTempdst = *pTempsrc1;
23422       else
23423         mng_put_uint16 ((mng_uint8p)pTempdst,
23424                         (mng_uint16)( ( (2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc2)) -
23425                                                     (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1)) ) + iM) /
23426                                         (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1))         ) );
23427 
23428       pTempdst++;
23429       pTempsrc1++;
23430       pTempsrc2++;
23431     }
23432   }
23433   else
23434   {                                    /* just repeat the entire line */
23435     MNG_COPY (pTempdst, pTempsrc1, iWidth * 6);
23436   }
23437 
23438 #ifdef MNG_SUPPORT_TRACE
23439   MNG_TRACE (pData, MNG_FN_MAGNIFY_RGB16_Y2, MNG_LC_END);
23440 #endif
23441 
23442   return MNG_NOERROR;
23443 }
23444 
23445 /* ************************************************************************** */
23446 
mng_magnify_rgb16_y3(mng_datap pData,mng_int32 iS,mng_int32 iM,mng_uint32 iWidth,mng_uint8p pSrcline1,mng_uint8p pSrcline2,mng_uint8p pDstline)23447 mng_retcode mng_magnify_rgb16_y3 (mng_datap  pData,
23448                                   mng_int32  iS,
23449                                   mng_int32  iM,
23450                                   mng_uint32 iWidth,
23451                                   mng_uint8p pSrcline1,
23452                                   mng_uint8p pSrcline2,
23453                                   mng_uint8p pDstline)
23454 {
23455 #ifdef MNG_SUPPORT_TRACE
23456   MNG_TRACE (pData, MNG_FN_MAGNIFY_RGB16_Y3, MNG_LC_START);
23457 #endif
23458 
23459   if (pSrcline2)                       /* do we have a second line ? */
23460   {
23461     if (iS < (iM+1) / 2)               /* top half ? */
23462       MNG_COPY (pDstline, pSrcline1, iWidth * 6)
23463     else
23464       MNG_COPY (pDstline, pSrcline2, iWidth * 6);
23465   }
23466   else
23467   {                                    /* just repeat the entire line */
23468     MNG_COPY (pDstline, pSrcline1, iWidth * 6);
23469   }
23470 
23471 #ifdef MNG_SUPPORT_TRACE
23472   MNG_TRACE (pData, MNG_FN_MAGNIFY_RGB16_Y3, MNG_LC_END);
23473 #endif
23474 
23475   return MNG_NOERROR;
23476 }
23477 
23478 /* ************************************************************************** */
23479 
23480 #ifndef MNG_NO_GRAY_SUPPORT
mng_magnify_ga16_y1(mng_datap pData,mng_int32 iS,mng_int32 iM,mng_uint32 iWidth,mng_uint8p pSrcline1,mng_uint8p pSrcline2,mng_uint8p pDstline)23481 mng_retcode mng_magnify_ga16_y1 (mng_datap  pData,
23482                                  mng_int32  iS,
23483                                  mng_int32  iM,
23484                                  mng_uint32 iWidth,
23485                                  mng_uint8p pSrcline1,
23486                                  mng_uint8p pSrcline2,
23487                                  mng_uint8p pDstline)
23488 {
23489 #ifdef MNG_SUPPORT_TRACE
23490   MNG_TRACE (pData, MNG_FN_MAGNIFY_GA16_Y1, MNG_LC_START);
23491 #endif
23492 
23493   MNG_COPY (pDstline, pSrcline1, (iWidth << 2));
23494 
23495 #ifdef MNG_SUPPORT_TRACE
23496   MNG_TRACE (pData, MNG_FN_MAGNIFY_GA16_Y1, MNG_LC_END);
23497 #endif
23498 
23499   return MNG_NOERROR;
23500 }
23501 
23502 /* ************************************************************************** */
23503 
mng_magnify_ga16_y2(mng_datap pData,mng_int32 iS,mng_int32 iM,mng_uint32 iWidth,mng_uint8p pSrcline1,mng_uint8p pSrcline2,mng_uint8p pDstline)23504 mng_retcode mng_magnify_ga16_y2 (mng_datap  pData,
23505                                  mng_int32  iS,
23506                                  mng_int32  iM,
23507                                  mng_uint32 iWidth,
23508                                  mng_uint8p pSrcline1,
23509                                  mng_uint8p pSrcline2,
23510                                  mng_uint8p pDstline)
23511 {
23512   mng_uint32  iX;
23513   mng_uint16p pTempsrc1;
23514   mng_uint16p pTempsrc2;
23515   mng_uint16p pTempdst;
23516 
23517 #ifdef MNG_SUPPORT_TRACE
23518   MNG_TRACE (pData, MNG_FN_MAGNIFY_GA16_Y2, MNG_LC_START);
23519 #endif
23520 
23521   pTempsrc1 = (mng_uint16p)pSrcline1;  /* initialize pixel-loop */
23522   pTempsrc2 = (mng_uint16p)pSrcline2;
23523   pTempdst  = (mng_uint16p)pDstline;
23524 
23525   if (pTempsrc2)                       /* do we have a second line ? */
23526   {
23527     for (iX = 0; iX < iWidth; iX++)
23528     {                                  /* calculate the distances */
23529       if (*pTempsrc1 == *pTempsrc2)
23530         *pTempdst = *pTempsrc1;
23531       else
23532         mng_put_uint16 ((mng_uint8p)pTempdst,
23533                         (mng_uint16)( ( (2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc2)) -
23534                                                     (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1)) ) + iM) /
23535                                         (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1))         ) );
23536 
23537       pTempdst++;
23538       pTempsrc1++;
23539       pTempsrc2++;
23540 
23541       if (*pTempsrc1 == *pTempsrc2)
23542         *pTempdst = *pTempsrc1;
23543       else
23544         mng_put_uint16 ((mng_uint8p)pTempdst,
23545                         (mng_uint16)( ( (2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc2)) -
23546                                                     (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1)) ) + iM) /
23547                                         (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1))         ) );
23548 
23549       pTempdst++;
23550       pTempsrc1++;
23551       pTempsrc2++;
23552     }
23553   }
23554   else
23555   {                                    /* just repeat the entire line */
23556     MNG_COPY (pTempdst, pTempsrc1, (iWidth << 2));
23557   }
23558 
23559 #ifdef MNG_SUPPORT_TRACE
23560   MNG_TRACE (pData, MNG_FN_MAGNIFY_GA16_Y2, MNG_LC_END);
23561 #endif
23562 
23563   return MNG_NOERROR;
23564 }
23565 
23566 /* ************************************************************************** */
23567 
mng_magnify_ga16_y3(mng_datap pData,mng_int32 iS,mng_int32 iM,mng_uint32 iWidth,mng_uint8p pSrcline1,mng_uint8p pSrcline2,mng_uint8p pDstline)23568 mng_retcode mng_magnify_ga16_y3 (mng_datap  pData,
23569                                 mng_int32  iS,
23570                                 mng_int32  iM,
23571                                 mng_uint32 iWidth,
23572                                 mng_uint8p pSrcline1,
23573                                 mng_uint8p pSrcline2,
23574                                 mng_uint8p pDstline)
23575 {
23576 #ifdef MNG_SUPPORT_TRACE
23577   MNG_TRACE (pData, MNG_FN_MAGNIFY_GA16_Y3, MNG_LC_START);
23578 #endif
23579 
23580   if (pSrcline2)                       /* do we have a second line ? */
23581   {
23582     if (iS < (iM+1) / 2)               /* top half ? */
23583       MNG_COPY (pDstline, pSrcline1, (iWidth << 2))
23584     else
23585       MNG_COPY (pDstline, pSrcline2, (iWidth << 2));
23586   }
23587   else
23588   {                                    /* just repeat the entire line */
23589     MNG_COPY (pDstline, pSrcline1, (iWidth << 2));
23590   }
23591 
23592 #ifdef MNG_SUPPORT_TRACE
23593   MNG_TRACE (pData, MNG_FN_MAGNIFY_GA16_Y2, MNG_LC_END);
23594 #endif
23595 
23596   return MNG_NOERROR;
23597 }
23598 
23599 /* ************************************************************************** */
23600 
mng_magnify_ga16_y4(mng_datap pData,mng_int32 iS,mng_int32 iM,mng_uint32 iWidth,mng_uint8p pSrcline1,mng_uint8p pSrcline2,mng_uint8p pDstline)23601 mng_retcode mng_magnify_ga16_y4 (mng_datap  pData,
23602                                  mng_int32  iS,
23603                                  mng_int32  iM,
23604                                  mng_uint32 iWidth,
23605                                  mng_uint8p pSrcline1,
23606                                  mng_uint8p pSrcline2,
23607                                  mng_uint8p pDstline)
23608 {
23609   mng_uint32  iX;
23610   mng_uint16p pTempsrc1;
23611   mng_uint16p pTempsrc2;
23612   mng_uint16p pTempdst;
23613 
23614 #ifdef MNG_SUPPORT_TRACE
23615   MNG_TRACE (pData, MNG_FN_MAGNIFY_GA16_Y4, MNG_LC_START);
23616 #endif
23617 
23618   pTempsrc1 = (mng_uint16p)pSrcline1;  /* initialize pixel-loop */
23619   pTempsrc2 = (mng_uint16p)pSrcline2;
23620   pTempdst  = (mng_uint16p)pDstline;
23621 
23622   if (pTempsrc2)                       /* do we have a second line ? */
23623   {
23624     if (iS < (iM+1) / 2)               /* top half ? */
23625     {
23626       for (iX = 0; iX < iWidth; iX++)
23627       {                                /* calculate the distances */
23628         if (*pTempsrc1 == *pTempsrc2)
23629           *pTempdst = *pTempsrc1;
23630         else
23631           mng_put_uint16 ((mng_uint8p)pTempdst,
23632                           (mng_uint16)( ( (2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc2)) -
23633                                                       (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1)) ) + iM) /
23634                                           (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1))         ) );
23635 
23636         pTempdst++;
23637         pTempsrc1++;
23638         pTempsrc2 += 2;
23639 
23640         *pTempdst++ = *pTempsrc1++;    /* replicate alpha from top */
23641       }
23642     }
23643     else
23644     {
23645        for (iX = 0; iX < iWidth; iX++)
23646       {                                /* calculate the distances */
23647         if (*pTempsrc1 == *pTempsrc2)
23648           *pTempdst = *pTempsrc1;
23649         else
23650           mng_put_uint16 ((mng_uint8p)pTempdst,
23651                           (mng_uint16)( ( (2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc2)) -
23652                                                       (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1)) ) + iM) /
23653                                           (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1))         ) );
23654 
23655         pTempdst++;
23656         pTempsrc1 += 2;
23657         pTempsrc2++;
23658 
23659         *pTempdst++ = *pTempsrc2++;    /* replicate alpha from bottom */
23660       }
23661     }
23662   }
23663   else
23664   {                                    /* just repeat the entire line */
23665     MNG_COPY (pTempdst, pTempsrc1, (iWidth << 2));
23666   }
23667 
23668 #ifdef MNG_SUPPORT_TRACE
23669   MNG_TRACE (pData, MNG_FN_MAGNIFY_GA16_Y4, MNG_LC_END);
23670 #endif
23671 
23672   return MNG_NOERROR;
23673 }
23674 
23675 /* ************************************************************************** */
23676 
mng_magnify_ga16_y5(mng_datap pData,mng_int32 iS,mng_int32 iM,mng_uint32 iWidth,mng_uint8p pSrcline1,mng_uint8p pSrcline2,mng_uint8p pDstline)23677 mng_retcode mng_magnify_ga16_y5 (mng_datap  pData,
23678                                  mng_int32  iS,
23679                                  mng_int32  iM,
23680                                  mng_uint32 iWidth,
23681                                  mng_uint8p pSrcline1,
23682                                  mng_uint8p pSrcline2,
23683                                  mng_uint8p pDstline)
23684 {
23685   mng_uint32  iX;
23686   mng_uint16p pTempsrc1;
23687   mng_uint16p pTempsrc2;
23688   mng_uint16p pTempdst;
23689 
23690 #ifdef MNG_SUPPORT_TRACE
23691   MNG_TRACE (pData, MNG_FN_MAGNIFY_GA16_Y5, MNG_LC_START);
23692 #endif
23693 
23694   pTempsrc1 = (mng_uint16p)pSrcline1;  /* initialize pixel-loop */
23695   pTempsrc2 = (mng_uint16p)pSrcline2;
23696   pTempdst  = (mng_uint16p)pDstline;
23697 
23698   if (pTempsrc2)                       /* do we have a second line ? */
23699   {
23700     if (iS < (iM+1) / 2)               /* top half ? */
23701     {
23702       for (iX = 0; iX < iWidth; iX++)
23703       {
23704         *pTempdst = *pTempsrc1;        /* replicate gray from top */
23705 
23706         pTempdst++;
23707         pTempsrc1++;
23708         pTempsrc2++;
23709 
23710         if (*pTempsrc1 == *pTempsrc2)  /* calculate the distances */
23711           *pTempdst = *pTempsrc1;
23712         else
23713           mng_put_uint16 ((mng_uint8p)pTempdst,
23714                           (mng_uint16)( ( (2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc2)) -
23715                                                       (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1)) ) + iM) /
23716                                           (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1))         ) );
23717 
23718         pTempdst++;
23719         pTempsrc1++;
23720         pTempsrc2++;
23721       }
23722     }
23723     else
23724     {
23725       for (iX = 0; iX < iWidth; iX++)
23726       {
23727         *pTempdst = *pTempsrc2;        /* replicate gray from bottom */
23728 
23729         pTempdst++;
23730         pTempsrc1++;
23731         pTempsrc2++;
23732 
23733         if (*pTempsrc1 == *pTempsrc2)  /* calculate the distances */
23734           *pTempdst = *pTempsrc1;
23735         else
23736           mng_put_uint16 ((mng_uint8p)pTempdst,
23737                           (mng_uint16)( ( (2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc2)) -
23738                                                       (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1)) ) + iM) /
23739                                           (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1))         ) );
23740 
23741         pTempdst++;
23742         pTempsrc1++;
23743         pTempsrc2++;
23744       }
23745     }
23746   }
23747   else
23748   {                                    /* just repeat the entire line */
23749     MNG_COPY (pTempdst, pTempsrc1, (iWidth << 2));
23750   }
23751 
23752 #ifdef MNG_SUPPORT_TRACE
23753   MNG_TRACE (pData, MNG_FN_MAGNIFY_GA16_Y5, MNG_LC_END);
23754 #endif
23755 
23756   return MNG_NOERROR;
23757 }
23758 #endif /* MNG_NO_GRAY_SUPPORT */
23759 
23760 /* ************************************************************************** */
23761 
mng_magnify_rgba16_y1(mng_datap pData,mng_int32 iS,mng_int32 iM,mng_uint32 iWidth,mng_uint8p pSrcline1,mng_uint8p pSrcline2,mng_uint8p pDstline)23762 mng_retcode mng_magnify_rgba16_y1 (mng_datap  pData,
23763                                    mng_int32  iS,
23764                                    mng_int32  iM,
23765                                    mng_uint32 iWidth,
23766                                    mng_uint8p pSrcline1,
23767                                    mng_uint8p pSrcline2,
23768                                    mng_uint8p pDstline)
23769 {
23770 #ifdef MNG_SUPPORT_TRACE
23771   MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA16_Y1, MNG_LC_START);
23772 #endif
23773 
23774   MNG_COPY (pDstline, pSrcline1, (iWidth << 3));
23775 
23776 #ifdef MNG_SUPPORT_TRACE
23777   MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA16_Y1, MNG_LC_END);
23778 #endif
23779 
23780   return MNG_NOERROR;
23781 }
23782 
23783 /* ************************************************************************** */
23784 
mng_magnify_rgba16_y2(mng_datap pData,mng_int32 iS,mng_int32 iM,mng_uint32 iWidth,mng_uint8p pSrcline1,mng_uint8p pSrcline2,mng_uint8p pDstline)23785 mng_retcode mng_magnify_rgba16_y2 (mng_datap  pData,
23786                                    mng_int32  iS,
23787                                    mng_int32  iM,
23788                                    mng_uint32 iWidth,
23789                                    mng_uint8p pSrcline1,
23790                                    mng_uint8p pSrcline2,
23791                                    mng_uint8p pDstline)
23792 {
23793   mng_uint32  iX;
23794   mng_uint16p pTempsrc1;
23795   mng_uint16p pTempsrc2;
23796   mng_uint16p pTempdst;
23797 
23798 #ifdef MNG_SUPPORT_TRACE
23799   MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA16_Y2, MNG_LC_START);
23800 #endif
23801 
23802   pTempsrc1 = (mng_uint16p)pSrcline1;  /* initialize pixel-loop */
23803   pTempsrc2 = (mng_uint16p)pSrcline2;
23804   pTempdst  = (mng_uint16p)pDstline;
23805 
23806   if (pTempsrc2)                       /* do we have a second line ? */
23807   {
23808     for (iX = 0; iX < iWidth; iX++)
23809     {                                  /* calculate the distances */
23810       if (*pTempsrc1 == *pTempsrc2)
23811         *pTempdst = *pTempsrc1;
23812       else
23813         mng_put_uint16 ((mng_uint8p)pTempdst,
23814                         (mng_uint16)( ( (2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc2)) -
23815                                                     (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1)) ) + iM) /
23816                                         (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1))         ) );
23817 
23818       pTempdst++;
23819       pTempsrc1++;
23820       pTempsrc2++;
23821 
23822       if (*pTempsrc1 == *pTempsrc2)
23823         *pTempdst = *pTempsrc1;
23824       else
23825         mng_put_uint16 ((mng_uint8p)pTempdst,
23826                         (mng_uint16)( ( (2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc2)) -
23827                                                     (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1)) ) + iM) /
23828                                         (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1))         ) );
23829 
23830       pTempdst++;
23831       pTempsrc1++;
23832       pTempsrc2++;
23833 
23834       if (*pTempsrc1 == *pTempsrc2)
23835         *pTempdst = *pTempsrc1;
23836       else
23837         mng_put_uint16 ((mng_uint8p)pTempdst,
23838                         (mng_uint16)( ( (2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc2)) -
23839                                                     (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1)) ) + iM) /
23840                                         (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1))         ) );
23841 
23842       pTempdst++;
23843       pTempsrc1++;
23844       pTempsrc2++;
23845 
23846       if (*pTempsrc1 == *pTempsrc2)
23847         *pTempdst = *pTempsrc1;
23848       else
23849         mng_put_uint16 ((mng_uint8p)pTempdst,
23850                         (mng_uint16)( ( (2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc2)) -
23851                                                     (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1)) ) + iM) /
23852                                         (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1))         ) );
23853 
23854       pTempdst++;
23855       pTempsrc1++;
23856       pTempsrc2++;
23857     }
23858   }
23859   else
23860   {                                    /* just repeat the entire line */
23861     MNG_COPY (pTempdst, pTempsrc1, (iWidth << 3));
23862   }
23863 
23864 #ifdef MNG_SUPPORT_TRACE
23865   MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA16_Y2, MNG_LC_END);
23866 #endif
23867 
23868   return MNG_NOERROR;
23869 }
23870 
23871 /* ************************************************************************** */
23872 
mng_magnify_rgba16_y3(mng_datap pData,mng_int32 iS,mng_int32 iM,mng_uint32 iWidth,mng_uint8p pSrcline1,mng_uint8p pSrcline2,mng_uint8p pDstline)23873 mng_retcode mng_magnify_rgba16_y3 (mng_datap  pData,
23874                                    mng_int32  iS,
23875                                    mng_int32  iM,
23876                                    mng_uint32 iWidth,
23877                                    mng_uint8p pSrcline1,
23878                                    mng_uint8p pSrcline2,
23879                                    mng_uint8p pDstline)
23880 {
23881 #ifdef MNG_SUPPORT_TRACE
23882   MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA16_Y3, MNG_LC_START);
23883 #endif
23884 
23885   if (pSrcline2)                       /* do we have a second line ? */
23886   {
23887     if (iS < (iM+1) / 2)               /* top half ? */
23888       MNG_COPY (pDstline, pSrcline1, (iWidth << 3))
23889     else
23890       MNG_COPY (pDstline, pSrcline2, (iWidth << 3));
23891   }
23892   else
23893   {                                    /* just repeat the entire line */
23894     MNG_COPY (pDstline, pSrcline1, (iWidth << 3));
23895   }
23896 
23897 #ifdef MNG_SUPPORT_TRACE
23898   MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA16_Y2, MNG_LC_END);
23899 #endif
23900 
23901   return MNG_NOERROR;
23902 }
23903 
23904 /* ************************************************************************** */
23905 
mng_magnify_rgba16_y4(mng_datap pData,mng_int32 iS,mng_int32 iM,mng_uint32 iWidth,mng_uint8p pSrcline1,mng_uint8p pSrcline2,mng_uint8p pDstline)23906 mng_retcode mng_magnify_rgba16_y4 (mng_datap  pData,
23907                                    mng_int32  iS,
23908                                    mng_int32  iM,
23909                                    mng_uint32 iWidth,
23910                                    mng_uint8p pSrcline1,
23911                                    mng_uint8p pSrcline2,
23912                                    mng_uint8p pDstline)
23913 {
23914   mng_uint32  iX;
23915   mng_uint16p pTempsrc1;
23916   mng_uint16p pTempsrc2;
23917   mng_uint16p pTempdst;
23918 
23919 #ifdef MNG_SUPPORT_TRACE
23920   MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA16_Y4, MNG_LC_START);
23921 #endif
23922 
23923   pTempsrc1 = (mng_uint16p)pSrcline1;  /* initialize pixel-loop */
23924   pTempsrc2 = (mng_uint16p)pSrcline2;
23925   pTempdst  = (mng_uint16p)pDstline;
23926 
23927   if (pTempsrc2)                       /* do we have a second line ? */
23928   {
23929     if (iS < (iM+1) / 2)               /* top half ? */
23930     {
23931       for (iX = 0; iX < iWidth; iX++)
23932       {                                /* calculate the distances */
23933         if (*pTempsrc1 == *pTempsrc2)
23934           *pTempdst = *pTempsrc1;
23935         else
23936           mng_put_uint16 ((mng_uint8p)pTempdst,
23937                           (mng_uint16)( ( (2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc2)) -
23938                                                       (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1)) ) + iM) /
23939                                           (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1))         ) );
23940 
23941         pTempdst++;
23942         pTempsrc1++;
23943         pTempsrc2++;
23944 
23945         if (*pTempsrc1 == *pTempsrc2)
23946           *pTempdst = *pTempsrc1;
23947         else
23948           mng_put_uint16 ((mng_uint8p)pTempdst,
23949                           (mng_uint16)( ( (2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc2)) -
23950                                                       (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1)) ) + iM) /
23951                                           (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1))         ) );
23952 
23953         pTempdst++;
23954         pTempsrc1++;
23955         pTempsrc2++;
23956 
23957         if (*pTempsrc1 == *pTempsrc2)
23958           *pTempdst = *pTempsrc1;
23959         else
23960           mng_put_uint16 ((mng_uint8p)pTempdst,
23961                           (mng_uint16)( ( (2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc2)) -
23962                                                       (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1)) ) + iM) /
23963                                           (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1))         ) );
23964 
23965         pTempdst++;
23966         pTempsrc1++;
23967         pTempsrc2 += 2;
23968 
23969         *pTempdst++ = *pTempsrc1++;    /* replicate alpha from top */
23970       }
23971     }
23972     else
23973     {
23974       for (iX = 0; iX < iWidth; iX++)
23975       {                                /* calculate the distances */
23976         if (*pTempsrc1 == *pTempsrc2)
23977           *pTempdst = *pTempsrc1;
23978         else
23979           mng_put_uint16 ((mng_uint8p)pTempdst,
23980                           (mng_uint16)( ( (2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc2)) -
23981                                                       (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1)) ) + iM) /
23982                                           (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1))         ) );
23983 
23984         pTempdst++;
23985         pTempsrc1++;
23986         pTempsrc2++;
23987 
23988         if (*pTempsrc1 == *pTempsrc2)
23989           *pTempdst = *pTempsrc1;
23990         else
23991           mng_put_uint16 ((mng_uint8p)pTempdst,
23992                           (mng_uint16)( ( (2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc2)) -
23993                                                       (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1)) ) + iM) /
23994                                           (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1))         ) );
23995 
23996         pTempdst++;
23997         pTempsrc1++;
23998         pTempsrc2++;
23999 
24000         if (*pTempsrc1 == *pTempsrc2)
24001           *pTempdst = *pTempsrc1;
24002         else
24003           mng_put_uint16 ((mng_uint8p)pTempdst,
24004                           (mng_uint16)( ( (2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc2)) -
24005                                                       (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1)) ) + iM) /
24006                                           (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1))         ) );
24007 
24008         pTempdst++;
24009         pTempsrc1 += 2;
24010         pTempsrc2++;
24011 
24012         *pTempdst++ = *pTempsrc2++;    /* replicate alpha from bottom */
24013       }
24014     }
24015   }
24016   else
24017   {                                    /* just repeat the entire line */
24018     MNG_COPY (pTempdst, pTempsrc1, (iWidth << 3));
24019   }
24020 
24021 #ifdef MNG_SUPPORT_TRACE
24022   MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA16_Y4, MNG_LC_END);
24023 #endif
24024 
24025   return MNG_NOERROR;
24026 }
24027 
24028 /* ************************************************************************** */
24029 
mng_magnify_rgba16_y5(mng_datap pData,mng_int32 iS,mng_int32 iM,mng_uint32 iWidth,mng_uint8p pSrcline1,mng_uint8p pSrcline2,mng_uint8p pDstline)24030 mng_retcode mng_magnify_rgba16_y5 (mng_datap  pData,
24031                                    mng_int32  iS,
24032                                    mng_int32  iM,
24033                                    mng_uint32 iWidth,
24034                                    mng_uint8p pSrcline1,
24035                                    mng_uint8p pSrcline2,
24036                                    mng_uint8p pDstline)
24037 {
24038   mng_uint32  iX;
24039   mng_uint16p pTempsrc1;
24040   mng_uint16p pTempsrc2;
24041   mng_uint16p pTempdst;
24042 
24043 #ifdef MNG_SUPPORT_TRACE
24044   MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA16_Y5, MNG_LC_START);
24045 #endif
24046 
24047   pTempsrc1 = (mng_uint16p)pSrcline1;  /* initialize pixel-loop */
24048   pTempsrc2 = (mng_uint16p)pSrcline2;
24049   pTempdst  = (mng_uint16p)pDstline;
24050 
24051   if (pTempsrc2)                       /* do we have a second line ? */
24052   {
24053     if (iS < (iM+1) / 2)               /* top half ? */
24054     {
24055       for (iX = 0; iX < iWidth; iX++)
24056       {
24057         *pTempdst++ = *pTempsrc1++;    /* replicate color from top */
24058         *pTempdst++ = *pTempsrc1++;
24059         *pTempdst++ = *pTempsrc1++;
24060 
24061         pTempsrc2 += 3;
24062 
24063         if (*pTempsrc1 == *pTempsrc2)  /* calculate the distances */
24064           *pTempdst = *pTempsrc1;
24065         else
24066           mng_put_uint16 ((mng_uint8p)pTempdst,
24067                           (mng_uint16)( ( (2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc2)) -
24068                                                       (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1)) ) + iM) /
24069                                           (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1))         ) );
24070 
24071         pTempdst++;
24072         pTempsrc1++;
24073         pTempsrc2++;
24074       }
24075     }
24076     else
24077     {
24078       for (iX = 0; iX < iWidth; iX++)
24079       {
24080         *pTempdst++ = *pTempsrc2++;    /* replicate color from bottom */
24081         *pTempdst++ = *pTempsrc2++;
24082         *pTempdst++ = *pTempsrc2++;
24083 
24084         pTempsrc1 += 3;
24085 
24086         if (*pTempsrc1 == *pTempsrc2)  /* calculate the distances */
24087           *pTempdst = *pTempsrc1;
24088         else
24089           mng_put_uint16 ((mng_uint8p)pTempdst,
24090                           (mng_uint16)( ( (2 * iS * ( (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc2)) -
24091                                                       (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1)) ) + iM) /
24092                                           (iM * 2)) + (mng_int32)(mng_get_uint16 ((mng_uint8p)pTempsrc1))         ) );
24093 
24094         pTempdst++;
24095         pTempsrc1++;
24096         pTempsrc2++;
24097       }
24098     }
24099   }
24100   else
24101   {                                    /* just repeat the entire line */
24102     MNG_COPY (pTempdst, pTempsrc1, (iWidth << 3));
24103   }
24104 
24105 #ifdef MNG_SUPPORT_TRACE
24106   MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA16_Y5, MNG_LC_END);
24107 #endif
24108 
24109   return MNG_NOERROR;
24110 }
24111 #endif /* MNG_NO_16BIT_SUPPORT */
24112 #endif /* MNG_OPTIMIZE_FOOTPRINT_MAGN */
24113 #endif /* MNG_SKIPCHUNK_MAGN */
24114 
24115 /* ************************************************************************** */
24116 /* *                                                                        * */
24117 /* * PAST composition routines - compose over/under with a target object    * */
24118 /* *                                                                        * */
24119 /* ************************************************************************** */
24120 
24121 #ifndef MNG_SKIPCHUNK_PAST
mng_composeover_rgba8(mng_datap pData)24122 mng_retcode mng_composeover_rgba8 (mng_datap pData)
24123 {
24124   mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
24125   mng_uint8p     pWorkrow;
24126   mng_uint8p     pOutrow;
24127   mng_int32      iX;
24128   mng_uint8      iFGa8, iBGa8;
24129   mng_uint8      iCr8, iCg8, iCb8, iCa8;
24130 
24131 #ifdef MNG_SUPPORT_TRACE
24132   MNG_TRACE (pData, MNG_FN_COMPOSEOVER_RGBA8, MNG_LC_START);
24133 #endif
24134 
24135   pWorkrow = pData->pRGBArow;
24136   pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
24137                               (pData->iCol * pBuf->iSamplesize);
24138 
24139 #ifdef MNG_DECREMENT_LOOPS
24140   for (iX = pData->iRowsamples; iX > 0; iX--)
24141 #else
24142   for (iX = 0; iX < pData->iRowsamples; iX++)
24143 #endif
24144   {
24145     iFGa8 = *(pWorkrow+3);       /* get alpha values */
24146     iBGa8 = *(pOutrow+3);
24147 
24148     if (iFGa8)                   /* any opacity at all ? */
24149     {                            /* fully opaque or background fully transparent ? */
24150       if ((iFGa8 == 0xFF) || (iBGa8 == 0))
24151       {                          /* then simply copy the values */
24152         *pOutrow     = *pWorkrow;
24153         *(pOutrow+1) = *(pWorkrow+1);
24154         *(pOutrow+2) = *(pWorkrow+2);
24155         *(pOutrow+3) = iFGa8;
24156       }
24157       else
24158       {
24159         if (iBGa8 == 0xFF)       /* background fully opaque ? */
24160         {                        /* do alpha composing */
24161 #ifdef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
24162           int i;
24163           for (i=2; i >= 0; i--)
24164           {
24165           MNG_COMPOSE8 (*(pOutrow+i), *(pWorkrow+i), iFGa8, *(pOutrow+i));
24166           }
24167 #else
24168           MNG_COMPOSE8 (*pOutrow,     *pWorkrow,     iFGa8, *pOutrow    );
24169           MNG_COMPOSE8 (*(pOutrow+1), *(pWorkrow+1), iFGa8, *(pOutrow+1));
24170           MNG_COMPOSE8 (*(pOutrow+2), *(pWorkrow+2), iFGa8, *(pOutrow+2));
24171 #endif
24172                                  /* alpha remains fully opaque !!! */
24173         }
24174         else
24175         {                        /* here we'll have to blend */
24176           MNG_BLEND8 (*pWorkrow, *(pWorkrow+1), *(pWorkrow+2), iFGa8,
24177                       *pOutrow, *(pOutrow+1), *(pOutrow+2), iBGa8,
24178                       iCr8, iCg8, iCb8, iCa8);
24179                                  /* and return the composed values */
24180           *pOutrow     = iCr8;
24181           *(pOutrow+1) = iCg8;
24182           *(pOutrow+2) = iCb8;
24183           *(pOutrow+3) = iCa8;
24184         }
24185       }
24186     }
24187 
24188     pOutrow  += 4;
24189     pWorkrow += 4;
24190   }
24191 
24192 #ifdef MNG_SUPPORT_TRACE
24193   MNG_TRACE (pData, MNG_FN_COMPOSEOVER_RGBA8, MNG_LC_END);
24194 #endif
24195 
24196   return MNG_NOERROR;
24197 }
24198 
24199 /* ************************************************************************** */
24200 
24201 #ifndef MNG_NO_16BIT_SUPPORT
mng_composeover_rgba16(mng_datap pData)24202 mng_retcode mng_composeover_rgba16 (mng_datap pData)
24203 {
24204   mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
24205   mng_uint16p    pWorkrow;
24206   mng_uint16p    pOutrow;
24207   mng_int32      iX;
24208   mng_uint16     iFGa16, iFGr16, iFGg16, iFGb16;
24209   mng_uint16     iBGa16, iBGr16, iBGg16, iBGb16;
24210   mng_uint16     iCr16, iCg16, iCb16, iCa16;
24211 
24212 #ifdef MNG_SUPPORT_TRACE
24213   MNG_TRACE (pData, MNG_FN_COMPOSEOVER_RGBA16, MNG_LC_START);
24214 #endif
24215 
24216   pWorkrow = (mng_uint16p)pData->pRGBArow;
24217   pOutrow  = (mng_uint16p)(pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
24218                                             (pData->iCol * pBuf->iSamplesize));
24219 
24220 #ifdef MNG_DECREMENT_LOOPS
24221   for (iX = pData->iRowsamples; iX > 0; iX--)
24222 #else
24223   for (iX = 0; iX < pData->iRowsamples; iX++)
24224 #endif
24225   {                              /* get alpha values */
24226     iFGa16 = mng_get_uint16 ((mng_uint8p)(pWorkrow+3));
24227     iBGa16 = mng_get_uint16 ((mng_uint8p)(pOutrow+3));
24228 
24229     if (iFGa16)                  /* any opacity at all ? */
24230     {                            /* fully opaque or background fully transparent ? */
24231       if ((iFGa16 == 0xFFFF) || (iBGa16 == 0))
24232       {                          /* then simply copy the values */
24233         *pOutrow     = *pWorkrow;
24234         *(pOutrow+1) = *(pWorkrow+1);
24235         *(pOutrow+2) = *(pWorkrow+2);
24236         *(pOutrow+3) = *(pWorkrow+3);
24237       }
24238       else
24239       {                          /* get color values */
24240         iFGr16 = mng_get_uint16 ((mng_uint8p)pWorkrow);
24241         iFGg16 = mng_get_uint16 ((mng_uint8p)(pWorkrow+1));
24242         iFGb16 = mng_get_uint16 ((mng_uint8p)(pWorkrow+2));
24243         iBGr16 = mng_get_uint16 ((mng_uint8p)pOutrow);
24244         iBGg16 = mng_get_uint16 ((mng_uint8p)(pOutrow+1));
24245         iBGb16 = mng_get_uint16 ((mng_uint8p)(pOutrow+2));
24246 
24247         if (iBGa16 == 0xFFFF)    /* background fully opaque ? */
24248         {                        /* do alpha composing */
24249           MNG_COMPOSE16 (iFGr16, iFGr16, iFGa16, iBGr16);
24250           MNG_COMPOSE16 (iFGg16, iFGg16, iFGa16, iBGg16);
24251           MNG_COMPOSE16 (iFGb16, iFGb16, iFGa16, iBGb16);
24252 
24253           mng_put_uint16 ((mng_uint8p)pOutrow,     iFGr16);
24254           mng_put_uint16 ((mng_uint8p)(pOutrow+1), iFGg16);
24255           mng_put_uint16 ((mng_uint8p)(pOutrow+2), iFGb16);
24256                                  /* alpha remains fully opaque !!! */
24257         }
24258         else
24259         {                        /* here we'll have to blend */
24260           MNG_BLEND16 (iFGr16, iFGg16, iFGb16, iFGa16,
24261                        iBGr16, iBGg16, iBGb16, iBGa16,
24262                        iCr16,  iCg16,  iCb16,  iCa16);
24263                                  /* and return the composed values */
24264           mng_put_uint16 ((mng_uint8p)pOutrow,     iCr16);
24265           mng_put_uint16 ((mng_uint8p)(pOutrow+1), iCg16);
24266           mng_put_uint16 ((mng_uint8p)(pOutrow+2), iCb16);
24267           mng_put_uint16 ((mng_uint8p)(pOutrow+3), iCa16);
24268         }
24269       }
24270     }
24271 
24272     pOutrow  += 4;
24273     pWorkrow += 4;
24274   }
24275 
24276 #ifdef MNG_SUPPORT_TRACE
24277   MNG_TRACE (pData, MNG_FN_COMPOSEOVER_RGBA16, MNG_LC_END);
24278 #endif
24279 
24280   return MNG_NOERROR;
24281 }
24282 #endif
24283 
24284 /* ************************************************************************** */
24285 
mng_composeunder_rgba8(mng_datap pData)24286 mng_retcode mng_composeunder_rgba8 (mng_datap pData)
24287 {
24288   mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
24289   mng_uint8p     pWorkrow;
24290   mng_uint8p     pOutrow;
24291   mng_int32      iX;
24292   mng_uint8      iFGa8, iBGa8;
24293   mng_uint8      iCr8, iCg8, iCb8, iCa8;
24294 
24295 #ifdef MNG_SUPPORT_TRACE
24296   MNG_TRACE (pData, MNG_FN_COMPOSEUNDER_RGBA8, MNG_LC_START);
24297 #endif
24298 
24299   pWorkrow = pData->pRGBArow;
24300   pOutrow  = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
24301                               (pData->iCol * pBuf->iSamplesize);
24302 
24303 #ifdef MNG_DECREMENT_LOOPS
24304   for (iX = pData->iRowsamples; iX > 0; iX--)
24305 #else
24306   for (iX = 0; iX < pData->iRowsamples; iX++)
24307 #endif
24308   {
24309     iFGa8 = *(pOutrow+3);        /* get alpha values */
24310     iBGa8 = *(pWorkrow+3);
24311                                  /* anything to do at all ? */
24312     if ((iBGa8) && (iFGa8 != 0xFF))
24313     {
24314       if (iBGa8 == 0xFF)         /* background fully opaque ? */
24315       {                          /* do alpha composing */
24316 #ifdef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
24317         int i;
24318         for (i=2; i >= 0; i--)
24319         {
24320         MNG_COMPOSE8 (*(pOutrow+i), *(pOutrow+i), iFGa8, *(pWorkrow+i));
24321         }
24322 #else
24323         MNG_COMPOSE8 (*pOutrow,     *pOutrow,     iFGa8, *pWorkrow    );
24324         MNG_COMPOSE8 (*(pOutrow+1), *(pOutrow+1), iFGa8, *(pWorkrow+1));
24325         MNG_COMPOSE8 (*(pOutrow+2), *(pOutrow+2), iFGa8, *(pWorkrow+2));
24326 #endif
24327         *(pOutrow+3) = 0xFF;     /* alpha becomes fully opaque !!! */
24328       }
24329       else
24330       {                          /* here we'll have to blend */
24331         MNG_BLEND8 (*pOutrow, *(pOutrow+1), *(pOutrow+2), iFGa8,
24332                     *pWorkrow, *(pWorkrow+1), *(pWorkrow+2), iBGa8,
24333                     iCr8, iCg8, iCb8, iCa8);
24334                                  /* and return the composed values */
24335         *pOutrow     = iCr8;
24336         *(pOutrow+1) = iCg8;
24337         *(pOutrow+2) = iCb8;
24338         *(pOutrow+3) = iCa8;
24339       }
24340     }
24341 
24342     pOutrow  += 4;
24343     pWorkrow += 4;
24344   }
24345 
24346 #ifdef MNG_SUPPORT_TRACE
24347   MNG_TRACE (pData, MNG_FN_COMPOSEUNDER_RGBA8, MNG_LC_END);
24348 #endif
24349 
24350   return MNG_NOERROR;
24351 }
24352 
24353 /* ************************************************************************** */
24354 
24355 #ifndef MNG_NO_16BIT_SUPPORT
mng_composeunder_rgba16(mng_datap pData)24356 mng_retcode mng_composeunder_rgba16 (mng_datap pData)
24357 {
24358   mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
24359   mng_uint16p    pWorkrow;
24360   mng_uint16p    pOutrow;
24361   mng_int32      iX;
24362   mng_uint16     iFGa16, iFGr16, iFGg16, iFGb16;
24363   mng_uint16     iBGa16, iBGr16, iBGg16, iBGb16;
24364   mng_uint16     iCr16, iCg16, iCb16, iCa16;
24365 
24366 #ifdef MNG_SUPPORT_TRACE
24367   MNG_TRACE (pData, MNG_FN_COMPOSEUNDER_RGBA16, MNG_LC_START);
24368 #endif
24369 
24370   pWorkrow = (mng_uint16p)pData->pRGBArow;
24371   pOutrow  = (mng_uint16p)(pBuf->pImgdata + (pData->iRow * pBuf->iRowsize   ) +
24372                                             (pData->iCol * pBuf->iSamplesize));
24373 
24374 #ifdef MNG_DECREMENT_LOOPS
24375   for (iX = pData->iRowsamples; iX > 0; iX--)
24376 #else
24377   for (iX = 0; iX < pData->iRowsamples; iX++)
24378 #endif
24379   {                              /* get alpha values */
24380     iFGa16 = mng_get_uint16 ((mng_uint8p)(pOutrow+3));
24381     iBGa16 = mng_get_uint16 ((mng_uint8p)(pWorkrow+3));
24382                                  /* anything to do at all ? */
24383     if ((iBGa16) && (iFGa16 != 0xFFFF))
24384     {
24385       iFGr16 = mng_get_uint16 ((mng_uint8p)pOutrow);
24386       iFGg16 = mng_get_uint16 ((mng_uint8p)(pOutrow+1));
24387       iFGb16 = mng_get_uint16 ((mng_uint8p)(pOutrow+2));
24388       iBGr16 = mng_get_uint16 ((mng_uint8p)pWorkrow);
24389       iBGg16 = mng_get_uint16 ((mng_uint8p)(pWorkrow+1));
24390       iBGb16 = mng_get_uint16 ((mng_uint8p)(pWorkrow+2));
24391 
24392       if (iBGa16 == 0xFFFF)      /* background fully opaque ? */
24393       {                          /* do alpha composing */
24394         MNG_COMPOSE16 (iFGr16, iFGr16, iFGa16, iBGr16);
24395         MNG_COMPOSE16 (iFGg16, iFGg16, iFGa16, iBGg16);
24396         MNG_COMPOSE16 (iFGb16, iFGb16, iFGa16, iBGb16);
24397 
24398         mng_put_uint16 ((mng_uint8p)pOutrow,     iFGr16);
24399         mng_put_uint16 ((mng_uint8p)(pOutrow+1), iFGg16);
24400         mng_put_uint16 ((mng_uint8p)(pOutrow+2), iFGb16);
24401         *(pOutrow+3) = 0xFFFF;   /* alpha becomes fully opaque !!! */
24402       }
24403       else
24404       {                          /* here we'll have to blend */
24405         MNG_BLEND16 (iFGr16, iFGg16, iFGb16, iFGa16,
24406                      iBGr16, iBGg16, iBGb16, iBGa16,
24407                      iCr16,  iCg16,  iCb16,  iCa16);
24408                                  /* and return the composed values */
24409         mng_put_uint16 ((mng_uint8p)pOutrow,     iCr16);
24410         mng_put_uint16 ((mng_uint8p)(pOutrow+1), iCg16);
24411         mng_put_uint16 ((mng_uint8p)(pOutrow+2), iCb16);
24412         mng_put_uint16 ((mng_uint8p)(pOutrow+3), iCa16);
24413       }
24414     }
24415 
24416     pOutrow  += 4;
24417     pWorkrow += 4;
24418   }
24419 
24420 #ifdef MNG_SUPPORT_TRACE
24421   MNG_TRACE (pData, MNG_FN_COMPOSEUNDER_RGBA16, MNG_LC_END);
24422 #endif
24423 
24424   return MNG_NOERROR;
24425 }
24426 #endif
24427 #endif
24428 
24429 /* ************************************************************************** */
24430 /* *                                                                        * */
24431 /* * PAST flip & tile routines - flip or tile a row of pixels               * */
24432 /* *                                                                        * */
24433 /* ************************************************************************** */
24434 
24435 #ifndef MNG_SKIPCHUNK_PAST
mng_flip_rgba8(mng_datap pData)24436 mng_retcode mng_flip_rgba8 (mng_datap pData)
24437 {
24438   mng_uint32p pWorkrow;
24439   mng_uint32p pOutrow;
24440   mng_int32   iX;
24441 
24442 #ifdef MNG_SUPPORT_TRACE
24443   MNG_TRACE (pData, MNG_FN_FLIP_RGBA8, MNG_LC_START);
24444 #endif
24445                                        /* setup temp pointers */
24446   pWorkrow        = (mng_uint32p)pData->pRGBArow + pData->iRowsamples - 1;
24447   pOutrow         = (mng_uint32p)pData->pWorkrow;
24448                                        /* swap original buffers */
24449   pData->pWorkrow = pData->pRGBArow;
24450   pData->pRGBArow = (mng_uint8p)pOutrow;
24451 
24452 #ifdef MNG_DECREMENT_LOOPS
24453   for (iX = pData->iRowsamples; iX > 0; iX--)
24454 #else
24455   for (iX = 0; iX < pData->iRowsamples; iX++)
24456 #endif
24457   {                                    /* let's flip */
24458     *pOutrow = *pWorkrow;
24459     pOutrow++;
24460     pWorkrow--;
24461   }
24462 
24463 #ifdef MNG_SUPPORT_TRACE
24464   MNG_TRACE (pData, MNG_FN_FLIP_RGBA8, MNG_LC_END);
24465 #endif
24466 
24467   return MNG_NOERROR;
24468 }
24469 
24470 /* ************************************************************************** */
24471 
24472 #ifndef MNG_NO_16BIT_SUPPORT
mng_flip_rgba16(mng_datap pData)24473 mng_retcode mng_flip_rgba16 (mng_datap pData)
24474 {
24475   mng_uint32p pWorkrow;
24476   mng_uint32p pOutrow;
24477   mng_int32   iX;
24478 
24479 #ifdef MNG_SUPPORT_TRACE
24480   MNG_TRACE (pData, MNG_FN_FLIP_RGBA16, MNG_LC_START);
24481 #endif
24482                                        /* setup temp pointers */
24483   pWorkrow        = (mng_uint32p)pData->pRGBArow + ((pData->iRowsamples - 1) << 1);
24484   pOutrow         = (mng_uint32p)pData->pWorkrow;
24485                                        /* swap original buffers */
24486   pData->pWorkrow = pData->pRGBArow;
24487   pData->pRGBArow = (mng_uint8p)pOutrow;
24488 
24489 #ifdef MNG_DECREMENT_LOOPS
24490   for (iX = pData->iRowsamples; iX > 0; iX--)
24491 #else
24492   for (iX = 0; iX < pData->iRowsamples; iX++)
24493 #endif
24494   {                                    /* let's flip */
24495     *pOutrow       = *pWorkrow;
24496     *(pOutrow + 1) = *(pWorkrow + 1);
24497 
24498     pOutrow  += 2;
24499     pWorkrow -= 2;
24500   }
24501 
24502 #ifdef MNG_SUPPORT_TRACE
24503   MNG_TRACE (pData, MNG_FN_FLIP_RGBA16, MNG_LC_END);
24504 #endif
24505 
24506   return MNG_NOERROR;
24507 }
24508 #endif
24509 
24510 /* ************************************************************************** */
24511 
mng_tile_rgba8(mng_datap pData)24512 mng_retcode mng_tile_rgba8 (mng_datap pData)
24513 {
24514   mng_uint32p pWorkrow;
24515   mng_uint32p pOutrow;
24516   mng_int32   iX;
24517   mng_uint32  iZ, iMax;
24518 
24519 #ifdef MNG_SUPPORT_TRACE
24520   MNG_TRACE (pData, MNG_FN_TILE_RGBA8, MNG_LC_START);
24521 #endif
24522 
24523   iZ              = pData->iSourcel;   /* indent ? */
24524                                        /* what's our source-length */
24525   iMax            = ((mng_imagep)pData->pRetrieveobj)->pImgbuf->iWidth;
24526                                        /* setup temp pointers */
24527   pWorkrow        = (mng_uint32p)pData->pRGBArow + iZ;
24528   pOutrow         = (mng_uint32p)pData->pWorkrow;
24529                                        /* swap original buffers */
24530   pData->pWorkrow = pData->pRGBArow;
24531   pData->pRGBArow = (mng_uint8p)pOutrow;
24532 
24533   for (iX = pData->iDestl; iX < pData->iDestr; iX++)
24534   {                                    /* tiiiile */
24535     *pOutrow = *pWorkrow;
24536 
24537     pWorkrow++;
24538     pOutrow++;
24539     iZ++;
24540 
24541     if (iZ >= iMax)                    /* end of source ? */
24542     {
24543       iZ       = 0;
24544       pWorkrow = (mng_uint32p)pData->pWorkrow;
24545     }
24546   }
24547 
24548 #ifdef MNG_SUPPORT_TRACE
24549   MNG_TRACE (pData, MNG_FN_TILE_RGBA8, MNG_LC_END);
24550 #endif
24551 
24552   return MNG_NOERROR;
24553 }
24554 
24555 /* ************************************************************************** */
24556 
24557 #ifndef MNG_NO_16BIT_SUPPORT
mng_tile_rgba16(mng_datap pData)24558 mng_retcode mng_tile_rgba16 (mng_datap pData)
24559 {
24560   mng_uint32p pWorkrow;
24561   mng_uint32p pOutrow;
24562   mng_int32   iX;
24563   mng_uint32  iZ, iMax;
24564 
24565 #ifdef MNG_SUPPORT_TRACE
24566   MNG_TRACE (pData, MNG_FN_TILE_RGBA16, MNG_LC_START);
24567 #endif
24568 
24569   iZ              = pData->iSourcel;   /* indent ? */
24570                                        /* what's our source-length */
24571   iMax            = ((mng_imagep)pData->pRetrieveobj)->pImgbuf->iWidth;
24572                                        /* setup temp pointers */
24573   pWorkrow        = (mng_uint32p)pData->pRGBArow + (iZ << 1);
24574   pOutrow         = (mng_uint32p)pData->pWorkrow;
24575                                        /* swap original buffers */
24576   pData->pWorkrow = pData->pRGBArow;
24577   pData->pRGBArow = (mng_uint8p)pOutrow;
24578 
24579   for (iX = pData->iDestl; iX < pData->iDestr; iX++)
24580   {                                    /* tiiiile */
24581     *pOutrow       = *pWorkrow;
24582     *(pOutrow + 1) = *(pWorkrow + 1);
24583 
24584     pWorkrow += 2;
24585     pOutrow  += 2;
24586     iZ++;
24587 
24588     if (iZ >= iMax)                    /* end of source ? */
24589     {
24590       iZ       = 0;
24591       pWorkrow = (mng_uint32p)pData->pWorkrow;
24592     }
24593   }
24594 
24595 #ifdef MNG_SUPPORT_TRACE
24596   MNG_TRACE (pData, MNG_FN_TILE_RGBA16, MNG_LC_END);
24597 #endif
24598 
24599   return MNG_NOERROR;
24600 }
24601 #endif
24602 #endif /* MNG_SKIPCHUNK_PAST */
24603 
24604 /* ************************************************************************** */
24605 
24606 #endif /* MNG_INCLUDE_DISPLAY_PROCS */
24607 
24608 /* ************************************************************************** */
24609 /* * end of file                                                            * */
24610 /* ************************************************************************** */
24611