summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/libmng/libmng_pixels.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/libmng/libmng_pixels.c')
-rw-r--r--src/3rdparty/libmng/libmng_pixels.c24610
1 files changed, 24610 insertions, 0 deletions
diff --git a/src/3rdparty/libmng/libmng_pixels.c b/src/3rdparty/libmng/libmng_pixels.c
new file mode 100644
index 0000000000..ce5637be95
--- /dev/null
+++ b/src/3rdparty/libmng/libmng_pixels.c
@@ -0,0 +1,24610 @@
+/* ************************************************************************** */
+/* * For conditions of distribution and use, * */
+/* * see copyright notice in libmng.h * */
+/* ************************************************************************** */
+/* * * */
+/* * project : libmng * */
+/* * file : libmng_pixels.c copyright (c) 2000-2005 G.Juyn * */
+/* * version : 1.0.10 * */
+/* * * */
+/* * purpose : Pixel-row management routines (implementation) * */
+/* * * */
+/* * author : G.Juyn * */
+/* * * */
+/* * comment : implementation of the pixel-row management routines * */
+/* * * */
+/* * the dual alpha-composing for RGBA/BGRA/etc output-canvas' * */
+/* * is based on the Note on Compositing chapter of the * */
+/* * DOH-3 draft, noted to me by Adam M. Costello * */
+/* * * */
+/* * changes : 0.5.1 - 05/08/2000 - G.Juyn * */
+/* * - changed strict-ANSI stuff * */
+/* * 0.5.1 - 05/11/2000 - G.Juyn * */
+/* * - added callback error-reporting support * */
+/* * 0.5.1 - 05/12/2000 - G.Juyn * */
+/* * - changed trace to macro for callback error-reporting * */
+/* * * */
+/* * 0.5.2 - 05/22/2000 - G.Juyn * */
+/* * - added JNG support * */
+/* * 0.5.2 - 05/30/2000 - G.Juyn * */
+/* * - fixed minor bugs 16-bit pixel-handling * */
+/* * - added delta-image row-processing routines * */
+/* * 0.5.2 - 06/02/2000 - G.Juyn * */
+/* * - fixed endian support (hopefully) * */
+/* * 0.5.2 - 06/03/2000 - G.Juyn * */
+/* * - fixed makeup for Linux gcc compile * */
+/* * 0.5.2 - 06/05/2000 - G.Juyn * */
+/* * - implemented app bkgd restore routines * */
+/* * - implemented RGBA8, ARGB8, BGRA8 & ABGR8 display routines * */
+/* * - added support for RGB8_A8 canvasstyle * */
+/* * 0.5.2 - 06/09/2000 - G.Juyn * */
+/* * - fixed alpha-handling for alpha canvasstyles * */
+/* * * */
+/* * 0.5.3 - 06/16/2000 - G.Juyn * */
+/* * - changed progressive-display processing * */
+/* * 0.5.3 - 06/17/2000 - G.Juyn * */
+/* * - changed to support delta-images * */
+/* * - optimized some store_xxx routines * */
+/* * 0.5.3 - 06/20/2000 - G.Juyn * */
+/* * - fixed nasty bug with embedded PNG after delta-image * */
+/* * 0.5.3 - 06/24/2000 - G.Juyn * */
+/* * - fixed problem with 16-bit GA format * */
+/* * 0.5.3 - 06/25/2000 - G.Juyn * */
+/* * - fixed problem with cheap transparency for 4-bit gray * */
+/* * - fixed display_xxxx routines for interlaced images * */
+/* * 0.5.3 - 06/28/2000 - G.Juyn * */
+/* * - fixed compiler-warning for non-initialized iB variable * */
+/* * * */
+/* * 0.9.1 - 07/05/2000 - G.Juyn * */
+/* * - fixed mandatory BACK color to be opaque * */
+/* * * */
+/* * 0.9.2 - 07/31/2000 - G.Juyn * */
+/* * - B110547 - fixed bug in interlace code * */
+/* * 0.9.2 - 08/05/2000 - G.Juyn * */
+/* * - changed file-prefixes * */
+/* * * */
+/* * 0.9.3 - 08/20/2000 - G.Juyn * */
+/* * - fixed app-supplied background restore * */
+/* * 0.9.3 - 08/26/2000 - G.Juyn * */
+/* * - added MAGN chunk * */
+/* * 0.9.3 - 09/07/2000 - G.Juyn * */
+/* * - added support for new filter_types * */
+/* * 0.9.3 - 09/30/2000 - G.Juyn * */
+/* * - fixed MAGN rounding errors (thanks Matthias!) * */
+/* * 0.9.3 - 10/10/2000 - G.Juyn * */
+/* * - fixed alpha-blending for RGBA canvasstyle * */
+/* * 0.9.3 - 10/11/2000 - G.Juyn * */
+/* * - fixed alpha-blending for other alpha-canvasstyles * */
+/* * 0.9.3 - 10/16/2000 - G.Juyn * */
+/* * - added optional support for bKGD for PNG images * */
+/* * - added support for JDAA * */
+/* * 0.9.3 - 10/17/2000 - G.Juyn * */
+/* * - fixed support for bKGD * */
+/* * 0.9.3 - 10/19/2000 - G.Juyn * */
+/* * - implemented delayed delta-processing * */
+/* * 0.9.3 - 10/28/2000 - G.Juyn * */
+/* * - fixed tRNS processing for gray-image < 8-bits * */
+/* * * */
+/* * 0.9.4 - 12/16/2000 - G.Juyn * */
+/* * - fixed mixup of data- & function-pointers (thanks Dimitri)* */
+/* * 0.9.4 - 1/18/2001 - G.Juyn * */
+/* * - removed "old" MAGN methods 3 & 4 * */
+/* * - added "new" MAGN methods 3, 4 & 5 * */
+/* * - removed test filter-methods 1 & 65 * */
+/* * * */
+/* * 1.0.1 - 04/21/2001 - G.Juyn (code by G.Kelly) * */
+/* * - added BGRA8 canvas with premultiplied alpha * */
+/* * 1.0.1 - 04/25/2001 - G.Juyn * */
+/* * - moved mng_clear_cms to libmng_cms * */
+/* * * */
+/* * 1.0.2 - 06/25/2001 - G.Juyn * */
+/* * - added option to turn off progressive refresh * */
+/* * * */
+/* * 1.0.4 - 11/04/2001 - G.Juyn * */
+/* * - fixed possible compile-problem in cleanup_rowproc * */
+/* * 1.0.4 - 06/22/2002 - G.Juyn * */
+/* * - B558212 - off by one error * */
+/* * - MNG subimage alpha composite wrong for rgba8 images * */
+/* * * */
+/* * 1.0.5 - 08/07/2002 - G.Juyn * */
+/* * - added test-option for PNG filter method 193 (=no filter) * */
+/* * 1.0.5 - 08/15/2002 - G.Juyn * */
+/* * - completed PROM support * */
+/* * - completed delta-image support * */
+/* * 1.0.5 - 08/16/2002 - G.Juyn * */
+/* * - completed MAGN support (16-bit functions) * */
+/* * 1.0.5 - 08/19/2002 - G.Juyn * */
+/* * - B597134 - libmng pollutes the linker namespace * */
+/* * 1.0.5 - 09/19/2002 - G.Juyn * */
+/* * - optimized restore-background for bKGD cases * */
+/* * 1.0.5 - 09/20/2002 - G.Juyn * */
+/* * - finished support for BACK image & tiling * */
+/* * 1.0.5 - 09/22/2002 - G.Juyn * */
+/* * - added bgrx8 canvas (filler byte) * */
+/* * 1.0.5 - 09/23/2002 - G.Juyn * */
+/* * - added compose over/under routines for PAST processing * */
+/* * - added flip & tile routines for PAST processing * */
+/* * * */
+/* * 1.0.6 - 03/09/2003 - G.Juyn * */
+/* * - hiding 12-bit JPEG stuff * */
+/* * 1.0.6 - 05/11/2003 - Glenn RP * */
+/* * - added size-optimization COMPOSE routine usage * */
+/* * 1.0.6 - 05/11/2003 - G. Juyn * */
+/* * - added conditionals around canvas update routines * */
+/* * 1.0.6 - 05/25/2003 - Glenn RP * */
+/* * - added size-optimization DIV255B8 routine usage * */
+/* * 1.0.6 - 06/09/2003 - G. R-P * */
+/* * - added conditionals around 8-bit magn routines * */
+/* * 1.0.6 - 07/07/2003 - G. R-P * */
+/* * - removed conditionals around 8-bit magn routines * */
+/* * - added MNG_NO_16BIT_SUPPORT and MNG_NO_DELTA_PNG * */
+/* * conditionals * */
+/* * - reversed many loops to use decrementing counter * */
+/* * - combined init functions * */
+/* * - converted some switches to array references * */
+/* * 1.0.6 - 07/29/2003 - G.Juyn * */
+/* * - fixed duplicate for-loop * */
+/* * 1.0.6 - 07/29/2003 - G.R-P * */
+/* * - added SKIPCHUNK conditionals around PAST chunk support * */
+/* * - fixed "FOOTPRINT_COMPOSEIV" typo (now "FOOTPRINT_DIV") * */
+/* * 1.0.6 - 08/17/2003 - G.R-P * */
+/* * - added more conditionals around "promote" functions * */
+/* * * */
+/* * 1.0.7 - 11/27/2003 - R.A * */
+/* * - added CANVAS_RGB565 and CANVAS_BGR565 * */
+/* * 1.0.7 - 12/06/2003 - R.A * */
+/* * - added CANVAS_RGBA565 and CANVAS_BGRA565 * */
+/* * 1.0.7 - 01/25/2004 - J.S * */
+/* * - added premultiplied alpha canvas' for RGBA, ARGB, ABGR * */
+/* * 1.0.7 - 03/08/2004 - G.R-P * */
+/* * - added more conditionals around 16-bit-supporting code * */
+/* * 1.0.7 - 03/09/2004 - G.Juyn * */
+/* * - fixed bug in promote_g8_g8 with 16bit support off * */
+/* * 1.0.7 - 03/09/2004 - G.R-P * */
+/* * - more optimizations with 16bit support off * */
+/* * 1.0.7 - 03/10/2004 - G.Juyn * */
+/* * - fixed some warnings for 16bit optimizations * */
+/* * 1.0.7 - 03/21/2004 - G.Juyn * */
+/* * - fixed some 64-bit platform compiler warnings * */
+/* * * */
+/* * 1.0.8 - 06/20/2004 - G.Juyn * */
+/* * - some speed optimizations (thanks to John Stiles) * */
+/* * 1.0.8 - 08/01/2004 - G.Juyn * */
+/* * - added support for 3+byte pixelsize for JPEG's * */
+/* * * */
+/* * 1.0.9 - 10/10/2004 - G.R-P. * */
+/* * - added MNG_NO_1_2_4BIT_SUPPORT * */
+/* * 1.0.9 - 10/14/2004 - G.Juyn * */
+/* * - added bgr565_a8 canvas-style (thanks to J. Elvander) * */
+/* * 1.0.9 - 12/05/2004 - G.Juyn * */
+/* * - added LITTLEENDIAN/BIGENDIAN fixtures (thanks J.Stiles) * */
+/* * - fixed MNG_NO_1_2_4BIT_SUPPORT for TBBN1G04.PNG * */
+/* * 1.0.9 - 12/31/2004 - G.R-P. * */
+/* * - fixed warnings about C++ style (//) comments * */
+/* * * */
+/* * 1.0.10 - 07/06/2005 - G.R-P. * */
+/* * - added MORE MNG_NO_1_2_4BIT_SUPPORT * */
+/* * 1.0.10 - 10/06/2005 - G.R-P. * */
+/* * - alloc more memory for MNG_NO_1_2_4BIT_SUPPORT * */
+/* * 1.0.10 - 12/07/2005 - G.R-P. * */
+/* * - optimized footprint of 16bit support * */
+/* * 1.0.10 - 03/07/2006 - (thanks to W. Manthey) * */
+/* * - added CANVAS_RGB555 and CANVAS_BGR555 * */
+/* * * */
+/* ************************************************************************** */
+
+#include "libmng.h"
+#include "libmng_data.h"
+#include "libmng_error.h"
+#include "libmng_trace.h"
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#include "libmng_objects.h"
+#include "libmng_object_prc.h"
+#include "libmng_memory.h"
+#include "libmng_cms.h"
+#include "libmng_filter.h"
+#include "libmng_pixels.h"
+
+#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
+#pragma option -A /* force ANSI-C */
+#endif
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_DISPLAY_PROCS
+
+/* TODO: magnification & canvas-positioning/-clipping */
+
+/* TODO: major optimization of pixel-loops by using assembler (?) */
+
+/* ************************************************************************** */
+/* * * */
+/* * Interlace tables * */
+/* * * */
+/* ************************************************************************** */
+
+MNG_LOCAL mng_uint32 const interlace_row [7] = { 0, 0, 4, 0, 2, 0, 1 };
+MNG_LOCAL mng_uint32 const interlace_rowskip [7] = { 8, 8, 8, 4, 4, 2, 2 };
+MNG_LOCAL mng_uint32 const interlace_col [7] = { 0, 4, 0, 2, 0, 1, 0 };
+MNG_LOCAL mng_uint32 const interlace_colskip [7] = { 8, 8, 4, 4, 2, 2, 1 };
+MNG_LOCAL mng_uint32 const interlace_roundoff [7] = { 7, 7, 3, 3, 1, 1, 0 };
+MNG_LOCAL mng_uint32 const interlace_divider [7] = { 3, 3, 2, 2, 1, 1, 0 };
+
+/* ************************************************************************** */
+/* * * */
+/* * Alpha composing macros * */
+/* * the code below is slightly modified from the libpng package * */
+/* * the original was last optimized by Greg Roelofs & Mark Adler * */
+/* * * */
+/* ************************************************************************** */
+
+#define MNG_COMPOSE8(RET,FG,ALPHA,BG) { \
+ mng_uint16 iH = (mng_uint16)((mng_uint16)(FG) * (mng_uint16)(ALPHA) \
+ + (mng_uint16)(BG)*(mng_uint16)(255 - \
+ (mng_uint16)(ALPHA)) + (mng_uint16)128); \
+ (RET) = (mng_uint8)((iH + (iH >> 8)) >> 8); }
+
+#define MNG_COMPOSE16(RET,FG,ALPHA,BG) { \
+ mng_uint32 iH = (mng_uint32)((mng_uint32)(FG) * (mng_uint32)(ALPHA) \
+ + (mng_uint32)(BG)*(mng_uint32)(65535L - \
+ (mng_uint32)(ALPHA)) + (mng_uint32)32768L); \
+ (RET) = (mng_uint16)((iH + (iH >> 16)) >> 16); }
+
+/* ************************************************************************** */
+/* * * */
+/* * Alpha blending macros * */
+/* * this code is based on Adam Costello's "Note on Compositing" from the * */
+/* * mng-list which gives the following formula: * */
+/* * * */
+/* * top pixel = (Rt, Gt, Bt, At) * */
+/* * bottom pixel = (Rb, Gb, Bb, Ab) * */
+/* * composite pixel = (Rc, Gc, Bc, Ac) * */
+/* * * */
+/* * all values in the range 0..1 * */
+/* * * */
+/* * Ac = 1 - (1 - At)(1 - Ab) * */
+/* * s = At / Ac * */
+/* * t = (1 - At) Ab / Ac * */
+/* * Rc = s Rt + t Rb * */
+/* * Gc = s Gt + t Gb * */
+/* * Bc = s Bt + t Bb * */
+/* * * */
+/* * (I just hope I coded it correctly in integer arithmetic...) * */
+/* * * */
+/* ************************************************************************** */
+
+#define MNG_BLEND8(RT, GT, BT, AT, RB, GB, BB, AB, RC, GC, BC, AC) { \
+ mng_uint32 S, T; \
+ (AC) = (mng_uint8)((mng_uint32)255 - \
+ ((((mng_uint32)255 - (mng_uint32)(AT)) * \
+ ((mng_uint32)255 - (mng_uint32)(AB)) ) >> 8)); \
+ S = (mng_uint32)(((mng_uint32)(AT) << 8) / \
+ (mng_uint32)(AC)); \
+ T = (mng_uint32)(((mng_uint32)255 - (mng_uint32)(AT)) * \
+ (mng_uint32)(AB) / (mng_uint32)(AC)); \
+ (RC) = (mng_uint8)((S * (mng_uint32)(RT) + \
+ T * (mng_uint32)(RB) + (mng_uint32)127) >> 8); \
+ (GC) = (mng_uint8)((S * (mng_uint32)(GT) + \
+ T * (mng_uint32)(GB) + (mng_uint32)127) >> 8); \
+ (BC) = (mng_uint8)((S * (mng_uint32)(BT) + \
+ T * (mng_uint32)(BB) + (mng_uint32)127) >> 8); }
+
+#define MNG_BLEND16(RT, GT, BT, AT, RB, GB, BB, AB, RC, GC, BC, AC) { \
+ mng_uint32 S, T; \
+ (AC) = (mng_uint16)((mng_uint32)65535 - \
+ ((((mng_uint32)65535 - (mng_uint32)(AT)) * \
+ ((mng_uint32)65535 - (mng_uint32)(AB)) ) >> 16)); \
+ S = (mng_uint32)(((mng_uint32)(AT) << 16) / \
+ (mng_uint32)(AC)); \
+ T = (mng_uint32)(((mng_uint32)65535 - (mng_uint32)(AT)) * \
+ (mng_uint32)(AB) / (mng_uint32)(AC)); \
+ (RC) = (mng_uint16)((S * (mng_uint32)(RT) + \
+ T * (mng_uint32)(RB) + (mng_uint32)32767) >> 16); \
+ (GC) = (mng_uint16)((S * (mng_uint32)(GT) + \
+ T * (mng_uint32)(GB) + (mng_uint32)32767) >> 16); \
+ (BC) = (mng_uint16)((S * (mng_uint32)(BT) + \
+ T * (mng_uint32)(BB) + (mng_uint32)32767) >> 16); }
+
+/* ************************************************************************** */
+
+/* note a good optimizing compiler will optimize this */
+#define DIV255B8(x) (mng_uint8)(((x) + 127) / 255)
+#define DIV255B16(x) (mng_uint16)(((x) + 32767) / 65535)
+
+/* ************************************************************************** */
+/* * * */
+/* * Progressive display check - checks to see if progressive display is * */
+/* * in order & indicates so * */
+/* * * */
+/* * The routine is called after a call to one of the display_xxx routines * */
+/* * if appropriate * */
+/* * * */
+/* * The refresh is warrented in the read_chunk routine (mng_read.c) * */
+/* * and only during read&display processing, since there's not much point * */
+/* * doing it from memory! * */
+/* * * */
+/* ************************************************************************** */
+
+mng_retcode mng_display_progressive_check (mng_datap pData)
+{
+ if ((pData->bDoProgressive) && /* need progressive display? */
+ ((pData->eImagetype != mng_it_mng) || (pData->iDataheight > 300)) &&
+ (pData->iDestb - pData->iDestt > 50) && (!pData->pCurraniobj))
+ {
+ mng_int32 iC = pData->iRow + pData->iDestt - pData->iSourcet;
+
+ if (iC % 20 == 0) /* every 20th line */
+ pData->bNeedrefresh = MNG_TRUE;
+
+ }
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+/* * * */
+/* * Display routines - convert rowdata (which is already color-corrected) * */
+/* * to the output canvas, respecting the opacity information * */
+/* * * */
+/* ************************************************************************** */
+
+MNG_LOCAL void check_update_region (mng_datap pData)
+{ /* determine actual canvas row */
+ mng_int32 iRow = pData->iRow + pData->iDestt - pData->iSourcet;
+ /* check for change in update-region */
+ if ((pData->iDestl < (mng_int32)pData->iUpdateleft) || (pData->iUpdateright == 0))
+ pData->iUpdateleft = pData->iDestl;
+
+ if (pData->iDestr > (mng_int32)pData->iUpdateright)
+ pData->iUpdateright = pData->iDestr;
+
+ if ((iRow < (mng_int32)pData->iUpdatetop) || (pData->iUpdatebottom == 0))
+ pData->iUpdatetop = iRow;
+
+ if (iRow+1 > (mng_int32)pData->iUpdatebottom)
+ pData->iUpdatebottom = iRow+1;
+
+ return;
+}
+
+/* ************************************************************************** */
+
+#ifndef MNG_SKIPCANVAS_RGB8
+#ifndef MNG_NO_16BIT_SUPPORT
+#ifndef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
+mng_retcode mng_display_rgb8 (mng_datap pData)
+{
+ mng_uint8p pScanline;
+ mng_uint8p pDataline;
+ mng_int32 iX;
+ mng_uint16 iA16;
+ mng_uint16 iFGr16, iFGg16, iFGb16;
+ mng_uint16 iBGr16, iBGg16, iBGb16;
+ mng_uint8 iA8;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_RGB8, MNG_LC_START);
+#endif
+ /* viewable row ? */
+ if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
+ { /* address destination row */
+ pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ /* adjust destination row starting-point */
+ pScanline = pScanline + (pData->iCol * 3) + (pData->iDestl * 3);
+ pDataline = pData->pRGBArow; /* address source row */
+
+ if (pData->bIsRGBA16) /* adjust source row starting-point */
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 3);
+ else
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
+
+ if (pData->bIsOpaque) /* forget about transparency ? */
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* scale down by dropping the LSB */
+ *pScanline = *pDataline;
+ *(pScanline+1) = *(pDataline+2);
+ *(pScanline+2) = *(pDataline+4);
+
+ pScanline += (pData->iColinc * 3);
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* copy the values */
+ *pScanline = *pDataline;
+ *(pScanline+1) = *(pDataline+1);
+ *(pScanline+2) = *(pDataline+2);
+
+ pScanline += (pData->iColinc * 3);
+ pDataline += 4;
+ }
+ }
+ }
+ else
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ {
+ iA16 = mng_get_uint16 (pDataline+6);
+
+ if (iA16) /* any opacity at all ? */
+ {
+ if (iA16 == 0xFFFF) /* fully opaque ? */
+ { /* scale down by dropping the LSB */
+ *pScanline = *pDataline;
+ *(pScanline+1) = *(pDataline+2);
+ *(pScanline+2) = *(pDataline+4);
+ }
+ else
+ { /* get the proper values */
+ iFGr16 = mng_get_uint16 (pDataline );
+ iFGg16 = mng_get_uint16 (pDataline+2);
+ iFGb16 = mng_get_uint16 (pDataline+4);
+ /* scale background up */
+ iBGr16 = (mng_uint16)(*pScanline );
+ iBGg16 = (mng_uint16)(*(pScanline+1));
+ iBGb16 = (mng_uint16)(*(pScanline+2));
+ iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
+ iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
+ iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
+ /* now compose */
+ MNG_COMPOSE16(iFGr16, iFGr16, iA16, iBGr16);
+ MNG_COMPOSE16(iFGg16, iFGg16, iA16, iBGg16);
+ MNG_COMPOSE16(iFGb16, iFGb16, iA16, iBGb16);
+ /* and return the composed values */
+ *pScanline = (mng_uint8)(iFGr16 >> 8);
+ *(pScanline+1) = (mng_uint8)(iFGg16 >> 8);
+ *(pScanline+2) = (mng_uint8)(iFGb16 >> 8);
+ }
+ }
+
+ pScanline += (pData->iColinc * 3);
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ {
+ iA8 = *(pDataline+3); /* get alpha value */
+
+ if (iA8) /* any opacity at all ? */
+ {
+ if (iA8 == 0xFF) /* fully opaque ? */
+ { /* then simply copy the values */
+ *pScanline = *pDataline;
+ *(pScanline+1) = *(pDataline+1);
+ *(pScanline+2) = *(pDataline+2);
+ }
+ else
+ { /* do alpha composing */
+ MNG_COMPOSE8 (*pScanline, *pDataline, iA8, *pScanline );
+ MNG_COMPOSE8 (*(pScanline+1), *(pDataline+1), iA8, *(pScanline+1));
+ MNG_COMPOSE8 (*(pScanline+2), *(pDataline+2), iA8, *(pScanline+2));
+ }
+ }
+
+ pScanline += (pData->iColinc * 3);
+ pDataline += 4;
+ }
+ }
+ }
+ }
+
+ check_update_region (pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_RGB8, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#else /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
+mng_retcode mng_display_rgb8 (mng_datap pData)
+{
+ mng_uint8p pScanline;
+ mng_uint8p pDataline;
+ mng_int32 iX;
+ mng_uint16 iA16;
+ mng_uint16 iFGg16;
+ mng_uint16 iBGg16;
+ mng_uint8 iA8;
+ mng_uint8 iBps;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_RGB8, MNG_LC_START);
+#endif
+
+ iBps=(mng_uint8)(pData->bIsRGBA16 ? 2:1);
+ /* viewable row ? */
+ if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
+ { /* address destination row */
+ pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ /* adjust destination row starting-point */
+ pScanline = pScanline + (pData->iCol * 3) + (pData->iDestl * 3);
+ pDataline = pData->pRGBArow; /* address source row */
+
+ /* adjust source row starting-point */
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << (iBps+1));
+
+ if (pData->bIsOpaque) /* forget about transparency ? */
+ {
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* scale down by dropping the LSB */
+ *pScanline = *pDataline;
+ *(pScanline+1) = *(pDataline+iBps);
+ *(pScanline+2) = *(pDataline+2*iBps);
+
+ pScanline += (pData->iColinc * 3);
+ pDataline += 4*iBps;
+ }
+ }
+ }
+ else
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ {
+ iA16 = mng_get_uint16 (pDataline+6);
+
+ if (iA16) /* any opacity at all ? */
+ {
+ if (iA16 == 0xFFFF) /* fully opaque ? */
+ { /* scale down by dropping the LSB */
+ *pScanline = *pDataline;
+ *(pScanline+1) = *(pDataline+2);
+ *(pScanline+2) = *(pDataline+4);
+ }
+ else
+ { /* get the proper values */
+ int i;
+ for (i=2; i >= 0; i--)
+ {
+ iFGg16 = mng_get_uint16 (pDataline+i+i);
+ /* scale background up */
+ iBGg16 = (mng_uint16)(*(pScanline+i));
+ iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
+ /* now compose */
+ MNG_COMPOSE16(iFGg16, iFGg16, iA16, iBGg16);
+ /* and return the composed values */
+ *(pScanline+i) = (mng_uint8)(iFGg16 >> 8);
+ }
+ }
+ }
+
+ pScanline += (pData->iColinc * 3);
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ {
+ iA8 = *(pDataline+3); /* get alpha value */
+
+ if (iA8) /* any opacity at all ? */
+ {
+ if (iA8 == 0xFF) /* fully opaque ? */
+ { /* then simply copy the values */
+ *pScanline = *pDataline;
+ *(pScanline+1) = *(pDataline+1);
+ *(pScanline+2) = *(pDataline+2);
+ }
+ else
+ { /* do alpha composing */
+ int i;
+ for (i=2; i >= 0; i--)
+ {
+ MNG_COMPOSE8 (*(pScanline+i), *(pDataline+i), iA8, *(pScanline+i));
+ }
+ }
+ }
+
+ pScanline += (pData->iColinc * 3);
+ pDataline += 4;
+ }
+ }
+ }
+ }
+
+ check_update_region (pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_RGB8, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
+#else /* MNG_NO_16BIT_SUPPORT */
+mng_retcode mng_display_rgb8 (mng_datap pData)
+{
+ mng_uint8p pScanline;
+ mng_uint8p pDataline;
+ mng_int32 iX;
+ mng_uint8 iA8;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_RGB8, MNG_LC_START);
+#endif
+ /* viewable row ? */
+ if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
+ { /* address destination row */
+ pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ /* adjust destination row starting-point */
+ pScanline = pScanline + (pData->iCol * 3) + (pData->iDestl * 3);
+ pDataline = pData->pRGBArow; /* address source row */
+
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
+
+ if (pData->bIsOpaque) /* forget about transparency ? */
+ {
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* copy the values */
+ *pScanline = *pDataline;
+ *(pScanline+1) = *(pDataline+1);
+ *(pScanline+2) = *(pDataline+2);
+
+ pScanline += (pData->iColinc * 3);
+ pDataline += 4;
+ }
+ }
+ }
+ else
+ {
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ {
+ iA8 = *(pDataline+3); /* get alpha value */
+
+ if (iA8) /* any opacity at all ? */
+ {
+ if (iA8 == 0xFF) /* fully opaque ? */
+ { /* then simply copy the values */
+ *pScanline = *pDataline;
+ *(pScanline+1) = *(pDataline+1);
+ *(pScanline+2) = *(pDataline+2);
+ }
+ else
+ { /* do alpha composing */
+#ifdef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
+ int i;
+ for (i=2; i >= 0; i--)
+ {
+ MNG_COMPOSE8 (*(pScanline+i), *(pDataline+i), iA8, *(pScanline+i));
+ }
+#else
+ MNG_COMPOSE8 (*pScanline, *pDataline, iA8, *pScanline );
+ MNG_COMPOSE8 (*(pScanline+1), *(pDataline+1), iA8, *(pScanline+1));
+ MNG_COMPOSE8 (*(pScanline+2), *(pDataline+2), iA8, *(pScanline+2));
+#endif
+ }
+ }
+
+ pScanline += (pData->iColinc * 3);
+ pDataline += 4;
+ }
+ }
+ }
+ }
+
+ check_update_region (pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_RGB8, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_NO_16BIT_SUPPORT */
+#endif /* MNG_SKIPCANVAS_RGB8 */
+
+/* ************************************************************************** */
+
+#ifndef MNG_SKIPCANVAS_RGBA8
+#ifndef MNG_NO_16BIT_SUPPORT
+#ifndef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
+mng_retcode mng_display_rgba8 (mng_datap pData)
+{
+ mng_uint8p pScanline;
+ mng_uint8p pDataline;
+ mng_int32 iX;
+ mng_uint8 iFGa8, iBGa8, iCa8;
+ mng_uint16 iFGa16, iBGa16, iCa16;
+ mng_uint16 iFGr16, iFGg16, iFGb16;
+ mng_uint16 iBGr16, iBGg16, iBGb16;
+ mng_uint16 iCr16, iCg16, iCb16;
+ mng_uint8 iCr8, iCg8, iCb8;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_RGBA8, MNG_LC_START);
+#endif
+ /* viewable row ? */
+ if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
+ { /* address destination row */
+ pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ /* adjust destination row starting-point */
+ pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
+ pDataline = pData->pRGBArow; /* address source row */
+
+ if (pData->bIsRGBA16) /* adjust source row starting-point */
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 3);
+ else
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
+
+ if (pData->bIsOpaque) /* forget about transparency ? */
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* scale down by dropping the LSB */
+ *pScanline = *pDataline;
+ *(pScanline+1) = *(pDataline+2);
+ *(pScanline+2) = *(pDataline+4);
+ *(pScanline+3) = *(pDataline+6);
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* copy the values */
+ *pScanline = *pDataline;
+ *(pScanline+1) = *(pDataline+1);
+ *(pScanline+2) = *(pDataline+2);
+ *(pScanline+3) = *(pDataline+3);
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 4;
+ }
+ }
+ }
+ else
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* get alpha values */
+ iFGa16 = mng_get_uint16 (pDataline+6);
+ iBGa16 = (mng_uint16)(*(pScanline+3));
+ iBGa16 = (mng_uint16)(iBGa16 << 8) | iBGa16;
+
+ if (iFGa16) /* any opacity at all ? */
+ { /* fully opaque or background fully transparent ? */
+ if ((iFGa16 == 0xFFFF) || (iBGa16 == 0))
+ { /* plain copy it */
+ *pScanline = *pDataline;
+ *(pScanline+1) = *(pDataline+2);
+ *(pScanline+2) = *(pDataline+4);
+ *(pScanline+3) = *(pDataline+6);
+ }
+ else
+ {
+ if (iBGa16 == 0xFFFF) /* background fully opaque ? */
+ { /* get the proper values */
+ iFGr16 = mng_get_uint16 (pDataline );
+ iFGg16 = mng_get_uint16 (pDataline+2);
+ iFGb16 = mng_get_uint16 (pDataline+4);
+ /* scale background up */
+ iBGr16 = (mng_uint16)(*pScanline );
+ iBGg16 = (mng_uint16)(*(pScanline+1));
+ iBGb16 = (mng_uint16)(*(pScanline+2));
+ iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
+ iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
+ iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
+ /* now compose */
+ MNG_COMPOSE16(iFGr16, iFGr16, iFGa16, iBGr16);
+ MNG_COMPOSE16(iFGg16, iFGg16, iFGa16, iBGg16);
+ MNG_COMPOSE16(iFGb16, iFGb16, iFGa16, iBGb16);
+ /* and return the composed values */
+ *pScanline = (mng_uint8)(iFGr16 >> 8);
+ *(pScanline+1) = (mng_uint8)(iFGg16 >> 8);
+ *(pScanline+2) = (mng_uint8)(iFGb16 >> 8);
+ /* alpha remains fully opaque !!! */
+ }
+ else
+ { /* scale background up */
+ iBGr16 = (mng_uint16)(*pScanline );
+ iBGg16 = (mng_uint16)(*(pScanline+1));
+ iBGb16 = (mng_uint16)(*(pScanline+2));
+ iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
+ iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
+ iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
+ /* let's blend */
+ MNG_BLEND16 (mng_get_uint16 (pDataline ),
+ mng_get_uint16 (pDataline+2),
+ mng_get_uint16 (pDataline+4), iFGa16,
+ iBGr16, iBGg16, iBGb16, iBGa16,
+ iCr16, iCg16, iCb16, iCa16);
+ /* and return the composed values */
+ *pScanline = (mng_uint8)(iCr16 >> 8);
+ *(pScanline+1) = (mng_uint8)(iCg16 >> 8);
+ *(pScanline+2) = (mng_uint8)(iCb16 >> 8);
+ *(pScanline+3) = (mng_uint8)(iCa16 >> 8);
+ }
+ }
+ }
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ {
+ iFGa8 = *(pDataline+3); /* get alpha values */
+ iBGa8 = *(pScanline+3);
+
+ if (iFGa8) /* any opacity at all ? */
+ { /* fully opaque or background fully transparent ? */
+ if ((iFGa8 == 0xFF) || (iBGa8 == 0))
+ { /* then simply copy the values */
+ *pScanline = *pDataline;
+ *(pScanline+1) = *(pDataline+1);
+ *(pScanline+2) = *(pDataline+2);
+ *(pScanline+3) = *(pDataline+3);
+ }
+ else
+ {
+ if (iBGa8 == 0xFF) /* background fully opaque ? */
+ { /* do alpha composing */
+ MNG_COMPOSE8 (*pScanline, *pDataline, iFGa8, *pScanline );
+ MNG_COMPOSE8 (*(pScanline+1), *(pDataline+1), iFGa8, *(pScanline+1));
+ MNG_COMPOSE8 (*(pScanline+2), *(pDataline+2), iFGa8, *(pScanline+2));
+ /* alpha remains fully opaque !!! */
+ }
+ else
+ { /* now blend */
+ MNG_BLEND8 (*pDataline, *(pDataline+1), *(pDataline+2), iFGa8,
+ *pScanline, *(pScanline+1), *(pScanline+2), iBGa8,
+ iCr8, iCg8, iCb8, iCa8);
+ /* and return the composed values */
+ *pScanline = iCr8;
+ *(pScanline+1) = iCg8;
+ *(pScanline+2) = iCb8;
+ *(pScanline+3) = iCa8;
+ }
+ }
+ }
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 4;
+ }
+ }
+ }
+ }
+
+ check_update_region (pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_RGBA8, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#else /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
+mng_retcode mng_display_rgba8 (mng_datap pData)
+{
+ mng_uint8p pScanline;
+ mng_uint8p pDataline;
+ mng_int32 iX;
+ mng_uint8 iFGa8, iBGa8, iCa8;
+ mng_uint16 iFGa16, iBGa16, iCa16;
+ mng_uint16 iFGg16;
+ mng_uint16 iBGr16, iBGg16, iBGb16;
+ mng_uint16 iCr16, iCg16, iCb16;
+ mng_uint8 iCr8, iCg8, iCb8;
+ mng_uint8 iBps;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_RGBA8, MNG_LC_START);
+#endif
+
+ iBps=(mng_uint8)(pData->bIsRGBA16 ? 2:1);
+ /* viewable row ? */
+ if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
+ { /* address destination row */
+ pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ /* adjust destination row starting-point */
+ pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
+ pDataline = pData->pRGBArow; /* address source row */
+
+ /* adjust source row starting-point */
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << (iBps+1));
+
+ if (pData->bIsOpaque) /* forget about transparency ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* scale down by dropping the LSB */
+ *pScanline = *pDataline;
+ *(pScanline+1) = *(pDataline+iBps);
+ *(pScanline+2) = *(pDataline+2*iBps);
+ *(pScanline+3) = *(pDataline+3*iBps);
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 4*iBps;
+ }
+ }
+ else
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* get alpha values */
+ iFGa16 = mng_get_uint16 (pDataline+6);
+ iBGa16 = (mng_uint16)(*(pScanline+3));
+ iBGa16 = (mng_uint16)(iBGa16 << 8) | iBGa16;
+
+ if (iFGa16) /* any opacity at all ? */
+ { /* fully opaque or background fully transparent ? */
+ if ((iFGa16 == 0xFFFF) || (iBGa16 == 0))
+ { /* plain copy it */
+ *pScanline = *pDataline;
+ *(pScanline+1) = *(pDataline+2);
+ *(pScanline+2) = *(pDataline+4);
+ *(pScanline+3) = *(pDataline+6);
+ }
+ else
+ {
+ if (iBGa16 == 0xFFFF) /* background fully opaque ? */
+ { /* get the proper values */
+ int i;
+ for (i=2; i >= 0; i--)
+ {
+ iFGg16 = mng_get_uint16 (pDataline+i+i);
+ /* scale background up */
+ iBGg16 = (mng_uint16)(*(pScanline+i));
+ iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
+ /* now compose */
+ MNG_COMPOSE16(iFGg16, iFGg16, iFGa16, iBGg16);
+ /* and return the composed values */
+ *(pScanline+i) = (mng_uint8)(iFGg16 >> 8);
+ /* alpha remains fully opaque !!! */
+ }
+ }
+ else
+ { /* scale background up */
+ iBGr16 = (mng_uint16)(*pScanline );
+ iBGg16 = (mng_uint16)(*(pScanline+1));
+ iBGb16 = (mng_uint16)(*(pScanline+2));
+ iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
+ iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
+ iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
+ /* let's blend */
+ MNG_BLEND16 (mng_get_uint16 (pDataline ),
+ mng_get_uint16 (pDataline+2),
+ mng_get_uint16 (pDataline+4), iFGa16,
+ iBGr16, iBGg16, iBGb16, iBGa16,
+ iCr16, iCg16, iCb16, iCa16);
+ /* and return the composed values */
+ *pScanline = (mng_uint8)(iCr16 >> 8);
+ *(pScanline+1) = (mng_uint8)(iCg16 >> 8);
+ *(pScanline+2) = (mng_uint8)(iCb16 >> 8);
+ *(pScanline+3) = (mng_uint8)(iCa16 >> 8);
+ }
+ }
+ }
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ {
+ iFGa8 = *(pDataline+3); /* get alpha values */
+ iBGa8 = *(pScanline+3);
+
+ if (iFGa8) /* any opacity at all ? */
+ { /* fully opaque or background fully transparent ? */
+ if ((iFGa8 == 0xFF) || (iBGa8 == 0))
+ { /* then simply copy the values */
+ *pScanline = *pDataline;
+ *(pScanline+1) = *(pDataline+1);
+ *(pScanline+2) = *(pDataline+2);
+ *(pScanline+3) = *(pDataline+3);
+ }
+ else
+ {
+ if (iBGa8 == 0xFF) /* background fully opaque ? */
+ { /* do alpha composing */
+ int i;
+ for (i=2; i >= 0; i--)
+ {
+ MNG_COMPOSE8 (*(pScanline+i), *(pDataline+i), iFGa8, *(pScanline+i));
+ }
+ /* alpha remains fully opaque !!! */
+ }
+ else
+ { /* now blend */
+ MNG_BLEND8 (*pDataline, *(pDataline+1), *(pDataline+2), iFGa8,
+ *pScanline, *(pScanline+1), *(pScanline+2), iBGa8,
+ iCr8, iCg8, iCb8, iCa8);
+ /* and return the composed values */
+ *pScanline = iCr8;
+ *(pScanline+1) = iCg8;
+ *(pScanline+2) = iCb8;
+ *(pScanline+3) = iCa8;
+ }
+ }
+ }
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 4;
+ }
+ }
+ }
+ }
+
+ check_update_region (pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_RGBA8, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
+#else /* MNG_NO_16BIT_SUPPORT */
+mng_retcode mng_display_rgba8 (mng_datap pData)
+{
+ mng_uint8p pScanline;
+ mng_uint8p pDataline;
+ mng_int32 iX;
+ mng_uint8 iFGa8, iBGa8, iCa8;
+ mng_uint8 iCr8, iCg8, iCb8;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_RGBA8, MNG_LC_START);
+#endif
+ /* viewable row ? */
+ if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
+ { /* address destination row */
+ pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ /* adjust destination row starting-point */
+ pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
+ pDataline = pData->pRGBArow; /* address source row */
+
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
+
+ if (pData->bIsOpaque) /* forget about transparency ? */
+ {
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* copy the values */
+ *pScanline = *pDataline;
+ *(pScanline+1) = *(pDataline+1);
+ *(pScanline+2) = *(pDataline+2);
+ *(pScanline+3) = *(pDataline+3);
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 4;
+ }
+ }
+ }
+ else
+ {
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ {
+ iFGa8 = *(pDataline+3); /* get alpha values */
+ iBGa8 = *(pScanline+3);
+
+ if (iFGa8) /* any opacity at all ? */
+ { /* fully opaque or background fully transparent ? */
+ if ((iFGa8 == 0xFF) || (iBGa8 == 0))
+ { /* then simply copy the values */
+ *pScanline = *pDataline;
+ *(pScanline+1) = *(pDataline+1);
+ *(pScanline+2) = *(pDataline+2);
+ *(pScanline+3) = *(pDataline+3);
+ }
+ else
+ {
+ if (iBGa8 == 0xFF) /* background fully opaque ? */
+ { /* do alpha composing */
+#ifdef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
+ int i;
+ for (i=2; i >= 0; i--)
+ {
+ MNG_COMPOSE8 (*(pScanline+i), *(pDataline+i), iFGa8, *(pScanline+i));
+ }
+#else
+ MNG_COMPOSE8 (*pScanline, *pDataline, iFGa8, *pScanline );
+ MNG_COMPOSE8 (*(pScanline+1), *(pDataline+1), iFGa8, *(pScanline+1));
+ MNG_COMPOSE8 (*(pScanline+2), *(pDataline+2), iFGa8, *(pScanline+2));
+#endif
+ /* alpha remains fully opaque !!! */
+ }
+ else
+ { /* now blend */
+ MNG_BLEND8 (*pDataline, *(pDataline+1), *(pDataline+2), iFGa8,
+ *pScanline, *(pScanline+1), *(pScanline+2), iBGa8,
+ iCr8, iCg8, iCb8, iCa8);
+ /* and return the composed values */
+ *pScanline = iCr8;
+ *(pScanline+1) = iCg8;
+ *(pScanline+2) = iCb8;
+ *(pScanline+3) = iCa8;
+ }
+ }
+ }
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 4;
+ }
+ }
+ }
+ }
+
+ check_update_region (pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_RGBA8, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_NO_16BIT_SUPPORT */
+#endif /* MNG_SKIPCANVAS_RGBA8 */
+
+/* ************************************************************************** */
+
+#ifndef MNG_SKIPCANVAS_RGBA8_PM
+#ifndef MNG_NO_16BIT_SUPPORT
+#ifndef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
+mng_retcode mng_display_rgba8_pm (mng_datap pData)
+{
+ mng_uint8p pScanline;
+ mng_uint8p pDataline;
+ mng_int32 iX;
+ mng_uint32 s, t;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_RGBA8_PM, MNG_LC_START);
+#endif
+ /* viewable row ? */
+ if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
+ { /* address destination row */
+ pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ /* adjust destination row starting-point */
+ pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
+ pDataline = pData->pRGBArow; /* address source row */
+
+ if (pData->bIsRGBA16) /* adjust source row starting-point */
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 3);
+ else
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
+
+ if (pData->bIsOpaque) /* forget about transparency ? */
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* scale down by dropping the LSB */
+ if ((s = pDataline[6]) == 0)
+ *(mng_uint32*) pScanline = 0; /* set all components = 0 */
+ else
+ {
+ if (s == 255)
+ {
+ pScanline[0] = pDataline[0];
+ pScanline[1] = pDataline[2];
+ pScanline[2] = pDataline[4];
+ pScanline[3] = 255;
+ }
+ else
+ {
+#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
+ int i;
+ for (i=2; i >= 0; i--)
+ {
+ pScanline[2-i] = DIV255B8(s * pDataline[4-i-i]);
+ }
+#else
+ pScanline[0] = DIV255B8(s * pDataline[0]);
+ pScanline[1] = DIV255B8(s * pDataline[2]);
+ pScanline[2] = DIV255B8(s * pDataline[4]);
+#endif
+ pScanline[3] = (mng_uint8)s;
+ }
+ }
+ pScanline += (pData->iColinc << 2);
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* copy the values and premultiply */
+ if ((s = pDataline[3]) == 0)
+ *(mng_uint32*) pScanline = 0; /* set all components = 0 */
+ else
+ {
+ if (s == 255)
+ {
+#ifdef MNG_BIGENDIAN_SUPPORTED
+ *(mng_uint32*)pScanline = (*(mng_uint32*)pDataline) | 0x000000FF;
+#else
+ pScanline[0] = pDataline[0];
+ pScanline[1] = pDataline[1];
+ pScanline[2] = pDataline[2];
+ pScanline[3] = 255;
+#endif
+ }
+ else
+ {
+#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
+ int i;
+ for (i=2; i >= 0; i--)
+ {
+ pScanline[2-i] = DIV255B8(s * pDataline[2-i]);
+ }
+#else
+ pScanline[0] = DIV255B8(s * pDataline[0]);
+ pScanline[1] = DIV255B8(s * pDataline[1]);
+ pScanline[2] = DIV255B8(s * pDataline[2]);
+#endif
+ pScanline[3] = (mng_uint8)s;
+ }
+ }
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 4;
+ }
+ }
+ }
+ else
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* get alpha values */
+ if ((s = pDataline[6]) != 0) /* any opacity at all ? */
+ { /* fully opaque or background fully transparent ? */
+ if (s == 255)
+ { /* plain copy it */
+ pScanline[0] = pDataline[0];
+ pScanline[1] = pDataline[2];
+ pScanline[2] = pDataline[4];
+ pScanline[3] = 255;
+ }
+ else
+ { /* now blend (premultiplied) */
+ t = 255 - s;
+#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
+ {
+ int i;
+ for (i=2; i >= 0; i--)
+ {
+ pScanline[2-i] = DIV255B8(s * pDataline[4-i-i] + t *
+ pScanline[2-i]);
+ }
+ }
+#else
+ pScanline[0] = DIV255B8(s * pDataline[0] + t * pScanline[0]);
+ pScanline[1] = DIV255B8(s * pDataline[2] + t * pScanline[1]);
+ pScanline[2] = DIV255B8(s * pDataline[4] + t * pScanline[2]);
+#endif
+ pScanline[3] = (mng_uint8)(255 - DIV255B8(t * (255 - pScanline[3])));
+ }
+ }
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ {
+ if ((s = pDataline[3]) != 0) /* any opacity at all ? */
+ { /* fully opaque ? */
+ if (s == 255)
+ { /* then simply copy the values */
+#ifdef MNG_BIGENDIAN_SUPPORTED
+ *(mng_uint32*)pScanline = (*(mng_uint32*)pDataline) | 0x000000FF;
+#else
+ pScanline[0] = pDataline[0];
+ pScanline[1] = pDataline[1];
+ pScanline[2] = pDataline[2];
+ pScanline[3] = 255;
+#endif
+ }
+ else
+ { /* now blend (premultiplied) */
+ t = 255 - s;
+#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
+ {
+ int i;
+ for (i=2; i >= 0; i--)
+ {
+ pScanline[2-i] = DIV255B8(s * pDataline[2-i] + t *
+ pScanline[2-i]);
+ }
+ }
+#else
+ pScanline[0] = DIV255B8(s * pDataline[0] + t * pScanline[0]);
+ pScanline[1] = DIV255B8(s * pDataline[1] + t * pScanline[1]);
+ pScanline[2] = DIV255B8(s * pDataline[2] + t * pScanline[2]);
+#endif
+ pScanline[3] = (mng_uint8)(255 - DIV255B8(t * (255 - pScanline[3])));
+ }
+ }
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 4;
+ }
+ }
+ }
+ }
+
+ check_update_region (pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_RGBA8_PM, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#else /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
+mng_retcode mng_display_rgba8_pm (mng_datap pData)
+{
+ mng_uint8p pScanline;
+ mng_uint8p pDataline;
+ mng_int32 iX;
+ mng_uint32 s, t;
+ mng_uint8 iBps;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_RGBA8_PM, MNG_LC_START);
+#endif
+
+ iBps=(mng_uint8)(pData->bIsRGBA16 ? 2:1);
+ /* viewable row ? */
+ if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
+ { /* address destination row */
+ pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ /* adjust destination row starting-point */
+ pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
+ pDataline = pData->pRGBArow; /* address source row */
+
+ /* adjust source row starting-point */
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << (iBps+1));
+
+ if (pData->bIsOpaque) /* forget about transparency ? */
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* scale down by dropping the LSB */
+ if ((s = pDataline[6]) == 0)
+ *(mng_uint32*) pScanline = 0; /* set all components = 0 */
+ else
+ {
+ if (s == 255)
+ {
+ pScanline[0] = pDataline[0];
+ pScanline[1] = pDataline[2];
+ pScanline[2] = pDataline[4];
+ pScanline[3] = 255;
+ }
+ else
+ {
+#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
+ int i;
+ for (i=2; i >= 0; i--)
+ {
+ pScanline[2-i] = DIV255B8(s * pDataline[4-i-i]);
+ }
+#else
+ pScanline[0] = DIV255B8(s * pDataline[0]);
+ pScanline[1] = DIV255B8(s * pDataline[2]);
+ pScanline[2] = DIV255B8(s * pDataline[4]);
+#endif
+ pScanline[3] = (mng_uint8)s;
+ }
+ }
+ pScanline += (pData->iColinc << 2);
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* copy the values and premultiply */
+ if ((s = pDataline[3]) == 0)
+ *(mng_uint32*) pScanline = 0; /* set all components = 0 */
+ else
+ {
+ if (s == 255)
+ {
+#ifdef MNG_BIGENDIAN_SUPPORTED
+ *(mng_uint32*)pScanline = (*(mng_uint32*)pDataline) | 0x000000FF;
+#else
+ pScanline[0] = pDataline[0];
+ pScanline[1] = pDataline[1];
+ pScanline[2] = pDataline[2];
+ pScanline[3] = 255;
+#endif
+ }
+ else
+ {
+#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
+ int i;
+ for (i=2; i >= 0; i--)
+ {
+ pScanline[2-i] = DIV255B8(s * pDataline[2-i]);
+ }
+#else
+ pScanline[0] = DIV255B8(s * pDataline[0]);
+ pScanline[1] = DIV255B8(s * pDataline[1]);
+ pScanline[2] = DIV255B8(s * pDataline[2]);
+#endif
+ pScanline[3] = (mng_uint8)s;
+ }
+ }
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 4;
+ }
+ }
+ }
+ else
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* get alpha values */
+ if ((s = pDataline[6]) != 0) /* any opacity at all ? */
+ { /* fully opaque or background fully transparent ? */
+ if (s == 255)
+ { /* plain copy it */
+ pScanline[0] = pDataline[0];
+ pScanline[1] = pDataline[2];
+ pScanline[2] = pDataline[4];
+ pScanline[3] = 255;
+ }
+ else
+ { /* now blend (premultiplied) */
+ t = 255 - s;
+#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
+ {
+ int i;
+ for (i=2; i >= 0; i--)
+ {
+ pScanline[2-i] = DIV255B8(s * pDataline[4-i-i] + t *
+ pScanline[2-i]);
+ }
+ }
+#else
+ pScanline[0] = DIV255B8(s * pDataline[0] + t * pScanline[0]);
+ pScanline[1] = DIV255B8(s * pDataline[2] + t * pScanline[1]);
+ pScanline[2] = DIV255B8(s * pDataline[4] + t * pScanline[2]);
+#endif
+ pScanline[3] = (mng_uint8)(255 - DIV255B8(t * (255 - pScanline[3])));
+ }
+ }
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ {
+ if ((s = pDataline[3]) != 0) /* any opacity at all ? */
+ { /* fully opaque ? */
+ if (s == 255)
+ { /* then simply copy the values */
+#ifdef MNG_BIGENDIAN_SUPPORTED
+ *(mng_uint32*)pScanline = (*(mng_uint32*)pDataline) | 0x000000FF;
+#else
+ pScanline[0] = pDataline[0];
+ pScanline[1] = pDataline[1];
+ pScanline[2] = pDataline[2];
+ pScanline[3] = 255;
+#endif
+ }
+ else
+ { /* now blend (premultiplied) */
+ t = 255 - s;
+#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
+ {
+ int i;
+ for (i=2; i >= 0; i--)
+ {
+ pScanline[2-i] = DIV255B8(s * pDataline[2-i] + t *
+ pScanline[2-i]);
+ }
+ }
+#else
+ pScanline[0] = DIV255B8(s * pDataline[0] + t * pScanline[0]);
+ pScanline[1] = DIV255B8(s * pDataline[1] + t * pScanline[1]);
+ pScanline[2] = DIV255B8(s * pDataline[2] + t * pScanline[2]);
+#endif
+ pScanline[3] = (mng_uint8)(255 - DIV255B8(t * (255 - pScanline[3])));
+ }
+ }
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 4;
+ }
+ }
+ }
+ }
+
+ check_update_region (pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_RGBA8_PM, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
+#else /* MNG_NO_16BIT_SUPPORT */
+mng_retcode mng_display_rgba8_pm (mng_datap pData)
+{
+ mng_uint8p pScanline;
+ mng_uint8p pDataline;
+ mng_int32 iX;
+ mng_uint32 s, t;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_RGBA8_PM, MNG_LC_START);
+#endif
+ /* viewable row ? */
+ if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
+ { /* address destination row */
+ pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ /* adjust destination row starting-point */
+ pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
+ pDataline = pData->pRGBArow; /* address source row */
+
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
+
+ if (pData->bIsOpaque) /* forget about transparency ? */
+ {
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* copy the values and premultiply */
+ if ((s = pDataline[3]) == 0)
+ *(mng_uint32*) pScanline = 0; /* set all components = 0 */
+ else
+ {
+ if (s == 255)
+ {
+#ifdef MNG_BIGENDIAN_SUPPORTED
+ *(mng_uint32*)pScanline = (*(mng_uint32*)pDataline) | 0x000000FF;
+#else
+ pScanline[0] = pDataline[0];
+ pScanline[1] = pDataline[1];
+ pScanline[2] = pDataline[2];
+ pScanline[3] = 255;
+#endif
+ }
+ else
+ {
+#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
+ int i;
+ for (i=2; i >= 0; i--)
+ {
+ pScanline[2-i] = DIV255B8(s * pDataline[2-i]);
+ }
+#else
+ pScanline[0] = DIV255B8(s * pDataline[0]);
+ pScanline[1] = DIV255B8(s * pDataline[1]);
+ pScanline[2] = DIV255B8(s * pDataline[2]);
+#endif
+ pScanline[3] = (mng_uint8)s;
+ }
+ }
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 4;
+ }
+ }
+ }
+ else
+ {
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ {
+ if ((s = pDataline[3]) != 0) /* any opacity at all ? */
+ { /* fully opaque ? */
+ if (s == 255)
+ { /* then simply copy the values */
+#ifdef MNG_BIGENDIAN_SUPPORTED
+ *(mng_uint32*)pScanline = (*(mng_uint32*)pDataline) | 0x000000FF;
+#else
+ pScanline[0] = pDataline[0];
+ pScanline[1] = pDataline[1];
+ pScanline[2] = pDataline[2];
+ pScanline[3] = 255;
+#endif
+ }
+ else
+ { /* now blend (premultiplied) */
+ t = 255 - s;
+#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
+ {
+ int i;
+ for (i=2; i >= 0; i--)
+ {
+ pScanline[2-i] = DIV255B8(s * pDataline[2-i] + t *
+ pScanline[2-i]);
+ }
+ }
+#else
+ pScanline[0] = DIV255B8(s * pDataline[0] + t * pScanline[0]);
+ pScanline[1] = DIV255B8(s * pDataline[1] + t * pScanline[1]);
+ pScanline[2] = DIV255B8(s * pDataline[2] + t * pScanline[2]);
+#endif
+ pScanline[3] = (mng_uint8)(255 - DIV255B8(t * (255 - pScanline[3])));
+ }
+ }
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 4;
+ }
+ }
+ }
+ }
+
+ check_update_region (pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_RGBA8_PM, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_NO_16BIT_SUPPORT */
+#endif /* MNG_SKIPCANVAS_RGBA8_PM */
+
+/* ************************************************************************** */
+
+#ifndef MNG_SKIPCANVAS_ARGB8
+#ifndef MNG_NO_16BIT_SUPPORT
+#ifndef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
+mng_retcode mng_display_argb8 (mng_datap pData)
+{
+ mng_uint8p pScanline;
+ mng_uint8p pDataline;
+ mng_int32 iX;
+ mng_uint8 iFGa8, iBGa8, iCa8;
+ mng_uint16 iFGa16, iBGa16, iCa16;
+ mng_uint16 iFGr16, iFGg16, iFGb16;
+ mng_uint16 iBGr16, iBGg16, iBGb16;
+ mng_uint16 iCr16, iCg16, iCb16;
+ mng_uint8 iCr8, iCg8, iCb8;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_ARGB8, MNG_LC_START);
+#endif
+
+ /* viewable row ? */
+ if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
+ { /* address destination row */
+ pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ /* adjust destination row starting-point */
+ pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
+ pDataline = pData->pRGBArow; /* address source row */
+
+ if (pData->bIsRGBA16) /* adjust source row starting-point */
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 3);
+ else
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
+
+ if (pData->bIsOpaque) /* forget about transparency ? */
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* scale down by dropping the LSB */
+ *pScanline = *(pDataline+6);
+ *(pScanline+1) = *pDataline;
+ *(pScanline+2) = *(pDataline+2);
+ *(pScanline+3) = *(pDataline+4);
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* copy the values */
+ *pScanline = *(pDataline+3);
+ *(pScanline+1) = *pDataline;
+ *(pScanline+2) = *(pDataline+1);
+ *(pScanline+3) = *(pDataline+2);
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 4;
+ }
+ }
+ }
+ else
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* get alpha values */
+ iFGa16 = mng_get_uint16 (pDataline+6);
+ iBGa16 = (mng_uint16)(*pScanline);
+ iBGa16 = (mng_uint16)(iBGa16 << 8) | iBGa16;
+
+ if (iFGa16) /* any opacity at all ? */
+ { /* fully opaque or background fully transparent ? */
+ if ((iFGa16 == 0xFFFF) || (iBGa16 == 0))
+ { /* plain copy it */
+ *pScanline = *(pDataline+6);
+ *(pScanline+1) = *pDataline;
+ *(pScanline+2) = *(pDataline+2);
+ *(pScanline+3) = *(pDataline+4);
+ }
+ else
+ {
+ if (iBGa16 == 0xFFFF) /* background fully opaque ? */
+ { /* get the proper values */
+ iFGr16 = mng_get_uint16 (pDataline );
+ iFGg16 = mng_get_uint16 (pDataline+2);
+ iFGb16 = mng_get_uint16 (pDataline+4);
+ /* scale background up */
+ iBGr16 = (mng_uint16)(*(pScanline+1));
+ iBGg16 = (mng_uint16)(*(pScanline+2));
+ iBGb16 = (mng_uint16)(*(pScanline+3));
+ iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
+ iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
+ iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
+ /* now compose */
+ MNG_COMPOSE16(iFGr16, iFGr16, iFGa16, iBGr16);
+ MNG_COMPOSE16(iFGg16, iFGg16, iFGa16, iBGg16);
+ MNG_COMPOSE16(iFGb16, iFGb16, iFGa16, iBGb16);
+ /* and return the composed values */
+ /* alpha remains fully opaque !!! */
+ *(pScanline+1) = (mng_uint8)(iFGr16 >> 8);
+ *(pScanline+2) = (mng_uint8)(iFGg16 >> 8);
+ *(pScanline+3) = (mng_uint8)(iFGb16 >> 8);
+ }
+ else
+ { /* scale background up */
+ iBGr16 = (mng_uint16)(*(pScanline+1));
+ iBGg16 = (mng_uint16)(*(pScanline+2));
+ iBGb16 = (mng_uint16)(*(pScanline+3));
+ iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
+ iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
+ iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
+ /* let's blend */
+ MNG_BLEND16 (mng_get_uint16 (pDataline ),
+ mng_get_uint16 (pDataline+2),
+ mng_get_uint16 (pDataline+4), iFGa16,
+ iBGr16, iBGg16, iBGb16, iBGa16,
+ iCr16, iCg16, iCb16, iCa16);
+ /* and return the composed values */
+ *pScanline = (mng_uint8)(iCa16 >> 8);
+ *(pScanline+1) = (mng_uint8)(iCr16 >> 8);
+ *(pScanline+2) = (mng_uint8)(iCg16 >> 8);
+ *(pScanline+3) = (mng_uint8)(iCb16 >> 8);
+ }
+ }
+ }
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ {
+ iFGa8 = *(pDataline+3); /* get alpha values */
+ iBGa8 = *pScanline;
+
+ if (iFGa8) /* any opacity at all ? */
+ { /* fully opaque or background fully transparent ? */
+ if ((iFGa8 == 0xFF) || (iBGa8 == 0))
+ { /* then simply copy the values */
+ *pScanline = *(pDataline+3);
+ *(pScanline+1) = *pDataline;
+ *(pScanline+2) = *(pDataline+1);
+ *(pScanline+3) = *(pDataline+2);
+ }
+ else
+ {
+ if (iBGa8 == 0xFF) /* background fully opaque ? */
+ { /* do simple alpha composing */
+ /* alpha itself remains fully opaque !!! */
+ }
+ else
+ { /* now blend */
+ MNG_BLEND8 (*pDataline, *(pDataline+1), *(pDataline+2), iFGa8,
+ *(pScanline+1), *(pScanline+2), *(pScanline+3), iBGa8,
+ iCr8, iCg8, iCb8, iCa8);
+ /* and return the composed values */
+ *pScanline = iCa8;
+ *(pScanline+1) = iCr8;
+ *(pScanline+2) = iCg8;
+ *(pScanline+3) = iCb8;
+ }
+ }
+ }
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 4;
+ }
+ }
+ }
+ }
+
+ check_update_region (pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_ARGB8, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#else /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
+mng_retcode mng_display_argb8 (mng_datap pData)
+{
+ mng_uint8p pScanline;
+ mng_uint8p pDataline;
+ mng_int32 iX;
+ mng_uint8 iFGa8, iBGa8, iCa8;
+ mng_uint16 iFGa16, iBGa16, iCa16;
+ mng_uint16 iFGg16;
+ mng_uint16 iBGr16, iBGg16, iBGb16;
+ mng_uint16 iCr16, iCg16, iCb16;
+ mng_uint8 iCr8, iCg8, iCb8;
+ mng_uint8 iBps;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_ARGB8, MNG_LC_START);
+#endif
+
+ iBps=(mng_uint8)(pData->bIsRGBA16 ? 2:1);
+ /* viewable row ? */
+ if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
+ { /* address destination row */
+ pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ /* adjust destination row starting-point */
+ pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
+ pDataline = pData->pRGBArow; /* address source row */
+
+ /* adjust source row starting-point */
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << (iBps+1));
+
+ if (pData->bIsOpaque) /* forget about transparency ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* scale down by dropping the LSB */
+ *pScanline = *(pDataline+3*iBps);
+ *(pScanline+1) = *pDataline;
+ *(pScanline+2) = *(pDataline+iBps);
+ *(pScanline+3) = *(pDataline+2*iBps);
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 4*iBps;
+ }
+ }
+ else
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* get alpha values */
+ iFGa16 = mng_get_uint16 (pDataline+6);
+ iBGa16 = (mng_uint16)(*pScanline);
+ iBGa16 = (mng_uint16)(iBGa16 << 8) | iBGa16;
+
+ if (iFGa16) /* any opacity at all ? */
+ { /* fully opaque or background fully transparent ? */
+ if ((iFGa16 == 0xFFFF) || (iBGa16 == 0))
+ { /* plain copy it */
+ *pScanline = *(pDataline+6);
+ *(pScanline+1) = *pDataline;
+ *(pScanline+2) = *(pDataline+2);
+ *(pScanline+3) = *(pDataline+4);
+ }
+ else
+ {
+ if (iBGa16 == 0xFFFF) /* background fully opaque ? */
+ { /* get the proper values */
+ int i;
+ for (i=2; i >= 0; i--)
+ {
+ iFGg16 = mng_get_uint16 (pDataline+i+i);
+ /* scale background up */
+ iBGg16 = (mng_uint16)(*(pScanline+i+1));
+ iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
+ /* now compose */
+ MNG_COMPOSE16(iFGg16, iFGg16, iFGa16, iBGg16);
+ /* and return the composed values */
+ /* alpha remains fully opaque !!! */
+ *(pScanline+i+1) = (mng_uint8)(iFGg16 >> 8);
+ }
+ }
+ else
+ { /* scale background up */
+ iBGr16 = (mng_uint16)(*(pScanline+1));
+ iBGg16 = (mng_uint16)(*(pScanline+2));
+ iBGb16 = (mng_uint16)(*(pScanline+3));
+ iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
+ iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
+ iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
+ /* let's blend */
+ MNG_BLEND16 (mng_get_uint16 (pDataline ),
+ mng_get_uint16 (pDataline+2),
+ mng_get_uint16 (pDataline+4), iFGa16,
+ iBGr16, iBGg16, iBGb16, iBGa16,
+ iCr16, iCg16, iCb16, iCa16);
+ /* and return the composed values */
+ *pScanline = (mng_uint8)(iCa16 >> 8);
+ *(pScanline+1) = (mng_uint8)(iCr16 >> 8);
+ *(pScanline+2) = (mng_uint8)(iCg16 >> 8);
+ *(pScanline+3) = (mng_uint8)(iCb16 >> 8);
+ }
+ }
+ }
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ {
+ iFGa8 = *(pDataline+3); /* get alpha values */
+ iBGa8 = *pScanline;
+
+ if (iFGa8) /* any opacity at all ? */
+ { /* fully opaque or background fully transparent ? */
+ if ((iFGa8 == 0xFF) || (iBGa8 == 0))
+ { /* then simply copy the values */
+ *pScanline = *(pDataline+3);
+ *(pScanline+1) = *pDataline;
+ *(pScanline+2) = *(pDataline+1);
+ *(pScanline+3) = *(pDataline+2);
+ }
+ else
+ {
+ if (iBGa8 == 0xFF) /* background fully opaque ? */
+ { /* do simple alpha composing */
+ /* alpha itself remains fully opaque !!! */
+ int i;
+ for (i=2; i >= 0; i--)
+ {
+ MNG_COMPOSE8 (*(pScanline+i+1), *(pDataline+i), iFGa8, *(pScanline+i+1));
+ }
+ }
+ else
+ { /* now blend */
+ MNG_BLEND8 (*pDataline, *(pDataline+1), *(pDataline+2), iFGa8,
+ *(pScanline+1), *(pScanline+2), *(pScanline+3), iBGa8,
+ iCr8, iCg8, iCb8, iCa8);
+ /* and return the composed values */
+ *pScanline = iCa8;
+ *(pScanline+1) = iCr8;
+ *(pScanline+2) = iCg8;
+ *(pScanline+3) = iCb8;
+ }
+ }
+ }
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 4;
+ }
+ }
+ }
+ }
+
+ check_update_region (pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_ARGB8, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
+#else /* MNG_NO_16BIT_SUPPORT */
+mng_retcode mng_display_argb8 (mng_datap pData)
+{
+ mng_uint8p pScanline;
+ mng_uint8p pDataline;
+ mng_int32 iX;
+ mng_uint8 iFGa8, iBGa8, iCa8;
+ mng_uint8 iCr8, iCg8, iCb8;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_ARGB8, MNG_LC_START);
+#endif
+
+ /* viewable row ? */
+ if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
+ { /* address destination row */
+ pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ /* adjust destination row starting-point */
+ pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
+ pDataline = pData->pRGBArow; /* address source row */
+
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
+
+ if (pData->bIsOpaque) /* forget about transparency ? */
+ {
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* copy the values */
+ *pScanline = *(pDataline+3);
+ *(pScanline+1) = *pDataline;
+ *(pScanline+2) = *(pDataline+1);
+ *(pScanline+3) = *(pDataline+2);
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 4;
+ }
+ }
+ }
+ else
+ {
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ {
+ iFGa8 = *(pDataline+3); /* get alpha values */
+ iBGa8 = *pScanline;
+
+ if (iFGa8) /* any opacity at all ? */
+ { /* fully opaque or background fully transparent ? */
+ if ((iFGa8 == 0xFF) || (iBGa8 == 0))
+ { /* then simply copy the values */
+ *pScanline = *(pDataline+3);
+ *(pScanline+1) = *pDataline;
+ *(pScanline+2) = *(pDataline+1);
+ *(pScanline+3) = *(pDataline+2);
+ }
+ else
+ {
+ if (iBGa8 == 0xFF) /* background fully opaque ? */
+ { /* do simple alpha composing */
+ /* alpha itself remains fully opaque !!! */
+#ifdef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
+ int i;
+ for (i=2; i >= 0; i--)
+ {
+ MNG_COMPOSE8 (*(pScanline+i+1), *(pDataline+i), iFGa8, *(pScanline+i+1));
+ }
+#else
+ MNG_COMPOSE8 (*(pScanline+1), *pDataline, iFGa8, *(pScanline+1));
+ MNG_COMPOSE8 (*(pScanline+2), *(pDataline+1), iFGa8, *(pScanline+2));
+ MNG_COMPOSE8 (*(pScanline+3), *(pDataline+2), iFGa8, *(pScanline+3));
+#endif
+ }
+ else
+ { /* now blend */
+ MNG_BLEND8 (*pDataline, *(pDataline+1), *(pDataline+2), iFGa8,
+ *(pScanline+1), *(pScanline+2), *(pScanline+3), iBGa8,
+ iCr8, iCg8, iCb8, iCa8);
+ /* and return the composed values */
+ *pScanline = iCa8;
+ *(pScanline+1) = iCr8;
+ *(pScanline+2) = iCg8;
+ *(pScanline+3) = iCb8;
+ }
+ }
+ }
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 4;
+ }
+ }
+ }
+ }
+
+ check_update_region (pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_ARGB8, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_NO_16BIT_SUPPORT */
+#endif /* MNG_SKIPCANVAS_ARGB8 */
+
+/* ************************************************************************** */
+
+#ifndef MNG_SKIPCANVAS_ARGB8_PM
+#ifndef MNG_NO_16BIT_SUPPORT
+#ifndef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
+mng_retcode mng_display_argb8_pm (mng_datap pData)
+{
+ mng_uint8p pScanline;
+ mng_uint8p pDataline;
+ mng_int32 iX;
+ mng_uint32 s, t;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_ARGB8_PM, MNG_LC_START);
+#endif
+ /* viewable row ? */
+ if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
+ { /* address destination row */
+ pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ /* adjust destination row starting-point */
+ pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
+ pDataline = pData->pRGBArow; /* address source row */
+
+ if (pData->bIsRGBA16) /* adjust source row starting-point */
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 3);
+ else
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
+
+ if (pData->bIsOpaque) /* forget about transparency ? */
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* scale down by dropping the LSB */
+ if ((s = pDataline[6]) == 0)
+ *(mng_uint32*) pScanline = 0; /* set all components = 0 */
+ else
+ {
+ if (s == 255)
+ {
+ pScanline[0] = 255;
+ pScanline[1] = pDataline[0];
+ pScanline[2] = pDataline[2];
+ pScanline[3] = pDataline[4];
+ }
+ else
+ {
+ pScanline[0] = (mng_uint8)s;
+#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
+ {
+ int i;
+ for (i=2; i >= 0; i--)
+ {
+ pScanline[3-i] = DIV255B8(s * pDataline[4-i-i]);
+ }
+ }
+#else
+ pScanline[1] = DIV255B8(s * pDataline[0]);
+ pScanline[2] = DIV255B8(s * pDataline[2]);
+ pScanline[3] = DIV255B8(s * pDataline[4]);
+#endif
+ }
+ }
+ pScanline += (pData->iColinc << 2);
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* copy the values and premultiply */
+ if ((s = pDataline[3]) == 0)
+ *(mng_uint32*) pScanline = 0; /* set all components = 0 */
+ else
+ {
+ if (s == 255)
+ {
+ pScanline[0] = 255;
+ pScanline[1] = pDataline[0];
+ pScanline[2] = pDataline[1];
+ pScanline[3] = pDataline[2];
+ }
+ else
+ {
+ pScanline[0] = (mng_uint8)s;
+#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
+ {
+ int i;
+ for (i=2; i >= 0; i--)
+ {
+ pScanline[3-i] = DIV255B8(s * pDataline[2-i]);
+ }
+ }
+#else
+ pScanline[1] = DIV255B8(s * pDataline[0]);
+ pScanline[2] = DIV255B8(s * pDataline[1]);
+ pScanline[3] = DIV255B8(s * pDataline[2]);
+#endif
+ }
+ }
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 4;
+ }
+ }
+ }
+ else
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* get alpha values */
+ if ((s = pDataline[6]) != 0) /* any opacity at all ? */
+ { /* fully opaque or background fully transparent ? */
+ if (s == 255)
+ { /* plain copy it */
+ pScanline[0] = 255;
+ pScanline[1] = pDataline[0];
+ pScanline[2] = pDataline[2];
+ pScanline[3] = pDataline[4];
+ }
+ else
+ { /* now blend (premultiplied) */
+ t = 255 - s;
+ pScanline[0] = (mng_uint8)(255 - DIV255B8(t * (255 - pScanline[0])));
+#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
+ {
+ int i;
+ for (i=2; i >= 0; i--)
+ {
+ pScanline[3-i] = DIV255B8(s * pDataline[4-i-i] + t *
+ pScanline[3-i]);
+ }
+ }
+#else
+ pScanline[1] = DIV255B8(s * pDataline[0] + t * pScanline[1]);
+ pScanline[2] = DIV255B8(s * pDataline[2] + t * pScanline[2]);
+ pScanline[3] = DIV255B8(s * pDataline[4] + t * pScanline[3]);
+#endif
+ }
+ }
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ {
+ if ((s = pDataline[3]) != 0) /* any opacity at all ? */
+ { /* fully opaque ? */
+ if (s == 255)
+ { /* then simply copy the values */
+ pScanline[0] = 255;
+ pScanline[1] = pDataline[0];
+ pScanline[2] = pDataline[1];
+ pScanline[3] = pDataline[2];
+ }
+ else
+ { /* now blend (premultiplied) */
+ t = 255 - s;
+ pScanline[0] = (mng_uint8)(255 - DIV255B8(t * (255 - pScanline[0])));
+#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
+ {
+ int i;
+ for (i=2; i >= 0; i--)
+ {
+ pScanline[3-i] = DIV255B8(s * pDataline[2-i] + t *
+ pScanline[3-i]);
+ }
+ }
+#else
+ pScanline[1] = DIV255B8(s * pDataline[0] + t * pScanline[1]);
+ pScanline[2] = DIV255B8(s * pDataline[1] + t * pScanline[2]);
+ pScanline[3] = DIV255B8(s * pDataline[2] + t * pScanline[3]);
+#endif
+ }
+ }
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 4;
+ }
+ }
+ }
+ }
+
+ check_update_region (pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_ARGB8_PM, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#else /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
+mng_retcode mng_display_argb8_pm (mng_datap pData)
+{
+ mng_uint8p pScanline;
+ mng_uint8p pDataline;
+ mng_int32 iX;
+ mng_uint32 s, t;
+ mng_uint8 iBps;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_ARGB8_PM, MNG_LC_START);
+#endif
+
+ iBps=(mng_uint8)(pData->bIsRGBA16 ? 2:1);
+ /* viewable row ? */
+ if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
+ { /* address destination row */
+ pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ /* adjust destination row starting-point */
+ pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
+ pDataline = pData->pRGBArow; /* address source row */
+
+ /* adjust source row starting-point */
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << (iBps+1));
+
+ if (pData->bIsOpaque) /* forget about transparency ? */
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* scale down by dropping the LSB */
+ if ((s = pDataline[6]) == 0)
+ *(mng_uint32*) pScanline = 0; /* set all components = 0 */
+ else
+ {
+ if (s == 255)
+ {
+ pScanline[0] = 255;
+ pScanline[1] = pDataline[0];
+ pScanline[2] = pDataline[2];
+ pScanline[3] = pDataline[4];
+ }
+ else
+ {
+ pScanline[0] = (mng_uint8)s;
+#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
+ {
+ int i;
+ for (i=2; i >= 0; i--)
+ {
+ pScanline[3-i] = DIV255B8(s * pDataline[4-i-i]);
+ }
+ }
+#else
+ pScanline[1] = DIV255B8(s * pDataline[0]);
+ pScanline[2] = DIV255B8(s * pDataline[2]);
+ pScanline[3] = DIV255B8(s * pDataline[4]);
+#endif
+ }
+ }
+ pScanline += (pData->iColinc << 2);
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* copy the values and premultiply */
+ if ((s = pDataline[3]) == 0)
+ *(mng_uint32*) pScanline = 0; /* set all components = 0 */
+ else
+ {
+ if (s == 255)
+ {
+ pScanline[0] = 255;
+ pScanline[1] = pDataline[0];
+ pScanline[2] = pDataline[1];
+ pScanline[3] = pDataline[2];
+ }
+ else
+ {
+ pScanline[0] = (mng_uint8)s;
+#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
+ {
+ int i;
+ for (i=2; i >= 0; i--)
+ {
+ pScanline[3-i] = DIV255B8(s * pDataline[2-i]);
+ }
+ }
+#else
+ pScanline[1] = DIV255B8(s * pDataline[0]);
+ pScanline[2] = DIV255B8(s * pDataline[1]);
+ pScanline[3] = DIV255B8(s * pDataline[2]);
+#endif
+ }
+ }
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 4;
+ }
+ }
+ }
+ else
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* get alpha values */
+ if ((s = pDataline[6]) != 0) /* any opacity at all ? */
+ { /* fully opaque or background fully transparent ? */
+ if (s == 255)
+ { /* plain copy it */
+ pScanline[0] = 255;
+ pScanline[1] = pDataline[0];
+ pScanline[2] = pDataline[2];
+ pScanline[3] = pDataline[4];
+ }
+ else
+ { /* now blend (premultiplied) */
+ t = 255 - s;
+ pScanline[0] = (mng_uint8)(255 - DIV255B8(t * (255 - pScanline[0])));
+#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
+ {
+ int i;
+ for (i=2; i >= 0; i--)
+ {
+ pScanline[3-i] = DIV255B8(s * pDataline[4-i-i] + t *
+ pScanline[3-i]);
+ }
+ }
+#else
+ pScanline[1] = DIV255B8(s * pDataline[0] + t * pScanline[1]);
+ pScanline[2] = DIV255B8(s * pDataline[2] + t * pScanline[2]);
+ pScanline[3] = DIV255B8(s * pDataline[4] + t * pScanline[3]);
+#endif
+ }
+ }
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ {
+ if ((s = pDataline[3]) != 0) /* any opacity at all ? */
+ { /* fully opaque ? */
+ if (s == 255)
+ { /* then simply copy the values */
+ pScanline[0] = 255;
+ pScanline[1] = pDataline[0];
+ pScanline[2] = pDataline[1];
+ pScanline[3] = pDataline[2];
+ }
+ else
+ { /* now blend (premultiplied) */
+ t = 255 - s;
+ pScanline[0] = (mng_uint8)(255 - DIV255B8(t * (255 - pScanline[0])));
+#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
+ {
+ int i;
+ for (i=2; i >= 0; i--)
+ {
+ pScanline[3-i] = DIV255B8(s * pDataline[2-i] + t *
+ pScanline[3-i]);
+ }
+ }
+#else
+ pScanline[1] = DIV255B8(s * pDataline[0] + t * pScanline[1]);
+ pScanline[2] = DIV255B8(s * pDataline[1] + t * pScanline[2]);
+ pScanline[3] = DIV255B8(s * pDataline[2] + t * pScanline[3]);
+#endif
+ }
+ }
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 4;
+ }
+ }
+ }
+ }
+
+ check_update_region (pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_ARGB8_PM, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
+#else /* MNG_NO_16BIT_SUPPORT */
+mng_retcode mng_display_argb8_pm (mng_datap pData)
+{
+ mng_uint8p pScanline;
+ mng_uint8p pDataline;
+ mng_int32 iX;
+ mng_uint32 s, t;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_ARGB8_PM, MNG_LC_START);
+#endif
+ /* viewable row ? */
+ if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
+ { /* address destination row */
+ pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ /* adjust destination row starting-point */
+ pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
+ pDataline = pData->pRGBArow; /* address source row */
+
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
+
+ if (pData->bIsOpaque) /* forget about transparency ? */
+ {
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* copy the values and premultiply */
+ if ((s = pDataline[3]) == 0)
+ *(mng_uint32*) pScanline = 0; /* set all components = 0 */
+ else
+ {
+ if (s == 255)
+ {
+ pScanline[0] = 255;
+ pScanline[1] = pDataline[0];
+ pScanline[2] = pDataline[1];
+ pScanline[3] = pDataline[2];
+ }
+ else
+ {
+ pScanline[0] = (mng_uint8)s;
+#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
+ {
+ int i;
+ for (i=2; i >= 0; i--)
+ {
+ pScanline[3-i] = DIV255B8(s * pDataline[2-i]);
+ }
+ }
+#else
+ pScanline[1] = DIV255B8(s * pDataline[0]);
+ pScanline[2] = DIV255B8(s * pDataline[1]);
+ pScanline[3] = DIV255B8(s * pDataline[2]);
+#endif
+ }
+ }
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 4;
+ }
+ }
+ }
+ else
+ {
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ {
+ if ((s = pDataline[3]) != 0) /* any opacity at all ? */
+ { /* fully opaque ? */
+ if (s == 255)
+ { /* then simply copy the values */
+ pScanline[0] = 255;
+ pScanline[1] = pDataline[0];
+ pScanline[2] = pDataline[1];
+ pScanline[3] = pDataline[2];
+ }
+ else
+ { /* now blend (premultiplied) */
+ t = 255 - s;
+ pScanline[0] = (mng_uint8)(255 - DIV255B8(t * (255 - pScanline[0])));
+#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
+ {
+ int i;
+ for (i=2; i >= 0; i--)
+ {
+ pScanline[3-i] = DIV255B8(s * pDataline[2-i] + t *
+ pScanline[3-i]);
+ }
+ }
+#else
+ pScanline[1] = DIV255B8(s * pDataline[0] + t * pScanline[1]);
+ pScanline[2] = DIV255B8(s * pDataline[1] + t * pScanline[2]);
+ pScanline[3] = DIV255B8(s * pDataline[2] + t * pScanline[3]);
+#endif
+ }
+ }
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 4;
+ }
+ }
+ }
+ }
+
+ check_update_region (pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_ARGB8_PM, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_NO_16BIT_SUPPORT */
+#endif /* MNG_SKIPCANVAS_ARGB8_PM */
+
+/* ************************************************************************** */
+
+#ifndef MNG_SKIPCANVAS_RGB8_A8
+#ifndef MNG_NO_16BIT_SUPPORT
+#ifndef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
+mng_retcode mng_display_rgb8_a8 (mng_datap pData)
+{
+ mng_uint8p pScanline;
+ mng_uint8p pAlphaline;
+ mng_uint8p pDataline;
+ mng_int32 iX;
+ mng_uint8 iFGa8, iBGa8, iCa8;
+ mng_uint16 iFGa16, iBGa16, iCa16;
+ mng_uint16 iFGr16, iFGg16, iFGb16;
+ mng_uint16 iBGr16, iBGg16, iBGb16;
+ mng_uint16 iCr16, iCg16, iCb16;
+ mng_uint8 iCr8, iCg8, iCb8;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_RGB8_A8, MNG_LC_START);
+#endif
+ /* viewable row ? */
+ if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
+ { /* address destination rows */
+ pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ pAlphaline = (mng_uint8p)pData->fGetalphaline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ /* adjust destination rows starting-point */
+ pScanline = pScanline + (pData->iCol * 3) + (pData->iDestl * 3);
+ pAlphaline = pAlphaline + pData->iCol + pData->iDestl;
+
+ pDataline = pData->pRGBArow; /* address source row */
+
+ if (pData->bIsRGBA16) /* adjust source row starting-point */
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 3);
+ else
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
+
+ if (pData->bIsOpaque) /* forget about transparency ? */
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* scale down by dropping the LSB */
+ *pScanline = *pDataline;
+ *(pScanline+1) = *(pDataline+2);
+ *(pScanline+2) = *(pDataline+4);
+ *pAlphaline = *(pDataline+6);
+
+ pScanline += (pData->iColinc * 3);
+ pAlphaline += pData->iColinc;
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* copy the values */
+ *pScanline = *pDataline;
+ *(pScanline+1) = *(pDataline+1);
+ *(pScanline+2) = *(pDataline+2);
+ *pAlphaline = *(pDataline+3);
+
+ pScanline += (pData->iColinc * 3);
+ pAlphaline += pData->iColinc;
+ pDataline += 4;
+ }
+ }
+ }
+ else
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* get alpha values */
+ iFGa16 = mng_get_uint16 (pDataline+6);
+ iBGa16 = (mng_uint16)(*pAlphaline);
+ iBGa16 = (mng_uint16)(iBGa16 << 8) | iBGa16;
+
+ if (iFGa16) /* any opacity at all ? */
+ { /* fully opaque or background fully transparent ? */
+ if ((iFGa16 == 0xFFFF) || (iBGa16 == 0))
+ { /* plain copy it */
+ *pScanline = *pDataline;
+ *(pScanline+1) = *(pDataline+2);
+ *(pScanline+2) = *(pDataline+4);
+ *pAlphaline = *(pDataline+6);
+ }
+ else
+ {
+ if (iBGa16 == 0xFFFF) /* background fully opaque ? */
+ { /* get the proper values */
+ iFGr16 = mng_get_uint16 (pDataline );
+ iFGg16 = mng_get_uint16 (pDataline+2);
+ iFGb16 = mng_get_uint16 (pDataline+4);
+ /* scale background up */
+ iBGr16 = (mng_uint16)(*pScanline );
+ iBGg16 = (mng_uint16)(*(pScanline+1));
+ iBGb16 = (mng_uint16)(*(pScanline+2));
+ iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
+ iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
+ iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
+ /* now compose */
+ MNG_COMPOSE16(iFGr16, iFGr16, iFGa16, iBGr16);
+ MNG_COMPOSE16(iFGg16, iFGg16, iFGa16, iBGg16);
+ MNG_COMPOSE16(iFGb16, iFGb16, iFGa16, iBGb16);
+ /* and return the composed values */
+ *pScanline = (mng_uint8)(iFGr16 >> 8);
+ *(pScanline+1) = (mng_uint8)(iFGg16 >> 8);
+ *(pScanline+2) = (mng_uint8)(iFGb16 >> 8);
+ /* alpha remains fully opaque !!! */
+ }
+ else
+ { /* scale background up */
+ iBGr16 = (mng_uint16)(*pScanline );
+ iBGg16 = (mng_uint16)(*(pScanline+1));
+ iBGb16 = (mng_uint16)(*(pScanline+2));
+ iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
+ iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
+ iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
+ /* let's blend */
+ MNG_BLEND16 (mng_get_uint16 (pDataline ),
+ mng_get_uint16 (pDataline+2),
+ mng_get_uint16 (pDataline+4), iFGa16,
+ iBGr16, iBGg16, iBGb16, iBGa16,
+ iCr16, iCg16, iCb16, iCa16);
+ /* and return the composed values */
+ *pScanline = (mng_uint8)(iCr16 >> 8);
+ *(pScanline+1) = (mng_uint8)(iCg16 >> 8);
+ *(pScanline+2) = (mng_uint8)(iCb16 >> 8);
+ *pAlphaline = (mng_uint8)(iCa16 >> 8);
+ }
+ }
+ }
+
+ pScanline += (pData->iColinc * 3);
+ pAlphaline += pData->iColinc;
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ {
+ iFGa8 = *(pDataline+3); /* get alpha values */
+ iBGa8 = *pAlphaline;
+
+ if (iFGa8) /* any opacity at all ? */
+ { /* fully opaque or background fully transparent ? */
+ if ((iFGa8 == 0xFF) || (iBGa8 == 0))
+ { /* then simply copy the values */
+ *pScanline = *pDataline;
+ *(pScanline+1) = *(pDataline+1);
+ *(pScanline+2) = *(pDataline+2);
+ *pAlphaline = *(pDataline+3);
+ }
+ else
+ {
+ if (iBGa8 == 0xFF) /* background fully opaque ? */
+ { /* do alpha composing */
+ MNG_COMPOSE8 (*pScanline, *pDataline, iFGa8, *pScanline );
+ MNG_COMPOSE8 (*(pScanline+1), *(pDataline+1), iFGa8, *(pScanline+1));
+ MNG_COMPOSE8 (*(pScanline+2), *(pDataline+2), iFGa8, *(pScanline+2));
+ /* alpha remains fully opaque !!! */
+ }
+ else
+ { /* now blend */
+ MNG_BLEND8 (*pDataline, *(pDataline+1), *(pDataline+2), iFGa8,
+ *pScanline, *(pScanline+1), *(pScanline+2), iBGa8,
+ iCr8, iCg8, iCb8, iCa8);
+ /* and return the composed values */
+ *pScanline = iCr8;
+ *(pScanline+1) = iCg8;
+ *(pScanline+2) = iCb8;
+ *pAlphaline = iCa8;
+ }
+ }
+ }
+
+ pScanline += (pData->iColinc * 3);
+ pAlphaline += pData->iColinc;
+ pDataline += 4;
+ }
+ }
+ }
+ }
+
+ check_update_region (pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_RGB8_A8, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#else /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
+mng_retcode mng_display_rgb8_a8 (mng_datap pData)
+{
+ mng_uint8p pScanline;
+ mng_uint8p pAlphaline;
+ mng_uint8p pDataline;
+ mng_int32 iX;
+ mng_uint8 iFGa8, iBGa8, iCa8;
+ mng_uint16 iFGa16, iBGa16, iCa16;
+ mng_uint16 iFGg16;
+ mng_uint16 iBGr16, iBGg16, iBGb16;
+ mng_uint16 iCr16, iCg16, iCb16;
+ mng_uint8 iCr8, iCg8, iCb8;
+ mng_uint8 iBps;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_RGB8_A8, MNG_LC_START);
+#endif
+
+ iBps=(mng_uint8)(pData->bIsRGBA16 ? 2:1);
+ /* viewable row ? */
+ if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
+ { /* address destination rows */
+ pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ pAlphaline = (mng_uint8p)pData->fGetalphaline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ /* adjust destination rows starting-point */
+ pScanline = pScanline + (pData->iCol * 3) + (pData->iDestl * 3);
+ pAlphaline = pAlphaline + pData->iCol + pData->iDestl;
+
+ pDataline = pData->pRGBArow; /* address source row */
+
+ /* adjust source row starting-point */
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << (iBps+1));
+
+ if (pData->bIsOpaque) /* forget about transparency ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* scale down by dropping the LSB */
+ *pScanline = *pDataline;
+ *(pScanline+1) = *(pDataline+iBps);
+ *(pScanline+2) = *(pDataline+2*iBps);
+ *pAlphaline = *(pDataline+3*iBps);
+
+ pScanline += (pData->iColinc * 3);
+ pAlphaline += pData->iColinc;
+ pDataline += 4*iBps;
+ }
+ }
+ else
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* get alpha values */
+ iFGa16 = mng_get_uint16 (pDataline+6);
+ iBGa16 = (mng_uint16)(*pAlphaline);
+ iBGa16 = (mng_uint16)(iBGa16 << 8) | iBGa16;
+
+ if (iFGa16) /* any opacity at all ? */
+ { /* fully opaque or background fully transparent ? */
+ if ((iFGa16 == 0xFFFF) || (iBGa16 == 0))
+ { /* plain copy it */
+ *pScanline = *pDataline;
+ *(pScanline+1) = *(pDataline+2);
+ *(pScanline+2) = *(pDataline+4);
+ *pAlphaline = *(pDataline+6);
+ }
+ else
+ {
+ if (iBGa16 == 0xFFFF) /* background fully opaque ? */
+ { /* get the proper values */
+ int i;
+ for (i=2; i >= 0; i--)
+ {
+ iFGg16 = mng_get_uint16 (pDataline+i+i);
+ /* scale background up */
+ iBGg16 = (mng_uint16)(*(pScanline+i));
+ iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
+ /* now compose */
+ MNG_COMPOSE16(iFGg16, iFGg16, iFGa16, iBGg16);
+ /* and return the composed values */
+ *(pScanline+i) = (mng_uint8)(iFGg16 >> 8);
+ /* alpha remains fully opaque !!! */
+ }
+ }
+ else
+ { /* scale background up */
+ iBGr16 = (mng_uint16)(*pScanline );
+ iBGg16 = (mng_uint16)(*(pScanline+1));
+ iBGb16 = (mng_uint16)(*(pScanline+2));
+ iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
+ iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
+ iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
+ /* let's blend */
+ MNG_BLEND16 (mng_get_uint16 (pDataline ),
+ mng_get_uint16 (pDataline+2),
+ mng_get_uint16 (pDataline+4), iFGa16,
+ iBGr16, iBGg16, iBGb16, iBGa16,
+ iCr16, iCg16, iCb16, iCa16);
+ /* and return the composed values */
+ *pScanline = (mng_uint8)(iCr16 >> 8);
+ *(pScanline+1) = (mng_uint8)(iCg16 >> 8);
+ *(pScanline+2) = (mng_uint8)(iCb16 >> 8);
+ *pAlphaline = (mng_uint8)(iCa16 >> 8);
+ }
+ }
+ }
+
+ pScanline += (pData->iColinc * 3);
+ pAlphaline += pData->iColinc;
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ {
+ iFGa8 = *(pDataline+3); /* get alpha values */
+ iBGa8 = *pAlphaline;
+
+ if (iFGa8) /* any opacity at all ? */
+ { /* fully opaque or background fully transparent ? */
+ if ((iFGa8 == 0xFF) || (iBGa8 == 0))
+ { /* then simply copy the values */
+ *pScanline = *pDataline;
+ *(pScanline+1) = *(pDataline+1);
+ *(pScanline+2) = *(pDataline+2);
+ *pAlphaline = *(pDataline+3);
+ }
+ else
+ {
+ if (iBGa8 == 0xFF) /* background fully opaque ? */
+ { /* do alpha composing */
+ int i;
+ for (i=2; i >= 0; i--)
+ {
+ MNG_COMPOSE8 (*(pScanline+i), *(pDataline+i), iFGa8, *(pScanline+i));
+ }
+ /* alpha remains fully opaque !!! */
+ }
+ else
+ { /* now blend */
+ MNG_BLEND8 (*pDataline, *(pDataline+1), *(pDataline+2), iFGa8,
+ *pScanline, *(pScanline+1), *(pScanline+2), iBGa8,
+ iCr8, iCg8, iCb8, iCa8);
+ /* and return the composed values */
+ *pScanline = iCr8;
+ *(pScanline+1) = iCg8;
+ *(pScanline+2) = iCb8;
+ *pAlphaline = iCa8;
+ }
+ }
+ }
+
+ pScanline += (pData->iColinc * 3);
+ pAlphaline += pData->iColinc;
+ pDataline += 4;
+ }
+ }
+ }
+ }
+
+ check_update_region (pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_RGB8_A8, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
+#else /* MNG_NO_16BIT_SUPPORT */
+mng_retcode mng_display_rgb8_a8 (mng_datap pData)
+{
+ mng_uint8p pScanline;
+ mng_uint8p pAlphaline;
+ mng_uint8p pDataline;
+ mng_int32 iX;
+ mng_uint8 iFGa8, iBGa8, iCa8;
+ mng_uint8 iCr8, iCg8, iCb8;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_RGB8_A8, MNG_LC_START);
+#endif
+ /* viewable row ? */
+ if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
+ { /* address destination rows */
+ pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ pAlphaline = (mng_uint8p)pData->fGetalphaline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ /* adjust destination rows starting-point */
+ pScanline = pScanline + (pData->iCol * 3) + (pData->iDestl * 3);
+ pAlphaline = pAlphaline + pData->iCol + pData->iDestl;
+
+ pDataline = pData->pRGBArow; /* address source row */
+
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
+
+ if (pData->bIsOpaque) /* forget about transparency ? */
+ {
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* copy the values */
+ *pScanline = *pDataline;
+ *(pScanline+1) = *(pDataline+1);
+ *(pScanline+2) = *(pDataline+2);
+ *pAlphaline = *(pDataline+3);
+
+ pScanline += (pData->iColinc * 3);
+ pAlphaline += pData->iColinc;
+ pDataline += 4;
+ }
+ }
+ }
+ else
+ {
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ {
+ iFGa8 = *(pDataline+3); /* get alpha values */
+ iBGa8 = *pAlphaline;
+
+ if (iFGa8) /* any opacity at all ? */
+ { /* fully opaque or background fully transparent ? */
+ if ((iFGa8 == 0xFF) || (iBGa8 == 0))
+ { /* then simply copy the values */
+ *pScanline = *pDataline;
+ *(pScanline+1) = *(pDataline+1);
+ *(pScanline+2) = *(pDataline+2);
+ *pAlphaline = *(pDataline+3);
+ }
+ else
+ {
+ if (iBGa8 == 0xFF) /* background fully opaque ? */
+ { /* do alpha composing */
+#ifdef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
+ int i;
+ for (i=2; i >= 0; i--)
+ {
+ MNG_COMPOSE8 (*(pScanline+i), *(pDataline+i), iFGa8, *(pScanline+i));
+ }
+#else
+ MNG_COMPOSE8 (*pScanline, *pDataline, iFGa8, *pScanline );
+ MNG_COMPOSE8 (*(pScanline+1), *(pDataline+1), iFGa8, *(pScanline+1));
+ MNG_COMPOSE8 (*(pScanline+2), *(pDataline+2), iFGa8, *(pScanline+2));
+#endif
+ /* alpha remains fully opaque !!! */
+ }
+ else
+ { /* now blend */
+ MNG_BLEND8 (*pDataline, *(pDataline+1), *(pDataline+2), iFGa8,
+ *pScanline, *(pScanline+1), *(pScanline+2), iBGa8,
+ iCr8, iCg8, iCb8, iCa8);
+ /* and return the composed values */
+ *pScanline = iCr8;
+ *(pScanline+1) = iCg8;
+ *(pScanline+2) = iCb8;
+ *pAlphaline = iCa8;
+ }
+ }
+ }
+
+ pScanline += (pData->iColinc * 3);
+ pAlphaline += pData->iColinc;
+ pDataline += 4;
+ }
+ }
+ }
+ }
+
+ check_update_region (pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_RGB8_A8, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_NO_16BIT_SUPPORT */
+#endif /* MNG_SKIPCANVAS_RGB8_A8 */
+
+/* ************************************************************************** */
+
+#ifndef MNG_SKIPCANVAS_BGR8
+#ifndef MNG_NO_16BIT_SUPPORT
+#ifndef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
+mng_retcode mng_display_bgr8 (mng_datap pData)
+{
+ mng_uint8p pScanline;
+ mng_uint8p pDataline;
+ mng_int32 iX;
+ mng_uint16 iA16;
+ mng_uint16 iFGr16, iFGg16, iFGb16;
+ mng_uint16 iBGr16, iBGg16, iBGb16;
+ mng_uint8 iA8;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_BGR8, MNG_LC_START);
+#endif
+ /* viewable row ? */
+ if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
+ { /* address destination row */
+ pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ /* adjust destination row starting-point */
+ pScanline = pScanline + (pData->iCol * 3) + (pData->iDestl * 3);
+ pDataline = pData->pRGBArow; /* address source row */
+
+ if (pData->bIsRGBA16) /* adjust source row starting-point */
+ pDataline = pDataline + (pData->iSourcel / pData->iColinc) * 8;
+ else
+ pDataline = pDataline + (pData->iSourcel / pData->iColinc) * 4;
+
+ if (pData->bIsOpaque) /* forget about transparency ? */
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* scale down by dropping the LSB */
+ *pScanline = *(pDataline+4);
+ *(pScanline+1) = *(pDataline+2);
+ *(pScanline+2) = *pDataline;
+
+ pScanline += (pData->iColinc * 3);
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* copy the values */
+ *pScanline = *(pDataline+2);
+ *(pScanline+1) = *(pDataline+1);
+ *(pScanline+2) = *pDataline;
+
+ pScanline += (pData->iColinc * 3);
+ pDataline += 4;
+ }
+ }
+ }
+ else
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* get alpha value */
+ iA16 = mng_get_uint16 (pDataline+6);
+
+ if (iA16) /* any opacity at all ? */
+ {
+ if (iA16 == 0xFFFF) /* fully opaque ? */
+ { /* scale down by dropping the LSB */
+ *pScanline = *(pDataline+4);
+ *(pScanline+1) = *(pDataline+2);
+ *(pScanline+2) = *pDataline;
+ }
+ else
+ { /* get the proper values */
+ iFGr16 = mng_get_uint16 (pDataline );
+ iFGg16 = mng_get_uint16 (pDataline+2);
+ iFGb16 = mng_get_uint16 (pDataline+4);
+ /* scale background up */
+ iBGr16 = (mng_uint16)(*(pScanline+2));
+ iBGg16 = (mng_uint16)(*(pScanline+1));
+ iBGb16 = (mng_uint16)(*pScanline );
+ iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
+ iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
+ iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
+ /* now compose */
+ MNG_COMPOSE16(iFGr16, iFGr16, iA16, iBGr16);
+ MNG_COMPOSE16(iFGg16, iFGg16, iA16, iBGg16);
+ MNG_COMPOSE16(iFGb16, iFGb16, iA16, iBGb16);
+ /* and return the composed values */
+ *pScanline = (mng_uint8)(iFGb16 >> 8);
+ *(pScanline+1) = (mng_uint8)(iFGg16 >> 8);
+ *(pScanline+2) = (mng_uint8)(iFGr16 >> 8);
+ }
+ }
+
+ pScanline += (pData->iColinc * 3);
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ {
+ iA8 = *(pDataline+3); /* get alpha value */
+
+ if (iA8) /* any opacity at all ? */
+ {
+ if (iA8 == 0xFF) /* fully opaque ? */
+ { /* then simply copy the values */
+ *pScanline = *(pDataline+2);
+ *(pScanline+1) = *(pDataline+1);
+ *(pScanline+2) = *pDataline;
+ }
+ else
+ { /* do alpha composing */
+ MNG_COMPOSE8 (*pScanline, *(pDataline+2), iA8, *pScanline );
+ MNG_COMPOSE8 (*(pScanline+1), *(pDataline+1), iA8, *(pScanline+1));
+ MNG_COMPOSE8 (*(pScanline+2), *pDataline, iA8, *(pScanline+2));
+ }
+ }
+
+ pScanline += (pData->iColinc * 3);
+ pDataline += 4;
+ }
+ }
+ }
+ }
+
+ check_update_region (pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_BGR8, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#else /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
+mng_retcode mng_display_bgr8 (mng_datap pData)
+{
+ mng_uint8p pScanline;
+ mng_uint8p pDataline;
+ mng_int32 iX;
+ mng_uint16 iA16;
+ mng_uint16 iFGg16;
+ mng_uint16 iBGg16;
+ mng_uint8 iA8;
+ mng_uint8 iBps;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_BGR8, MNG_LC_START);
+#endif
+
+ iBps=(mng_uint8)(pData->bIsRGBA16 ? 2:1);
+ /* viewable row ? */
+ if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
+ { /* address destination row */
+ pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ /* adjust destination row starting-point */
+ pScanline = pScanline + (pData->iCol * 3) + (pData->iDestl * 3);
+ pDataline = pData->pRGBArow; /* address source row */
+
+ /* adjust source row starting-point */
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << (iBps+1));
+
+ if (pData->bIsOpaque) /* forget about transparency ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* scale down by dropping the LSB */
+ *pScanline = *(pDataline+2*iBps);
+ *(pScanline+1) = *(pDataline+iBps);
+ *(pScanline+2) = *pDataline;
+
+ pScanline += (pData->iColinc * 3);
+ pDataline += 4*iBps;
+ }
+ }
+ else
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* get alpha value */
+ iA16 = mng_get_uint16 (pDataline+6);
+
+ if (iA16) /* any opacity at all ? */
+ {
+ if (iA16 == 0xFFFF) /* fully opaque ? */
+ { /* scale down by dropping the LSB */
+ *pScanline = *(pDataline+4);
+ *(pScanline+1) = *(pDataline+2);
+ *(pScanline+2) = *pDataline;
+ }
+ else
+ { /* get the proper values */
+ int i;
+ for (i=2; i >= 0; i--)
+ {
+ iFGg16 = mng_get_uint16 (pDataline+i+i);
+ /* scale background up */
+ iBGg16 = (mng_uint16)(*(pScanline+2-i));
+ iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
+ /* now compose */
+ MNG_COMPOSE16(iFGg16, iFGg16, iA16, iBGg16);
+ /* and return the composed values */
+ *(pScanline+2-i) = (mng_uint8)(iFGg16 >> 8);
+ }
+ }
+ }
+
+ pScanline += (pData->iColinc * 3);
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ {
+ iA8 = *(pDataline+3); /* get alpha value */
+
+ if (iA8) /* any opacity at all ? */
+ {
+ if (iA8 == 0xFF) /* fully opaque ? */
+ { /* then simply copy the values */
+ *pScanline = *(pDataline+2);
+ *(pScanline+1) = *(pDataline+1);
+ *(pScanline+2) = *pDataline;
+ }
+ else
+ { /* do alpha composing */
+ int i;
+ for (i=2; i >= 0; i--)
+ {
+ MNG_COMPOSE8 (*(pScanline+i), *(pDataline+2-i), iA8, *(pScanline+i));
+ }
+ }
+ }
+
+ pScanline += (pData->iColinc * 3);
+ pDataline += 4;
+ }
+ }
+ }
+ }
+
+ check_update_region (pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_BGR8, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
+#else /* MNG_NO_16BIT_SUPPORT */
+mng_retcode mng_display_bgr8 (mng_datap pData)
+{
+ mng_uint8p pScanline;
+ mng_uint8p pDataline;
+ mng_int32 iX;
+ mng_uint8 iA8;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_BGR8, MNG_LC_START);
+#endif
+ /* viewable row ? */
+ if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
+ { /* address destination row */
+ pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ /* adjust destination row starting-point */
+ pScanline = pScanline + (pData->iCol * 3) + (pData->iDestl * 3);
+ pDataline = pData->pRGBArow; /* address source row */
+
+ pDataline = pDataline + (pData->iSourcel / pData->iColinc) * 4;
+
+ if (pData->bIsOpaque) /* forget about transparency ? */
+ {
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* copy the values */
+ *pScanline = *(pDataline+2);
+ *(pScanline+1) = *(pDataline+1);
+ *(pScanline+2) = *pDataline;
+
+ pScanline += (pData->iColinc * 3);
+ pDataline += 4;
+ }
+ }
+ }
+ else
+ {
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ {
+ iA8 = *(pDataline+3); /* get alpha value */
+
+ if (iA8) /* any opacity at all ? */
+ {
+ if (iA8 == 0xFF) /* fully opaque ? */
+ { /* then simply copy the values */
+ *pScanline = *(pDataline+2);
+ *(pScanline+1) = *(pDataline+1);
+ *(pScanline+2) = *pDataline;
+ }
+ else
+ { /* do alpha composing */
+#ifdef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
+ int i;
+ for (i=2; i >= 0; i--)
+ {
+ MNG_COMPOSE8 (*(pScanline+i), *(pDataline+2-i), iA8, *(pScanline+i));
+ }
+#else
+ MNG_COMPOSE8 (*pScanline, *(pDataline+2), iA8, *pScanline );
+ MNG_COMPOSE8 (*(pScanline+1), *(pDataline+1), iA8, *(pScanline+1));
+ MNG_COMPOSE8 (*(pScanline+2), *pDataline, iA8, *(pScanline+2));
+#endif
+ }
+ }
+
+ pScanline += (pData->iColinc * 3);
+ pDataline += 4;
+ }
+ }
+ }
+ }
+
+ check_update_region (pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_BGR8, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_NO_16BIT_SUPPORT */
+#endif /* MNG_SKIPCANVAS_BGR8 */
+
+/* ************************************************************************** */
+
+#ifndef MNG_SKIPCANVAS_BGRX8
+#ifndef MNG_NO_16BIT_SUPPORT
+#ifndef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
+mng_retcode mng_display_bgrx8 (mng_datap pData)
+{
+ mng_uint8p pScanline;
+ mng_uint8p pDataline;
+ mng_int32 iX;
+ mng_uint16 iA16;
+ mng_uint16 iFGr16, iFGg16, iFGb16;
+ mng_uint16 iBGr16, iBGg16, iBGb16;
+ mng_uint8 iA8;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_BGRX8, MNG_LC_START);
+#endif
+ /* viewable row ? */
+ if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
+ { /* address destination row */
+ pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ /* adjust destination row starting-point */
+ pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
+ pDataline = pData->pRGBArow; /* address source row */
+
+ if (pData->bIsRGBA16) /* adjust source row starting-point */
+ pDataline = pDataline + (pData->iSourcel / pData->iColinc) * 8;
+ else
+ pDataline = pDataline + (pData->iSourcel / pData->iColinc) * 4;
+
+ if (pData->bIsOpaque) /* forget about transparency ? */
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* scale down by dropping the LSB */
+ *pScanline = *(pDataline+4);
+ *(pScanline+1) = *(pDataline+2);
+ *(pScanline+2) = *pDataline;
+ *(pScanline+3) = 0xFF; /* filler byte */
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* copy the values */
+ *pScanline = *(pDataline+2);
+ *(pScanline+1) = *(pDataline+1);
+ *(pScanline+2) = *pDataline;
+ *(pScanline+3) = 0xFF; /* filler byte */
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 4;
+ }
+ }
+ }
+ else
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* get alpha value */
+ iA16 = mng_get_uint16 (pDataline+6);
+
+ if (iA16) /* any opacity at all ? */
+ {
+ if (iA16 == 0xFFFF) /* fully opaque ? */
+ { /* scale down by dropping the LSB */
+ *pScanline = *(pDataline+4);
+ *(pScanline+1) = *(pDataline+2);
+ *(pScanline+2) = *pDataline;
+ *(pScanline+3) = 0xFF; /* filler byte */
+ }
+ else
+ { /* get the proper values */
+ iFGr16 = mng_get_uint16 (pDataline );
+ iFGg16 = mng_get_uint16 (pDataline+2);
+ iFGb16 = mng_get_uint16 (pDataline+4);
+ /* scale background up */
+ iBGr16 = (mng_uint16)(*(pScanline+2));
+ iBGg16 = (mng_uint16)(*(pScanline+1));
+ iBGb16 = (mng_uint16)(*pScanline );
+ iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
+ iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
+ iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
+ /* now compose */
+ MNG_COMPOSE16(iFGr16, iFGr16, iA16, iBGr16);
+ MNG_COMPOSE16(iFGg16, iFGg16, iA16, iBGg16);
+ MNG_COMPOSE16(iFGb16, iFGb16, iA16, iBGb16);
+ /* and return the composed values */
+ *pScanline = (mng_uint8)(iFGb16 >> 8);
+ *(pScanline+1) = (mng_uint8)(iFGg16 >> 8);
+ *(pScanline+2) = (mng_uint8)(iFGr16 >> 8);
+ *(pScanline+3) = 0xFF; /* filler byte */
+ }
+ }
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ {
+ iA8 = *(pDataline+3); /* get alpha value */
+
+ if (iA8) /* any opacity at all ? */
+ {
+ if (iA8 == 0xFF) /* fully opaque ? */
+ { /* then simply copy the values */
+ *pScanline = *(pDataline+2);
+ *(pScanline+1) = *(pDataline+1);
+ *(pScanline+2) = *pDataline;
+ *(pScanline+3) = 0xFF; /* filler byte */
+ }
+ else
+ { /* do alpha composing */
+ MNG_COMPOSE8 (*pScanline, *(pDataline+2), iA8, *pScanline );
+ MNG_COMPOSE8 (*(pScanline+1), *(pDataline+1), iA8, *(pScanline+1));
+ MNG_COMPOSE8 (*(pScanline+2), *pDataline, iA8, *(pScanline+2));
+ *(pScanline+3) = 0xFF; /* filler byte */
+ }
+ }
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 4;
+ }
+ }
+ }
+ }
+
+ check_update_region (pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_BGRX8, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#else /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
+mng_retcode mng_display_bgrx8 (mng_datap pData)
+{
+ mng_uint8p pScanline;
+ mng_uint8p pDataline;
+ mng_int32 iX;
+ mng_uint16 iA16;
+ mng_uint16 iFGg16;
+ mng_uint16 iBGg16;
+ mng_uint8 iA8;
+ mng_uint8 iBps;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_BGRX8, MNG_LC_START);
+#endif
+
+ iBps=(mng_uint8)(pData->bIsRGBA16 ? 2:1);
+ /* viewable row ? */
+ if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
+ { /* address destination row */
+ pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ /* adjust destination row starting-point */
+ pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
+ pDataline = pData->pRGBArow; /* address source row */
+
+ /* adjust source row starting-point */
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << (iBps+1));
+
+ if (pData->bIsOpaque) /* forget about transparency ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* scale down by dropping the LSB */
+ *pScanline = *(pDataline+2*iBps);
+ *(pScanline+1) = *(pDataline+iBps);
+ *(pScanline+2) = *pDataline;
+ *(pScanline+3) = 0xFF; /* filler byte */
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 4*iBps;
+ }
+ }
+ else
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* get alpha value */
+ iA16 = mng_get_uint16 (pDataline+6);
+
+ if (iA16) /* any opacity at all ? */
+ {
+ if (iA16 == 0xFFFF) /* fully opaque ? */
+ { /* scale down by dropping the LSB */
+ *pScanline = *(pDataline+4);
+ *(pScanline+1) = *(pDataline+2);
+ *(pScanline+2) = *pDataline;
+ *(pScanline+3) = 0xFF; /* filler byte */
+ }
+ else
+ { /* get the proper values */
+ int i;
+ for (i=2; i >= 0; i--)
+ {
+ iFGg16 = mng_get_uint16 (pDataline+i+i);
+ /* scale background up */
+ iBGg16 = (mng_uint16)(*(pScanline+2-i));
+ iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
+ /* now compose */
+ MNG_COMPOSE16(iFGg16, iFGg16, iA16, iBGg16);
+ /* and return the composed values */
+ *(pScanline+2-i) = (mng_uint8)(iFGg16 >> 8);
+ }
+ *(pScanline+3) = 0xFF; /* filler byte */
+ }
+ }
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ {
+ iA8 = *(pDataline+3); /* get alpha value */
+
+ if (iA8) /* any opacity at all ? */
+ {
+ if (iA8 == 0xFF) /* fully opaque ? */
+ { /* then simply copy the values */
+ *pScanline = *(pDataline+2);
+ *(pScanline+1) = *(pDataline+1);
+ *(pScanline+2) = *pDataline;
+ *(pScanline+3) = 0xFF; /* filler byte */
+ }
+ else
+ { /* do alpha composing */
+ int i;
+ for (i=2; i >= 0; i--)
+ {
+ MNG_COMPOSE8 (*(pScanline+i), *(pDataline+2-i), iA8, *(pScanline+i));
+ }
+ *(pScanline+3) = 0xFF; /* filler byte */
+ }
+ }
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 4;
+ }
+ }
+ }
+ }
+
+ check_update_region (pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_BGRX8, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
+#else /* MNG_NO_16BIT_SUPPORT */
+mng_retcode mng_display_bgrx8 (mng_datap pData)
+{
+ mng_uint8p pScanline;
+ mng_uint8p pDataline;
+ mng_int32 iX;
+ mng_uint8 iA8;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_BGRX8, MNG_LC_START);
+#endif
+ /* viewable row ? */
+ if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
+ { /* address destination row */
+ pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ /* adjust destination row starting-point */
+ pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
+ pDataline = pData->pRGBArow; /* address source row */
+
+ pDataline = pDataline + (pData->iSourcel / pData->iColinc) * 4;
+
+ if (pData->bIsOpaque) /* forget about transparency ? */
+ {
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* copy the values */
+ *pScanline = *(pDataline+2);
+ *(pScanline+1) = *(pDataline+1);
+ *(pScanline+2) = *pDataline;
+ *(pScanline+3) = 0xFF; /* filler byte */
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 4;
+ }
+ }
+ }
+ else
+ {
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ {
+ iA8 = *(pDataline+3); /* get alpha value */
+
+ if (iA8) /* any opacity at all ? */
+ {
+ if (iA8 == 0xFF) /* fully opaque ? */
+ { /* then simply copy the values */
+ *pScanline = *(pDataline+2);
+ *(pScanline+1) = *(pDataline+1);
+ *(pScanline+2) = *pDataline;
+ *(pScanline+3) = 0xFF; /* filler byte */
+ }
+ else
+ { /* do alpha composing */
+#ifdef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
+ int i;
+ for (i=2; i >= 0; i--)
+ {
+ MNG_COMPOSE8 (*(pScanline+i), *(pDataline+2-i), iA8, *(pScanline+i));
+ }
+#else
+ MNG_COMPOSE8 (*pScanline, *(pDataline+2), iA8, *pScanline );
+ MNG_COMPOSE8 (*(pScanline+1), *(pDataline+1), iA8, *(pScanline+1));
+ MNG_COMPOSE8 (*(pScanline+2), *pDataline, iA8, *(pScanline+2));
+#endif
+ *(pScanline+3) = 0xFF; /* filler byte */
+ }
+ }
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 4;
+ }
+ }
+ }
+ }
+
+ check_update_region (pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_BGRX8, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_NO_16BIT_SUPPORT */
+#endif /* MNG_SKIPCANVAS_BGRX8 */
+
+/* ************************************************************************** */
+
+#ifndef MNG_SKIPCANVAS_BGRA8
+#ifndef MNG_NO_16BIT_SUPPORT
+#ifndef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
+mng_retcode mng_display_bgra8 (mng_datap pData)
+{
+ mng_uint8p pScanline;
+ mng_uint8p pDataline;
+ mng_int32 iX;
+ mng_uint8 iFGa8, iBGa8, iCa8;
+ mng_uint16 iFGa16, iBGa16, iCa16;
+ mng_uint16 iFGr16, iFGg16, iFGb16;
+ mng_uint16 iBGr16, iBGg16, iBGb16;
+ mng_uint16 iCr16, iCg16, iCb16;
+ mng_uint8 iCr8, iCg8, iCb8;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_BGRA8, MNG_LC_START);
+#endif
+ /* viewable row ? */
+ if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
+ { /* address destination row */
+ pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ /* adjust destination row starting-point */
+ pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
+ pDataline = pData->pRGBArow; /* address source row */
+
+ if (pData->bIsRGBA16) /* adjust source row starting-point */
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 3);
+ else
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
+
+ if (pData->bIsOpaque) /* forget about transparency ? */
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* scale down by dropping the LSB */
+ *pScanline = *(pDataline+4);
+ *(pScanline+1) = *(pDataline+2);
+ *(pScanline+2) = *pDataline;
+ *(pScanline+3) = *(pDataline+6);
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* copy the values */
+ *pScanline = *(pDataline+2);
+ *(pScanline+1) = *(pDataline+1);
+ *(pScanline+2) = *pDataline;
+ *(pScanline+3) = *(pDataline+3);
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 4;
+ }
+ }
+ }
+ else
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* get alpha values */
+ iFGa16 = mng_get_uint16 (pDataline+6);
+ iBGa16 = (mng_uint16)(*(pScanline+3));
+ iBGa16 = (mng_uint16)(iBGa16 << 8) | iBGa16;
+
+ if (iFGa16) /* any opacity at all ? */
+ { /* fully opaque or background fully transparent ? */
+ if ((iFGa16 == 0xFFFF) || (iBGa16 == 0))
+ { /* plain copy it */
+ *pScanline = *(pDataline+4);
+ *(pScanline+1) = *(pDataline+2);
+ *(pScanline+2) = *pDataline;
+ *(pScanline+3) = *(pDataline+6);
+ }
+ else
+ {
+ if (iBGa16 == 0xFFFF) /* background fully opaque ? */
+ { /* get the proper values */
+ iFGr16 = mng_get_uint16 (pDataline );
+ iFGg16 = mng_get_uint16 (pDataline+2);
+ iFGb16 = mng_get_uint16 (pDataline+4);
+ /* scale background up */
+ iBGr16 = (mng_uint16)(*(pScanline+2));
+ iBGg16 = (mng_uint16)(*(pScanline+1));
+ iBGb16 = (mng_uint16)(*pScanline );
+ iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
+ iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
+ iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
+ /* now compose */
+ MNG_COMPOSE16(iFGr16, iFGr16, iFGa16, iBGr16);
+ MNG_COMPOSE16(iFGg16, iFGg16, iFGa16, iBGg16);
+ MNG_COMPOSE16(iFGb16, iFGb16, iFGa16, iBGb16);
+ /* and return the composed values */
+ *pScanline = (mng_uint8)(iFGb16 >> 8);
+ *(pScanline+1) = (mng_uint8)(iFGg16 >> 8);
+ *(pScanline+2) = (mng_uint8)(iFGr16 >> 8);
+ /* alpha remains fully opaque !!! */
+ }
+ else
+ { /* scale background up */
+ iBGr16 = (mng_uint16)(*(pScanline+2));
+ iBGg16 = (mng_uint16)(*(pScanline+1));
+ iBGb16 = (mng_uint16)(*pScanline );
+ iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
+ iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
+ iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
+ /* let's blend */
+ MNG_BLEND16 (mng_get_uint16 (pDataline ),
+ mng_get_uint16 (pDataline+2),
+ mng_get_uint16 (pDataline+4), iFGa16,
+ iBGr16, iBGg16, iBGb16, iBGa16,
+ iCr16, iCg16, iCb16, iCa16);
+ /* and return the composed values */
+ *pScanline = (mng_uint8)(iCb16 >> 8);
+ *(pScanline+1) = (mng_uint8)(iCg16 >> 8);
+ *(pScanline+2) = (mng_uint8)(iCr16 >> 8);
+ *(pScanline+3) = (mng_uint8)(iCa16 >> 8);
+ }
+ }
+ }
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ {
+ iFGa8 = *(pDataline+3); /* get alpha values */
+ iBGa8 = *(pScanline+3);
+
+ if (iFGa8) /* any opacity at all ? */
+ { /* fully opaque or background fully transparent ? */
+ if ((iFGa8 == 0xFF) || (iBGa8 == 0))
+ { /* then simply copy the values */
+ *pScanline = *(pDataline+2);
+ *(pScanline+1) = *(pDataline+1);
+ *(pScanline+2) = *pDataline;
+ *(pScanline+3) = *(pDataline+3);
+ }
+ else
+ {
+ if (iBGa8 == 0xFF) /* background fully opaque ? */
+ { /* do alpha composing */
+ MNG_COMPOSE8 (*pScanline, *(pDataline+2), iFGa8, *pScanline );
+ MNG_COMPOSE8 (*(pScanline+1), *(pDataline+1), iFGa8, *(pScanline+1));
+ MNG_COMPOSE8 (*(pScanline+2), *pDataline, iFGa8, *(pScanline+2));
+ /* alpha remains fully opaque !!! */
+ }
+ else
+ { /* now blend */
+ MNG_BLEND8 (*pDataline, *(pDataline+1), *(pDataline+2), iFGa8,
+ *(pScanline+2), *(pScanline+1), *pScanline, iBGa8,
+ iCr8, iCg8, iCb8, iCa8);
+ /* and return the composed values */
+ *pScanline = iCb8;
+ *(pScanline+1) = iCg8;
+ *(pScanline+2) = iCr8;
+ *(pScanline+3) = iCa8;
+ }
+ }
+ }
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 4;
+ }
+ }
+ }
+ }
+
+ check_update_region (pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_BGRA8, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#else /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
+mng_retcode mng_display_bgra8 (mng_datap pData)
+{
+ mng_uint8p pScanline;
+ mng_uint8p pDataline;
+ mng_int32 iX;
+ mng_uint8 iFGa8, iBGa8, iCa8;
+ mng_uint16 iFGa16, iBGa16, iCa16;
+ mng_uint16 iFGg16;
+ mng_uint16 iBGr16, iBGg16, iBGb16;
+ mng_uint16 iCr16, iCg16, iCb16;
+ mng_uint8 iCr8, iCg8, iCb8;
+ mng_uint8 iBps;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_BGRA8, MNG_LC_START);
+#endif
+
+ iBps=(mng_uint8)(pData->bIsRGBA16 ? 2:1);
+ /* viewable row ? */
+ if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
+ { /* address destination row */
+ pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ /* adjust destination row starting-point */
+ pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
+ pDataline = pData->pRGBArow; /* address source row */
+
+ /* adjust source row starting-point */
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << (iBps+1));
+
+ if (pData->bIsOpaque) /* forget about transparency ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* scale down by dropping the LSB */
+ *pScanline = *(pDataline+2*iBps);
+ *(pScanline+1) = *(pDataline+iBps);
+ *(pScanline+2) = *pDataline;
+ *(pScanline+3) = *(pDataline+3*iBps);
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 4*iBps;
+ }
+ }
+ else
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* get alpha values */
+ iFGa16 = mng_get_uint16 (pDataline+6);
+ iBGa16 = (mng_uint16)(*(pScanline+3));
+ iBGa16 = (mng_uint16)(iBGa16 << 8) | iBGa16;
+
+ if (iFGa16) /* any opacity at all ? */
+ { /* fully opaque or background fully transparent ? */
+ if ((iFGa16 == 0xFFFF) || (iBGa16 == 0))
+ { /* plain copy it */
+ *pScanline = *(pDataline+4);
+ *(pScanline+1) = *(pDataline+2);
+ *(pScanline+2) = *pDataline;
+ *(pScanline+3) = *(pDataline+6);
+ }
+ else
+ {
+ if (iBGa16 == 0xFFFF) /* background fully opaque ? */
+ { /* get the proper values */
+ int i;
+ for (i=2; i >= 0; i--)
+ {
+ iFGg16 = mng_get_uint16 (pDataline+i+i);
+ /* scale background up */
+ iBGg16 = (mng_uint16)(*(pScanline+2-i));
+ iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
+ /* now compose */
+ MNG_COMPOSE16(iFGg16, iFGg16, iFGa16, iBGg16);
+ /* and return the composed values */
+ *(pScanline+2-i) = (mng_uint8)(iFGg16 >> 8);
+ /* alpha remains fully opaque !!! */
+ }
+ }
+ else
+ { /* scale background up */
+ iBGr16 = (mng_uint16)(*(pScanline+2));
+ iBGg16 = (mng_uint16)(*(pScanline+1));
+ iBGb16 = (mng_uint16)(*pScanline );
+ iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
+ iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
+ iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
+ /* let's blend */
+ MNG_BLEND16 (mng_get_uint16 (pDataline ),
+ mng_get_uint16 (pDataline+2),
+ mng_get_uint16 (pDataline+4), iFGa16,
+ iBGr16, iBGg16, iBGb16, iBGa16,
+ iCr16, iCg16, iCb16, iCa16);
+ /* and return the composed values */
+ *pScanline = (mng_uint8)(iCb16 >> 8);
+ *(pScanline+1) = (mng_uint8)(iCg16 >> 8);
+ *(pScanline+2) = (mng_uint8)(iCr16 >> 8);
+ *(pScanline+3) = (mng_uint8)(iCa16 >> 8);
+ }
+ }
+ }
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ {
+ iFGa8 = *(pDataline+3); /* get alpha values */
+ iBGa8 = *(pScanline+3);
+
+ if (iFGa8) /* any opacity at all ? */
+ { /* fully opaque or background fully transparent ? */
+ if ((iFGa8 == 0xFF) || (iBGa8 == 0))
+ { /* then simply copy the values */
+ *pScanline = *(pDataline+2);
+ *(pScanline+1) = *(pDataline+1);
+ *(pScanline+2) = *pDataline;
+ *(pScanline+3) = *(pDataline+3);
+ }
+ else
+ {
+ if (iBGa8 == 0xFF) /* background fully opaque ? */
+ { /* do alpha composing */
+ int i;
+ for (i=2; i >= 0; i--)
+ {
+ MNG_COMPOSE8 (*(pScanline+i), *(pDataline+2-i), iFGa8, *(pScanline+i));
+ }
+ /* alpha remains fully opaque !!! */
+ }
+ else
+ { /* now blend */
+ MNG_BLEND8 (*pDataline, *(pDataline+1), *(pDataline+2), iFGa8,
+ *(pScanline+2), *(pScanline+1), *pScanline, iBGa8,
+ iCr8, iCg8, iCb8, iCa8);
+ /* and return the composed values */
+ *pScanline = iCb8;
+ *(pScanline+1) = iCg8;
+ *(pScanline+2) = iCr8;
+ *(pScanline+3) = iCa8;
+ }
+ }
+ }
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 4;
+ }
+ }
+ }
+ }
+
+ check_update_region (pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_BGRA8, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
+#else /* MNG_NO_16BIT_SUPPORT */
+mng_retcode mng_display_bgra8 (mng_datap pData)
+{
+ mng_uint8p pScanline;
+ mng_uint8p pDataline;
+ mng_int32 iX;
+ mng_uint8 iFGa8, iBGa8, iCa8;
+ mng_uint8 iCr8, iCg8, iCb8;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_BGRA8, MNG_LC_START);
+#endif
+ /* viewable row ? */
+ if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
+ { /* address destination row */
+ pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ /* adjust destination row starting-point */
+ pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
+ pDataline = pData->pRGBArow; /* address source row */
+
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
+
+ if (pData->bIsOpaque) /* forget about transparency ? */
+ {
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* copy the values */
+ *pScanline = *(pDataline+2);
+ *(pScanline+1) = *(pDataline+1);
+ *(pScanline+2) = *pDataline;
+ *(pScanline+3) = *(pDataline+3);
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 4;
+ }
+ }
+ }
+ else
+ {
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ {
+ iFGa8 = *(pDataline+3); /* get alpha values */
+ iBGa8 = *(pScanline+3);
+
+ if (iFGa8) /* any opacity at all ? */
+ { /* fully opaque or background fully transparent ? */
+ if ((iFGa8 == 0xFF) || (iBGa8 == 0))
+ { /* then simply copy the values */
+ *pScanline = *(pDataline+2);
+ *(pScanline+1) = *(pDataline+1);
+ *(pScanline+2) = *pDataline;
+ *(pScanline+3) = *(pDataline+3);
+ }
+ else
+ {
+ if (iBGa8 == 0xFF) /* background fully opaque ? */
+ { /* do alpha composing */
+#ifdef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
+ int i;
+ for (i=2; i >= 0; i--)
+ {
+ MNG_COMPOSE8 (*(pScanline+i), *(pDataline+2-i), iFGa8, *(pScanline+i));
+ }
+#else
+ MNG_COMPOSE8 (*pScanline, *(pDataline+2), iFGa8, *pScanline );
+ MNG_COMPOSE8 (*(pScanline+1), *(pDataline+1), iFGa8, *(pScanline+1));
+ MNG_COMPOSE8 (*(pScanline+2), *pDataline, iFGa8, *(pScanline+2));
+#endif
+ /* alpha remains fully opaque !!! */
+ }
+ else
+ { /* now blend */
+ MNG_BLEND8 (*pDataline, *(pDataline+1), *(pDataline+2), iFGa8,
+ *(pScanline+2), *(pScanline+1), *pScanline, iBGa8,
+ iCr8, iCg8, iCb8, iCa8);
+ /* and return the composed values */
+ *pScanline = iCb8;
+ *(pScanline+1) = iCg8;
+ *(pScanline+2) = iCr8;
+ *(pScanline+3) = iCa8;
+ }
+ }
+ }
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 4;
+ }
+ }
+ }
+ }
+
+ check_update_region (pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_BGRA8, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_NO_16BIT_SUPPORT */
+#endif /* MNG_SKIPCANVAS_BGRA8 */
+
+/* ************************************************************************** */
+
+#ifndef MNG_SKIPCANVAS_BGRA8_PM
+#ifndef MNG_NO_16BIT_SUPPORT
+#ifndef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
+mng_retcode mng_display_bgra8_pm (mng_datap pData)
+{
+ mng_uint8p pScanline;
+ mng_uint8p pDataline;
+ mng_int32 iX;
+ mng_uint32 s, t;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_BGRA8PM, MNG_LC_START);
+#endif
+ /* viewable row ? */
+ if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
+ { /* address destination row */
+ pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ /* adjust destination row starting-point */
+ pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
+ pDataline = pData->pRGBArow; /* address source row */
+
+ if (pData->bIsRGBA16) /* adjust source row starting-point */
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 3);
+ else
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
+
+ if (pData->bIsOpaque) /* forget about transparency ? */
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* scale down by dropping the LSB */
+ if ((s = pDataline[6]) == 0)
+ *(mng_uint32*) pScanline = 0; /* set all components = 0 */
+ else
+ {
+ if (s == 255)
+ {
+ pScanline[0] = pDataline[4];
+ pScanline[1] = pDataline[2];
+ pScanline[2] = pDataline[0];
+ pScanline[3] = 255;
+ }
+ else
+ {
+ pScanline[0] = DIV255B8(s * pDataline[4]);
+ pScanline[1] = DIV255B8(s * pDataline[2]);
+ pScanline[2] = DIV255B8(s * pDataline[0]);
+ pScanline[3] = (mng_uint8)s;
+ }
+ }
+ pScanline += (pData->iColinc << 2);
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* copy the values and premultiply */
+ if ((s = pDataline[3]) == 0)
+ *(mng_uint32*) pScanline = 0; /* set all components = 0 */
+ else
+ {
+ if (s == 255)
+ {
+ pScanline[0] = pDataline[2];
+ pScanline[1] = pDataline[1];
+ pScanline[2] = pDataline[0];
+ pScanline[3] = 255;
+ }
+ else
+ {
+ pScanline[0] = DIV255B8(s * pDataline[2]);
+ pScanline[1] = DIV255B8(s * pDataline[1]);
+ pScanline[2] = DIV255B8(s * pDataline[0]);
+ pScanline[3] = (mng_uint8)s;
+ }
+ }
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 4;
+ }
+ }
+ }
+ else
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* get alpha values */
+ if ((s = pDataline[6]) != 0) /* any opacity at all ? */
+ { /* fully opaque or background fully transparent ? */
+ if (s == 255)
+ { /* plain copy it */
+ pScanline[0] = pDataline[4];
+ pScanline[1] = pDataline[2];
+ pScanline[2] = pDataline[0];
+ pScanline[3] = 255;
+ }
+ else
+ { /* now blend (premultiplied) */
+ t = 255 - s;
+#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
+ {
+ int i;
+ for (i=2; i >= 0; i--)
+ {
+ pScanline[i] = DIV255B8(s * pDataline[4-i-i] + t *
+ pScanline[i]);
+ }
+ }
+#else
+ pScanline[0] = DIV255B8(s * pDataline[4] + t * pScanline[0]);
+ pScanline[1] = DIV255B8(s * pDataline[2] + t * pScanline[1]);
+ pScanline[2] = DIV255B8(s * pDataline[0] + t * pScanline[2]);
+#endif
+ pScanline[3] = (mng_uint8)(255 - DIV255B8(t * (255 - pScanline[3])));
+ }
+ }
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ {
+ if ((s = pDataline[3]) != 0) /* any opacity at all ? */
+ { /* fully opaque ? */
+ if (s == 255)
+ { /* then simply copy the values */
+ pScanline[0] = pDataline[2];
+ pScanline[1] = pDataline[1];
+ pScanline[2] = pDataline[0];
+ pScanline[3] = 255;
+ }
+ else
+ { /* now blend (premultiplied) */
+ t = 255 - s;
+#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
+ {
+ int i;
+ for (i=2; i >= 0; i--)
+ {
+ pScanline[i] = DIV255B8(s * pDataline[2-i] + t *
+ pScanline[i]);
+ }
+ }
+#else
+ pScanline[0] = DIV255B8(s * pDataline[2] + t * pScanline[0]);
+ pScanline[1] = DIV255B8(s * pDataline[1] + t * pScanline[1]);
+ pScanline[2] = DIV255B8(s * pDataline[0] + t * pScanline[2]);
+#endif
+ pScanline[3] = (mng_uint8)(255 - DIV255B8(t * (255 - pScanline[3])));
+ }
+ }
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 4;
+ }
+ }
+ }
+ }
+
+ check_update_region (pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_BGRA8PM, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#else /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
+mng_retcode mng_display_bgra8_pm (mng_datap pData)
+{
+ mng_uint8p pScanline;
+ mng_uint8p pDataline;
+ mng_int32 iX;
+ mng_uint32 s, t;
+ mng_uint8 iBps;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_BGRA8PM, MNG_LC_START);
+#endif
+
+ iBps=(mng_uint8)(pData->bIsRGBA16 ? 2:1);
+ /* viewable row ? */
+ if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
+ { /* address destination row */
+ pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ /* adjust destination row starting-point */
+ pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
+ pDataline = pData->pRGBArow; /* address source row */
+
+ /* adjust source row starting-point */
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << (iBps+1));
+
+ if (pData->bIsOpaque) /* forget about transparency ? */
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* scale down by dropping the LSB */
+ if ((s = pDataline[6]) == 0)
+ *(mng_uint32*) pScanline = 0; /* set all components = 0 */
+ else
+ {
+ if (s == 255)
+ {
+ pScanline[0] = pDataline[4];
+ pScanline[1] = pDataline[2];
+ pScanline[2] = pDataline[0];
+ pScanline[3] = 255;
+ }
+ else
+ {
+#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
+ int i;
+ for (i=2; i >= 0; i--)
+ {
+ pScanline[i] = DIV255B8(s * pDataline[4-i-i]);
+ }
+#else
+ pScanline[0] = DIV255B8(s * pDataline[4]);
+ pScanline[1] = DIV255B8(s * pDataline[2]);
+ pScanline[2] = DIV255B8(s * pDataline[0]);
+#endif
+ pScanline[3] = (mng_uint8)s;
+ }
+ }
+ pScanline += (pData->iColinc << 2);
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* copy the values and premultiply */
+ if ((s = pDataline[3]) == 0)
+ *(mng_uint32*) pScanline = 0; /* set all components = 0 */
+ else
+ {
+ if (s == 255)
+ {
+ pScanline[0] = pDataline[2];
+ pScanline[1] = pDataline[1];
+ pScanline[2] = pDataline[0];
+ pScanline[3] = 255;
+ }
+ else
+ {
+#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
+ int i;
+ for (i=2; i >= 0; i--)
+ {
+ pScanline[i] = DIV255B8(s * pDataline[2-i]);
+ }
+#else
+ pScanline[0] = DIV255B8(s * pDataline[2]);
+ pScanline[1] = DIV255B8(s * pDataline[1]);
+ pScanline[2] = DIV255B8(s * pDataline[0]);
+#endif
+ pScanline[3] = (mng_uint8)s;
+ }
+ }
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 4;
+ }
+ }
+ }
+ else
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* get alpha values */
+ if ((s = pDataline[6]) != 0) /* any opacity at all ? */
+ { /* fully opaque or background fully transparent ? */
+ if (s == 255)
+ { /* plain copy it */
+ pScanline[0] = pDataline[4];
+ pScanline[1] = pDataline[2];
+ pScanline[2] = pDataline[0];
+ pScanline[3] = 255;
+ }
+ else
+ { /* now blend (premultiplied) */
+ t = 255 - s;
+#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
+ {
+ int i;
+ for (i=2; i >= 0; i--)
+ {
+ pScanline[i] = DIV255B8(s * pDataline[4-i-i] + t *
+ pScanline[i]);
+ }
+ }
+#else
+ pScanline[0] = DIV255B8(s * pDataline[4] + t * pScanline[0]);
+ pScanline[1] = DIV255B8(s * pDataline[2] + t * pScanline[1]);
+ pScanline[2] = DIV255B8(s * pDataline[0] + t * pScanline[2]);
+#endif
+ pScanline[3] = (mng_uint8)(255 - DIV255B8(t * (255 - pScanline[3])));
+ }
+ }
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ {
+ if ((s = pDataline[3]) != 0) /* any opacity at all ? */
+ { /* fully opaque ? */
+ if (s == 255)
+ { /* then simply copy the values */
+ pScanline[0] = pDataline[2];
+ pScanline[1] = pDataline[1];
+ pScanline[2] = pDataline[0];
+ pScanline[3] = 255;
+ }
+ else
+ { /* now blend (premultiplied) */
+ t = 255 - s;
+#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
+ {
+ int i;
+ for (i=2; i >= 0; i--)
+ {
+ pScanline[i] = DIV255B8(s * pDataline[2-i] + t *
+ pScanline[i]);
+ }
+ }
+#else
+ pScanline[0] = DIV255B8(s * pDataline[2] + t * pScanline[0]);
+ pScanline[1] = DIV255B8(s * pDataline[1] + t * pScanline[1]);
+ pScanline[2] = DIV255B8(s * pDataline[0] + t * pScanline[2]);
+#endif
+ pScanline[3] = (mng_uint8)(255 - DIV255B8(t * (255 - pScanline[3])));
+ }
+ }
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 4;
+ }
+ }
+ }
+ }
+
+ check_update_region (pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_BGRA8PM, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
+#else /* MNG_NO_16BIT_SUPPORT */
+mng_retcode mng_display_bgra8_pm (mng_datap pData)
+{
+ mng_uint8p pScanline;
+ mng_uint8p pDataline;
+ mng_int32 iX;
+ mng_uint32 s, t;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_BGRA8PM, MNG_LC_START);
+#endif
+ /* viewable row ? */
+ if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
+ { /* address destination row */
+ pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ /* adjust destination row starting-point */
+ pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
+ pDataline = pData->pRGBArow; /* address source row */
+
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
+
+ if (pData->bIsOpaque) /* forget about transparency ? */
+ {
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* copy the values and premultiply */
+ if ((s = pDataline[3]) == 0)
+ *(mng_uint32*) pScanline = 0; /* set all components = 0 */
+ else
+ {
+ if (s == 255)
+ {
+ pScanline[0] = pDataline[2];
+ pScanline[1] = pDataline[1];
+ pScanline[2] = pDataline[0];
+ pScanline[3] = 255;
+ }
+ else
+ {
+#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
+ int i;
+ for (i=2; i >= 0; i--)
+ {
+ pScanline[i] = DIV255B8(s * pDataline[2-i]);
+ }
+#else
+ pScanline[0] = DIV255B8(s * pDataline[2]);
+ pScanline[1] = DIV255B8(s * pDataline[1]);
+ pScanline[2] = DIV255B8(s * pDataline[0]);
+#endif
+ pScanline[3] = (mng_uint8)s;
+ }
+ }
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 4;
+ }
+ }
+ }
+ else
+ {
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ {
+ if ((s = pDataline[3]) != 0) /* any opacity at all ? */
+ { /* fully opaque ? */
+ if (s == 255)
+ { /* then simply copy the values */
+ pScanline[0] = pDataline[2];
+ pScanline[1] = pDataline[1];
+ pScanline[2] = pDataline[0];
+ pScanline[3] = 255;
+ }
+ else
+ { /* now blend (premultiplied) */
+ t = 255 - s;
+#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
+ {
+ int i;
+ for (i=2; i >= 0; i--)
+ {
+ pScanline[i] = DIV255B8(s * pDataline[2-i] + t *
+ pScanline[i]);
+ }
+ }
+#else
+ pScanline[0] = DIV255B8(s * pDataline[2] + t * pScanline[0]);
+ pScanline[1] = DIV255B8(s * pDataline[1] + t * pScanline[1]);
+ pScanline[2] = DIV255B8(s * pDataline[0] + t * pScanline[2]);
+#endif
+ pScanline[3] = (mng_uint8)(255 - DIV255B8(t * (255 - pScanline[3])));
+ }
+ }
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 4;
+ }
+ }
+ }
+ }
+
+ check_update_region (pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_BGRA8PM, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_NO_16BIT_SUPPORT */
+#endif /* MNG_SKIPCANVAS_BGRA8_PM */
+
+/* ************************************************************************** */
+
+#ifndef MNG_SKIPCANVAS_ABGR8
+#ifndef MNG_NO_16BIT_SUPPORT
+#ifndef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
+mng_retcode mng_display_abgr8 (mng_datap pData)
+{
+ mng_uint8p pScanline;
+ mng_uint8p pDataline;
+ mng_int32 iX;
+ mng_uint8 iFGa8, iBGa8, iCa8;
+ mng_uint16 iFGa16, iBGa16, iCa16;
+ mng_uint16 iFGr16, iFGg16, iFGb16;
+ mng_uint16 iBGr16, iBGg16, iBGb16;
+ mng_uint16 iCr16, iCg16, iCb16;
+ mng_uint8 iCr8, iCg8, iCb8;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_ABGR8, MNG_LC_START);
+#endif
+ /* viewable row ? */
+ if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
+ { /* address destination row */
+ pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ /* adjust destination row starting-point */
+ pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
+ pDataline = pData->pRGBArow; /* address source row */
+
+ if (pData->bIsRGBA16) /* adjust source row starting-point */
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 3);
+ else
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
+
+ if (pData->bIsOpaque) /* forget about transparency ? */
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* scale down by dropping the LSB */
+ *pScanline = *(pDataline+6);
+ *(pScanline+1) = *(pDataline+4);
+ *(pScanline+2) = *(pDataline+2);
+ *(pScanline+3) = *pDataline;
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* copy the values */
+ *pScanline = *(pDataline+3);
+ *(pScanline+1) = *(pDataline+2);
+ *(pScanline+2) = *(pDataline+1);
+ *(pScanline+3) = *pDataline;
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 4;
+ }
+ }
+ }
+ else
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* get alpha values */
+ iFGa16 = mng_get_uint16 (pDataline+6);
+ iBGa16 = (mng_uint16)(*pScanline);
+ iBGa16 = (mng_uint16)(iBGa16 << 8) | iBGa16;
+
+ if (iFGa16) /* any opacity at all ? */
+ { /* fully opaque or background fully transparent ? */
+ if ((iFGa16 == 0xFFFF) || (iBGa16 == 0))
+ { /* plain copy it */
+ *pScanline = *(pDataline+6);
+ *(pScanline+1) = *(pDataline+4);
+ *(pScanline+2) = *(pDataline+2);
+ *(pScanline+3) = *pDataline;
+ }
+ else
+ {
+ if (iBGa16 == 0xFFFF) /* background fully opaque ? */
+ { /* get the proper values */
+ iFGr16 = mng_get_uint16 (pDataline );
+ iFGg16 = mng_get_uint16 (pDataline+2);
+ iFGb16 = mng_get_uint16 (pDataline+4);
+ /* scale background up */
+ iBGr16 = (mng_uint16)(*(pScanline+3));
+ iBGg16 = (mng_uint16)(*(pScanline+2));
+ iBGb16 = (mng_uint16)(*(pScanline+1));
+ iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
+ iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
+ iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
+ /* now compose */
+ MNG_COMPOSE16(iFGr16, iFGr16, iFGa16, iBGr16);
+ MNG_COMPOSE16(iFGg16, iFGg16, iFGa16, iBGg16);
+ MNG_COMPOSE16(iFGb16, iFGb16, iFGa16, iBGb16);
+ /* and return the composed values */
+ /* alpha itself remains fully opaque !!! */
+ *(pScanline+1) = (mng_uint8)(iFGb16 >> 8);
+ *(pScanline+2) = (mng_uint8)(iFGg16 >> 8);
+ *(pScanline+3) = (mng_uint8)(iFGr16 >> 8);
+ }
+ else
+ { /* scale background up */
+ iBGr16 = (mng_uint16)(*(pScanline+3));
+ iBGg16 = (mng_uint16)(*(pScanline+2));
+ iBGb16 = (mng_uint16)(*(pScanline+1));
+ iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
+ iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
+ iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
+ /* let's blend */
+ MNG_BLEND16 (mng_get_uint16 (pDataline ),
+ mng_get_uint16 (pDataline+2),
+ mng_get_uint16 (pDataline+4), iFGa16,
+ iBGr16, iBGg16, iBGb16, iBGa16,
+ iCr16, iCg16, iCb16, iCa16);
+ /* and return the composed values */
+ *pScanline = (mng_uint8)(iCa16 >> 8);
+ *(pScanline+1) = (mng_uint8)(iCb16 >> 8);
+ *(pScanline+2) = (mng_uint8)(iCg16 >> 8);
+ *(pScanline+3) = (mng_uint8)(iCr16 >> 8);
+ }
+ }
+ }
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ {
+ iFGa8 = *(pDataline+3); /* get alpha values */
+ iBGa8 = *pScanline;
+
+ if (iFGa8) /* any opacity at all ? */
+ { /* fully opaque or background fully transparent ? */
+ if ((iFGa8 == 0xFF) || (iBGa8 == 0))
+ { /* then simply copy the values */
+ *pScanline = *(pDataline+3);
+ *(pScanline+1) = *(pDataline+2);
+ *(pScanline+2) = *(pDataline+1);
+ *(pScanline+3) = *pDataline;
+ }
+ else
+ {
+ if (iBGa8 == 0xFF) /* background fully opaque ? */
+ { /* do simple alpha composing */
+ /* alpha itself remains fully opaque !!! */
+ MNG_COMPOSE8 (*(pScanline+1), *(pDataline+2), iFGa8, *(pScanline+1));
+ MNG_COMPOSE8 (*(pScanline+2), *(pDataline+1), iFGa8, *(pScanline+2));
+ MNG_COMPOSE8 (*(pScanline+3), *pDataline, iFGa8, *(pScanline+3));
+ }
+ else
+ { /* now blend */
+ MNG_BLEND8 (*pDataline, *(pDataline+1), *(pDataline+2), iFGa8,
+ *(pScanline+3), *(pScanline+2), *(pScanline+1), iBGa8,
+ iCr8, iCg8, iCb8, iCa8);
+ /* and return the composed values */
+ *pScanline = iCa8;
+ *(pScanline+1) = iCb8;
+ *(pScanline+2) = iCg8;
+ *(pScanline+3) = iCr8;
+ }
+ }
+ }
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 4;
+ }
+ }
+ }
+ }
+
+ check_update_region (pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_ABGR8, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#else /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
+mng_retcode mng_display_abgr8 (mng_datap pData)
+{
+ mng_uint8p pScanline;
+ mng_uint8p pDataline;
+ mng_int32 iX;
+ mng_uint8 iFGa8, iBGa8, iCa8;
+ mng_uint16 iFGa16, iBGa16, iCa16;
+ mng_uint16 iFGg16;
+ mng_uint16 iBGr16, iBGg16, iBGb16;
+ mng_uint16 iCr16, iCg16, iCb16;
+ mng_uint8 iCr8, iCg8, iCb8;
+ mng_uint8 iBps;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_ABGR8, MNG_LC_START);
+#endif
+
+ iBps=(mng_uint8)(pData->bIsRGBA16 ? 2:1);
+ /* viewable row ? */
+ if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
+ { /* address destination row */
+ pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ /* adjust destination row starting-point */
+ pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
+ pDataline = pData->pRGBArow; /* address source row */
+
+ /* adjust source row starting-point */
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << (iBps+1));
+
+ if (pData->bIsOpaque) /* forget about transparency ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* scale down by dropping the LSB */
+ *pScanline = *(pDataline+3*iBps);
+ *(pScanline+1) = *(pDataline+2*iBps);
+ *(pScanline+2) = *(pDataline+iBps);
+ *(pScanline+3) = *pDataline;
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 4*iBps;
+ }
+ }
+ else
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* get alpha values */
+ iFGa16 = mng_get_uint16 (pDataline+6);
+ iBGa16 = (mng_uint16)(*pScanline);
+ iBGa16 = (mng_uint16)(iBGa16 << 8) | iBGa16;
+
+ if (iFGa16) /* any opacity at all ? */
+ { /* fully opaque or background fully transparent ? */
+ if ((iFGa16 == 0xFFFF) || (iBGa16 == 0))
+ { /* plain copy it */
+ *pScanline = *(pDataline+6);
+ *(pScanline+1) = *(pDataline+4);
+ *(pScanline+2) = *(pDataline+2);
+ *(pScanline+3) = *pDataline;
+ }
+ else
+ {
+ if (iBGa16 == 0xFFFF) /* background fully opaque ? */
+ { /* get the proper values */
+ int i;
+ for (i=2; i >= 0; i--)
+ {
+ iFGg16 = mng_get_uint16 (pDataline+i+i);
+ /* scale background up */
+ iBGg16 = (mng_uint16)(*(pScanline+3-i));
+ iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
+ /* now compose */
+ MNG_COMPOSE16(iFGg16, iFGg16, iFGa16, iBGg16);
+ /* and return the composed values */
+ /* alpha itself remains fully opaque !!! */
+ *(pScanline+3-i) = (mng_uint8)(iFGg16 >> 8);
+ }
+ }
+ else
+ { /* scale background up */
+ iBGr16 = (mng_uint16)(*(pScanline+3));
+ iBGg16 = (mng_uint16)(*(pScanline+2));
+ iBGb16 = (mng_uint16)(*(pScanline+1));
+ iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
+ iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
+ iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
+ /* let's blend */
+ MNG_BLEND16 (mng_get_uint16 (pDataline ),
+ mng_get_uint16 (pDataline+2),
+ mng_get_uint16 (pDataline+4), iFGa16,
+ iBGr16, iBGg16, iBGb16, iBGa16,
+ iCr16, iCg16, iCb16, iCa16);
+ /* and return the composed values */
+ *pScanline = (mng_uint8)(iCa16 >> 8);
+ *(pScanline+1) = (mng_uint8)(iCb16 >> 8);
+ *(pScanline+2) = (mng_uint8)(iCg16 >> 8);
+ *(pScanline+3) = (mng_uint8)(iCr16 >> 8);
+ }
+ }
+ }
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ {
+ iFGa8 = *(pDataline+3); /* get alpha values */
+ iBGa8 = *pScanline;
+
+ if (iFGa8) /* any opacity at all ? */
+ { /* fully opaque or background fully transparent ? */
+ if ((iFGa8 == 0xFF) || (iBGa8 == 0))
+ { /* then simply copy the values */
+ *pScanline = *(pDataline+3);
+ *(pScanline+1) = *(pDataline+2);
+ *(pScanline+2) = *(pDataline+1);
+ *(pScanline+3) = *pDataline;
+ }
+ else
+ {
+ if (iBGa8 == 0xFF) /* background fully opaque ? */
+ { /* do simple alpha composing */
+ /* alpha itself remains fully opaque !!! */
+ int i;
+ for (i=2; i >= 0; i--)
+ {
+ MNG_COMPOSE8 (*(pScanline+i+1), *(pDataline+2-i), iFGa8, *(pScanline+i+1));
+ }
+ }
+ else
+ { /* now blend */
+ MNG_BLEND8 (*pDataline, *(pDataline+1), *(pDataline+2), iFGa8,
+ *(pScanline+3), *(pScanline+2), *(pScanline+1), iBGa8,
+ iCr8, iCg8, iCb8, iCa8);
+ /* and return the composed values */
+ *pScanline = iCa8;
+ *(pScanline+1) = iCb8;
+ *(pScanline+2) = iCg8;
+ *(pScanline+3) = iCr8;
+ }
+ }
+ }
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 4;
+ }
+ }
+ }
+ }
+
+ check_update_region (pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_ABGR8, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
+#else /* MNG_NO_16BIT_SUPPORT */
+mng_retcode mng_display_abgr8 (mng_datap pData)
+{
+ mng_uint8p pScanline;
+ mng_uint8p pDataline;
+ mng_int32 iX;
+ mng_uint8 iFGa8, iBGa8, iCa8;
+ mng_uint8 iCr8, iCg8, iCb8;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_ABGR8, MNG_LC_START);
+#endif
+ /* viewable row ? */
+ if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
+ { /* address destination row */
+ pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ /* adjust destination row starting-point */
+ pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
+ pDataline = pData->pRGBArow; /* address source row */
+
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
+
+ if (pData->bIsOpaque) /* forget about transparency ? */
+ {
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* copy the values */
+ *pScanline = *(pDataline+3);
+ *(pScanline+1) = *(pDataline+2);
+ *(pScanline+2) = *(pDataline+1);
+ *(pScanline+3) = *pDataline;
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 4;
+ }
+ }
+ }
+ else
+ {
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ {
+ iFGa8 = *(pDataline+3); /* get alpha values */
+ iBGa8 = *pScanline;
+
+ if (iFGa8) /* any opacity at all ? */
+ { /* fully opaque or background fully transparent ? */
+ if ((iFGa8 == 0xFF) || (iBGa8 == 0))
+ { /* then simply copy the values */
+ *pScanline = *(pDataline+3);
+ *(pScanline+1) = *(pDataline+2);
+ *(pScanline+2) = *(pDataline+1);
+ *(pScanline+3) = *pDataline;
+ }
+ else
+ {
+ if (iBGa8 == 0xFF) /* background fully opaque ? */
+ { /* do simple alpha composing */
+ /* alpha itself remains fully opaque !!! */
+#ifdef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
+ int i;
+ for (i=2; i >= 0; i--)
+ {
+ MNG_COMPOSE8 (*(pScanline+i+1), *(pDataline+2-i), iFGa8, *(pScanline+i+1));
+ }
+#else
+ MNG_COMPOSE8 (*(pScanline+1), *(pDataline+2), iFGa8, *(pScanline+1));
+ MNG_COMPOSE8 (*(pScanline+2), *(pDataline+1), iFGa8, *(pScanline+2));
+ MNG_COMPOSE8 (*(pScanline+3), *pDataline, iFGa8, *(pScanline+3));
+#endif
+ }
+ else
+ { /* now blend */
+ MNG_BLEND8 (*pDataline, *(pDataline+1), *(pDataline+2), iFGa8,
+ *(pScanline+3), *(pScanline+2), *(pScanline+1), iBGa8,
+ iCr8, iCg8, iCb8, iCa8);
+ /* and return the composed values */
+ *pScanline = iCa8;
+ *(pScanline+1) = iCb8;
+ *(pScanline+2) = iCg8;
+ *(pScanline+3) = iCr8;
+ }
+ }
+ }
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 4;
+ }
+ }
+ }
+ }
+
+ check_update_region (pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_ABGR8, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_NO_16BIT_SUPPORT */
+#endif /* MNG_SKIPCANVAS_ABGR8 */
+
+/* ************************************************************************** */
+
+#ifndef MNG_SKIPCANVAS_ABGR8_PM
+#ifndef MNG_NO_16BIT_SUPPORT
+#ifndef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
+mng_retcode mng_display_abgr8_pm (mng_datap pData)
+{
+ mng_uint8p pScanline;
+ mng_uint8p pDataline;
+ mng_int32 iX;
+ mng_uint32 s, t;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_ABGR8_PM, MNG_LC_START);
+#endif
+ /* viewable row ? */
+ if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
+ { /* address destination row */
+ pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ /* adjust destination row starting-point */
+ pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
+ pDataline = pData->pRGBArow; /* address source row */
+
+ if (pData->bIsRGBA16) /* adjust source row starting-point */
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 3);
+ else
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
+
+ if (pData->bIsOpaque) /* forget about transparency ? */
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* scale down by dropping the LSB */
+ if ((s = pDataline[6]) == 0)
+ *(mng_uint32*) pScanline = 0; /* set all components = 0 */
+ else
+ {
+ if (s == 255)
+ {
+ pScanline[0] = 255;
+ pScanline[1] = pDataline[4];
+ pScanline[2] = pDataline[2];
+ pScanline[3] = pDataline[0];
+ }
+ else
+ {
+ pScanline[0] = (mng_uint8)s;
+#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
+ {
+ int i;
+ for (i=2; i >= 0; i--)
+ {
+ pScanline[i+1] = DIV255B8(s * pDataline[4-i-i]);
+ }
+ }
+#else
+ pScanline[1] = DIV255B8(s * pDataline[4]);
+ pScanline[2] = DIV255B8(s * pDataline[2]);
+ pScanline[3] = DIV255B8(s * pDataline[0]);
+#endif
+ }
+ }
+ pScanline += (pData->iColinc << 2);
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* copy the values and premultiply */
+ if ((s = pDataline[3]) == 0)
+ *(mng_uint32*) pScanline = 0; /* set all components = 0 */
+ else
+ {
+ if (s == 255)
+ {
+ pScanline[0] = 255;
+ pScanline[1] = pDataline[2];
+ pScanline[2] = pDataline[1];
+ pScanline[3] = pDataline[0];
+ }
+ else
+ {
+ pScanline[0] = (mng_uint8)s;
+#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
+ {
+ int i;
+ for (i=2; i >= 0; i--)
+ {
+ pScanline[i+1] = DIV255B8(s * pDataline[2-i]);
+ }
+ }
+#else
+ pScanline[1] = DIV255B8(s * pDataline[2]);
+ pScanline[2] = DIV255B8(s * pDataline[1]);
+ pScanline[3] = DIV255B8(s * pDataline[0]);
+#endif
+ }
+ }
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 4;
+ }
+ }
+ }
+ else
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* get alpha values */
+ if ((s = pDataline[6]) != 0) /* any opacity at all ? */
+ { /* fully opaque or background fully transparent ? */
+ if (s == 255)
+ { /* plain copy it */
+ pScanline[0] = 255;
+ pScanline[1] = pDataline[4];
+ pScanline[2] = pDataline[2];
+ pScanline[3] = pDataline[0];
+ }
+ else
+ { /* now blend (premultiplied) */
+ t = 255 - s;
+ pScanline[0] = (mng_uint8)(255 - DIV255B8(t * (255 - pScanline[0])));
+#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
+ {
+ int i;
+ for (i=2; i >= 0; i--)
+ {
+ pScanline[i+1] = DIV255B8(s * pDataline[4-i-i] + t *
+ pScanline[i+1]);
+ }
+ }
+#else
+ pScanline[1] = DIV255B8(s * pDataline[4] + t * pScanline[1]);
+ pScanline[2] = DIV255B8(s * pDataline[2] + t * pScanline[2]);
+ pScanline[3] = DIV255B8(s * pDataline[0] + t * pScanline[3]);
+#endif
+ }
+ }
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ {
+ if ((s = pDataline[3]) != 0) /* any opacity at all ? */
+ { /* fully opaque ? */
+ if (s == 255)
+ { /* then simply copy the values */
+ pScanline[0] = 255;
+ pScanline[1] = pDataline[2];
+ pScanline[2] = pDataline[1];
+ pScanline[3] = pDataline[0];
+ }
+ else
+ { /* now blend (premultiplied) */
+ t = 255 - s;
+ pScanline[0] = (mng_uint8)(255 - DIV255B8(t * (255 - pScanline[0])));
+#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
+ {
+ int i;
+ for (i=2; i >= 0; i--)
+ {
+ pScanline[i+1] = DIV255B8(s * pDataline[2-i] + t *
+ pScanline[i+1]);
+ }
+ }
+#else
+ pScanline[1] = DIV255B8(s * pDataline[2] + t * pScanline[1]);
+ pScanline[2] = DIV255B8(s * pDataline[1] + t * pScanline[2]);
+ pScanline[3] = DIV255B8(s * pDataline[0] + t * pScanline[3]);
+#endif
+ }
+ }
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 4;
+ }
+ }
+ }
+ }
+
+ check_update_region (pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_ABGR8_PM, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#else /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
+mng_retcode mng_display_abgr8_pm (mng_datap pData)
+{
+ mng_uint8p pScanline;
+ mng_uint8p pDataline;
+ mng_int32 iX;
+ mng_uint32 s, t;
+ mng_uint8 iBps;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_ABGR8_PM, MNG_LC_START);
+#endif
+
+ iBps=(mng_uint8)(pData->bIsRGBA16 ? 2:1);
+ /* viewable row ? */
+ if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
+ { /* address destination row */
+ pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ /* adjust destination row starting-point */
+ pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
+ pDataline = pData->pRGBArow; /* address source row */
+
+ /* adjust source row starting-point */
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << (iBps+1));
+
+ if (pData->bIsOpaque) /* forget about transparency ? */
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* scale down by dropping the LSB */
+ if ((s = pDataline[6]) == 0)
+ *(mng_uint32*) pScanline = 0; /* set all components = 0 */
+ else
+ {
+ if (s == 255)
+ {
+ pScanline[0] = 255;
+ pScanline[1] = pDataline[4];
+ pScanline[2] = pDataline[2];
+ pScanline[3] = pDataline[0];
+ }
+ else
+ {
+ pScanline[0] = (mng_uint8)s;
+#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
+ {
+ int i;
+ for (i=2; i >= 0; i--)
+ {
+ pScanline[i+1] = DIV255B8(s * pDataline[4-i-i]);
+ }
+ }
+#else
+ pScanline[1] = DIV255B8(s * pDataline[4]);
+ pScanline[2] = DIV255B8(s * pDataline[2]);
+ pScanline[3] = DIV255B8(s * pDataline[0]);
+#endif
+ }
+ }
+ pScanline += (pData->iColinc << 2);
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* copy the values and premultiply */
+ if ((s = pDataline[3]) == 0)
+ *(mng_uint32*) pScanline = 0; /* set all components = 0 */
+ else
+ {
+ if (s == 255)
+ {
+ pScanline[0] = 255;
+ pScanline[1] = pDataline[2];
+ pScanline[2] = pDataline[1];
+ pScanline[3] = pDataline[0];
+ }
+ else
+ {
+ pScanline[0] = (mng_uint8)s;
+#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
+ {
+ int i;
+ for (i=2; i >= 0; i--)
+ {
+ pScanline[i+1] = DIV255B8(s * pDataline[2-i]);
+ }
+ }
+#else
+ pScanline[1] = DIV255B8(s * pDataline[2]);
+ pScanline[2] = DIV255B8(s * pDataline[1]);
+ pScanline[3] = DIV255B8(s * pDataline[0]);
+#endif
+ }
+ }
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 4;
+ }
+ }
+ }
+ else
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* get alpha values */
+ if ((s = pDataline[6]) != 0) /* any opacity at all ? */
+ { /* fully opaque or background fully transparent ? */
+ if (s == 255)
+ { /* plain copy it */
+ pScanline[0] = 255;
+ pScanline[1] = pDataline[4];
+ pScanline[2] = pDataline[2];
+ pScanline[3] = pDataline[0];
+ }
+ else
+ { /* now blend (premultiplied) */
+ t = 255 - s;
+ pScanline[0] = (mng_uint8)(255 - DIV255B8(t * (255 - pScanline[0])));
+#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
+ {
+ int i;
+ for (i=2; i >= 0; i--)
+ {
+ pScanline[i+1] = DIV255B8(s * pDataline[4-i-i] + t *
+ pScanline[i+1]);
+ }
+ }
+#else
+ pScanline[1] = DIV255B8(s * pDataline[4] + t * pScanline[1]);
+ pScanline[2] = DIV255B8(s * pDataline[2] + t * pScanline[2]);
+ pScanline[3] = DIV255B8(s * pDataline[0] + t * pScanline[3]);
+#endif
+ }
+ }
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ {
+ if ((s = pDataline[3]) != 0) /* any opacity at all ? */
+ { /* fully opaque ? */
+ if (s == 255)
+ { /* then simply copy the values */
+ pScanline[0] = 255;
+ pScanline[1] = pDataline[2];
+ pScanline[2] = pDataline[1];
+ pScanline[3] = pDataline[0];
+ }
+ else
+ { /* now blend (premultiplied) */
+ t = 255 - s;
+ pScanline[0] = (mng_uint8)(255 - DIV255B8(t * (255 - pScanline[0])));
+#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
+ {
+ int i;
+ for (i=2; i >= 0; i--)
+ {
+ pScanline[i+1] = DIV255B8(s * pDataline[2-i] + t *
+ pScanline[i+1]);
+ }
+ }
+#else
+ pScanline[1] = DIV255B8(s * pDataline[2] + t * pScanline[1]);
+ pScanline[2] = DIV255B8(s * pDataline[1] + t * pScanline[2]);
+ pScanline[3] = DIV255B8(s * pDataline[0] + t * pScanline[3]);
+#endif
+ }
+ }
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 4;
+ }
+ }
+ }
+ }
+
+ check_update_region (pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_ABGR8_PM, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
+#else /* MNG_NO_16BIT_SUPPORT */
+mng_retcode mng_display_abgr8_pm (mng_datap pData)
+{
+ mng_uint8p pScanline;
+ mng_uint8p pDataline;
+ mng_int32 iX;
+ mng_uint32 s, t;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_ABGR8_PM, MNG_LC_START);
+#endif
+ /* viewable row ? */
+ if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
+ { /* address destination row */
+ pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ /* adjust destination row starting-point */
+ pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
+ pDataline = pData->pRGBArow; /* address source row */
+
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
+
+ if (pData->bIsOpaque) /* forget about transparency ? */
+ {
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* copy the values and premultiply */
+ if ((s = pDataline[3]) == 0)
+ *(mng_uint32*) pScanline = 0; /* set all components = 0 */
+ else
+ {
+ if (s == 255)
+ {
+ pScanline[0] = 255;
+ pScanline[1] = pDataline[2];
+ pScanline[2] = pDataline[1];
+ pScanline[3] = pDataline[0];
+ }
+ else
+ {
+ pScanline[0] = (mng_uint8)s;
+#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
+ {
+ int i;
+ for (i=2; i >= 0; i--)
+ {
+ pScanline[i+1] = DIV255B8(s * pDataline[2-i]);
+ }
+ }
+#else
+ pScanline[1] = DIV255B8(s * pDataline[2]);
+ pScanline[2] = DIV255B8(s * pDataline[1]);
+ pScanline[3] = DIV255B8(s * pDataline[0]);
+#endif
+ }
+ }
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 4;
+ }
+ }
+ }
+ else
+ {
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ {
+ if ((s = pDataline[3]) != 0) /* any opacity at all ? */
+ { /* fully opaque ? */
+ if (s == 255)
+ { /* then simply copy the values */
+ pScanline[0] = 255;
+ pScanline[1] = pDataline[2];
+ pScanline[2] = pDataline[1];
+ pScanline[3] = pDataline[0];
+ }
+ else
+ { /* now blend (premultiplied) */
+ t = 255 - s;
+ pScanline[0] = (mng_uint8)(255 - DIV255B8(t * (255 - pScanline[0])));
+#ifdef MNG_OPTIMIZE_FOOTPRINT_DIV
+ {
+ int i;
+ for (i=2; i >= 0; i--)
+ {
+ pScanline[i+1] = DIV255B8(s * pDataline[2-i] + t *
+ pScanline[i+1]);
+ }
+ }
+#else
+ pScanline[1] = DIV255B8(s * pDataline[2] + t * pScanline[1]);
+ pScanline[2] = DIV255B8(s * pDataline[1] + t * pScanline[2]);
+ pScanline[3] = DIV255B8(s * pDataline[0] + t * pScanline[3]);
+#endif
+ }
+ }
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 4;
+ }
+ }
+ }
+ }
+
+ check_update_region (pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_ABGR8_PM, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_NO_16BIT_SUPPORT */
+#endif /* MNG_SKIPCANVAS_ABGR8_PM */
+
+/* ************************************************************************** */
+
+#ifndef MNG_SKIPCANVAS_BGR565
+#ifndef MNG_NO_16BIT_SUPPORT
+#ifndef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
+mng_retcode mng_display_bgr565 (mng_datap pData)
+{
+ mng_uint8p pScanline;
+ mng_uint8p pDataline;
+ mng_int32 iX;
+ mng_uint16 iA16;
+ mng_uint16 iFGr16, iFGg16, iFGb16;
+ mng_uint16 iBGr16, iBGg16, iBGb16;
+ mng_uint8 iA8;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_BGR565, MNG_LC_START);
+#endif
+ /* viewable row ? */
+ if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
+ { /* address destination row */
+ pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ /* adjust destination row starting-point */
+ pScanline = pScanline + (pData->iCol * 2) + (pData->iDestl * 2);
+ pDataline = pData->pRGBArow; /* address source row */
+
+ if (pData->bIsRGBA16) /* adjust source row starting-point */
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 3);
+ else
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
+
+ if (pData->bIsOpaque) /* forget about transparency ? */
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* scale down by dropping the LSB */
+ *(pScanline+1) = (mng_uint8)( ( (*(pDataline))&0xF8 ) | ( (*(pDataline+2)>>5) ) );
+ *pScanline = (mng_uint8)( ( (*(pDataline+4)) >>3) | ( (*(pDataline+2)&0xFC) << 3) );
+
+ pScanline += (pData->iColinc * 2);
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* copy the values */
+ *(pScanline+1) = (mng_uint8)( ( (*(pDataline))&0xF8 ) | ( (*(pDataline+1)>>5 ) ) );
+ *pScanline = (mng_uint8)( ( *(pDataline+2) >>3 ) | ( (*(pDataline+1)&0xFC ) << 3) );
+
+
+ pScanline += (pData->iColinc * 2);
+ pDataline += 4;
+ }
+ }
+ }
+ else
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ {
+ iA16 = mng_get_uint16 (pDataline+6);
+
+ if (iA16) /* any opacity at all ? */
+ {
+ if (iA16 == 0xFFFF) /* fully opaque ? */
+ { /* scale down by dropping the LSB */
+ *(pScanline+1) = (mng_uint8)( (*(pDataline))&0xF8 ) | (mng_uint8)( (*(pDataline+2)>>5 ) );
+ *pScanline = (mng_uint8)( (*(pDataline+4)) >>3) | (mng_uint8)( (*(pDataline+2)&0xFC) << 3);
+ }
+ else
+ { /* get the proper values */
+ iFGr16 = mng_get_uint16 (pDataline );
+ iFGg16 = mng_get_uint16 (pDataline+2);
+ iFGb16 = mng_get_uint16 (pDataline+4);
+ /* scale background up */
+
+ iBGb16 = (mng_uint16)( (*(pScanline+1)) & 0xF8 );
+ iBGg16 = (mng_uint16)( (*(pScanline+1) << 5) | (((*(pScanline )) & 0xE0) >>3 ) );
+ iBGr16 = (mng_uint16)( (*(pScanline )) << 3 );
+
+ iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
+ iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
+ iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
+ /* now compose */
+ MNG_COMPOSE16(iFGr16, iFGr16, iA16, iBGr16);
+ MNG_COMPOSE16(iFGg16, iFGg16, iA16, iBGg16);
+ MNG_COMPOSE16(iFGb16, iFGb16, iA16, iBGb16);
+ /* and return the composed values */
+ *(pScanline+1) = (mng_uint8) ( ( (iFGr16 >> 8)&0xF8 ) | ( (mng_uint8)(iFGg16>>8) >> 5) );
+ *pScanline = (mng_uint8) ( ( (iFGb16>>11) ) | (((mng_uint8)(iFGg16>>8)&0xFC) << 3) );
+ }
+ }
+
+ pScanline += (pData->iColinc * 2);
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ {
+ iA8 = *(pDataline+3); /* get alpha value */
+
+ if (iA8) /* any opacity at all ? */
+ {
+ if (iA8 == 0xFF) /* fully opaque ? */
+ { /* then simply copy the values */
+ *(pScanline+1) = (mng_uint8)( ( (*(pDataline)) &0xF8 ) | (*(pDataline+1) >>5 ) );
+ *pScanline = (mng_uint8)( ( ((*(pDataline+2))>>3) ) | ((*(pDataline+1)&0xFC) << 3) );
+ }
+ else
+ { /* do alpha composing */
+ mng_uint8 iRed, iGreen, iBlue;
+
+ iRed = (mng_uint8) ( *(pScanline+1) & 0xF8 );
+ iGreen = (mng_uint8) ( (*(pScanline+1) << 5) | ( ((*pScanline) & 0xE0)>>3 ) );
+ iBlue = (mng_uint8) ( (*pScanline << 3) );
+
+ MNG_COMPOSE8 (iRed, *pDataline, iA8, iRed );
+ MNG_COMPOSE8 (iGreen, *(pDataline+1), iA8, iGreen );
+ MNG_COMPOSE8 (iBlue, *(pDataline+2), iA8, iBlue );
+
+ *(pScanline+1) = (mng_uint8) ( ( iRed & 0xF8 ) | (iGreen>>5) );
+ *pScanline = (mng_uint8) ( ( iBlue >> 3 ) | ( (iGreen & 0xFC) << 3) );
+ }
+ }
+
+ pScanline += (pData->iColinc * 2);
+ pDataline += 4;
+ }
+ }
+ }
+ }
+
+ check_update_region (pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_BGR565, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#else /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
+mng_retcode mng_display_bgr565 (mng_datap pData)
+{
+ mng_uint8p pScanline;
+ mng_uint8p pDataline;
+ mng_int32 iX;
+ mng_uint16 iA16;
+ mng_uint16 iFGr16, iFGg16, iFGb16;
+ mng_uint16 iBGr16, iBGg16, iBGb16;
+ mng_uint8 iA8;
+ mng_uint8 iBps;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_BGR565, MNG_LC_START);
+#endif
+
+ iBps=(mng_uint8)(pData->bIsRGBA16 ? 2:1);
+ /* viewable row ? */
+ if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
+ { /* address destination row */
+ pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ /* adjust destination row starting-point */
+ pScanline = pScanline + (pData->iCol * 2) + (pData->iDestl * 2);
+ pDataline = pData->pRGBArow; /* address source row */
+
+ /* adjust source row starting-point */
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << (iBps+1));
+
+ if (pData->bIsOpaque) /* forget about transparency ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* scale down by dropping the LSB */
+ *(pScanline+1) = (mng_uint8)( ( (*(pDataline))&0xF8 ) |
+ ( (*(pDataline+iBps)>>5) ) );
+ *pScanline = (mng_uint8)( ( (*(pDataline+2*iBps)) >>3) |
+ ( (*(pDataline+iBps)&0xFC) << 3) );
+
+ pScanline += (pData->iColinc * 2);
+ pDataline += 4*iBps;
+ }
+ }
+ else
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ {
+ iA16 = mng_get_uint16 (pDataline+6);
+
+ if (iA16) /* any opacity at all ? */
+ {
+ if (iA16 == 0xFFFF) /* fully opaque ? */
+ { /* scale down by dropping the LSB */
+ *(pScanline+1) = (mng_uint8)( (*(pDataline))&0xF8 ) | (mng_uint8)( (*(pDataline+2)>>5 ) );
+ *pScanline = (mng_uint8)( (*(pDataline+4)) >>3) | (mng_uint8)( (*(pDataline+2)&0xFC) << 3);
+ }
+ else
+ { /* get the proper values */
+ iFGr16 = mng_get_uint16 (pDataline );
+ iFGg16 = mng_get_uint16 (pDataline+2);
+ iFGb16 = mng_get_uint16 (pDataline+4);
+ /* scale background up */
+
+ iBGb16 = (mng_uint16)( (*(pScanline+1)) & 0xF8 );
+ iBGg16 = (mng_uint16)( (*(pScanline+1) << 5) | (((*(pScanline )) & 0xE0) >>3 ) );
+ iBGr16 = (mng_uint16)( (*(pScanline )) << 3 );
+
+ iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
+ iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
+ iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
+ /* now compose */
+ MNG_COMPOSE16(iFGr16, iFGr16, iA16, iBGr16);
+ MNG_COMPOSE16(iFGg16, iFGg16, iA16, iBGg16);
+ MNG_COMPOSE16(iFGb16, iFGb16, iA16, iBGb16);
+ /* and return the composed values */
+ *(pScanline+1) = (mng_uint8) ( ( (iFGr16 >> 8)&0xF8 ) | ( (mng_uint8)(iFGg16>>8) >> 5) );
+ *pScanline = (mng_uint8) ( ( (iFGb16>>11) ) | (((mng_uint8)(iFGg16>>8)&0xFC) << 3) );
+ }
+ }
+
+ pScanline += (pData->iColinc * 2);
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ {
+ iA8 = *(pDataline+3); /* get alpha value */
+
+ if (iA8) /* any opacity at all ? */
+ {
+ if (iA8 == 0xFF) /* fully opaque ? */
+ { /* then simply copy the values */
+ *(pScanline+1) = (mng_uint8)( ( (*(pDataline)) &0xF8 ) | (*(pDataline+1) >>5 ) );
+ *pScanline = (mng_uint8)( ( ((*(pDataline+2))>>3) ) | ((*(pDataline+1)&0xFC) << 3) );
+ }
+ else
+ { /* do alpha composing */
+ mng_uint8 iRed, iGreen, iBlue;
+
+ iRed = (mng_uint8) ( *(pScanline+1) & 0xF8 );
+ iGreen = (mng_uint8) ( (*(pScanline+1) << 5) | ( ((*pScanline) & 0xE0)>>3 ) );
+ iBlue = (mng_uint8) ( (*pScanline << 3) );
+
+ MNG_COMPOSE8 (iRed, *pDataline, iA8, iRed );
+ MNG_COMPOSE8 (iGreen, *(pDataline+1), iA8, iGreen );
+ MNG_COMPOSE8 (iBlue, *(pDataline+2), iA8, iBlue );
+
+ *(pScanline+1) = (mng_uint8) ( ( iRed & 0xF8 ) | (iGreen>>5) );
+ *pScanline = (mng_uint8) ( ( iBlue >> 3 ) | ( (iGreen & 0xFC) << 3) );
+ }
+ }
+
+ pScanline += (pData->iColinc * 2);
+ pDataline += 4;
+ }
+ }
+ }
+ }
+
+ check_update_region (pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_BGR565, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
+#else /* MNG_NO_16BIT_SUPPORT */
+mng_retcode mng_display_bgr565 (mng_datap pData)
+{
+ mng_uint8p pScanline;
+ mng_uint8p pDataline;
+ mng_int32 iX;
+ mng_uint8 iA8;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_BGR565, MNG_LC_START);
+#endif
+ /* viewable row ? */
+ if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
+ { /* address destination row */
+ pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ /* adjust destination row starting-point */
+ pScanline = pScanline + (pData->iCol * 2) + (pData->iDestl * 2);
+ pDataline = pData->pRGBArow; /* address source row */
+
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
+
+ if (pData->bIsOpaque) /* forget about transparency ? */
+ {
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* copy the values */
+ *(pScanline+1) = (mng_uint8)( ( (*(pDataline))&0xF8 ) | ( (*(pDataline+1)>>5 ) ) );
+ *pScanline = (mng_uint8)( ( *(pDataline+2) >>3 ) | ( (*(pDataline+1)&0xFC ) << 3) );
+
+
+ pScanline += (pData->iColinc * 2);
+ pDataline += 4;
+ }
+ }
+ }
+ else
+ {
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ {
+ iA8 = *(pDataline+3); /* get alpha value */
+
+ if (iA8) /* any opacity at all ? */
+ {
+ if (iA8 == 0xFF) /* fully opaque ? */
+ { /* then simply copy the values */
+ *(pScanline+1) = (mng_uint8)( ( (*(pDataline)) &0xF8 ) | (*(pDataline+1) >>5 ) );
+ *pScanline = (mng_uint8)( ( ((*(pDataline+2))>>3) ) | ((*(pDataline+1)&0xFC) << 3) );
+ }
+ else
+ { /* do alpha composing */
+ mng_uint8 iRed, iGreen, iBlue;
+
+ iRed = (mng_uint8) ( *(pScanline+1) & 0xF8 );
+ iGreen = (mng_uint8) ( (*(pScanline+1) << 5) | ( ((*pScanline) & 0xE0)>>3 ) );
+ iBlue = (mng_uint8) ( (*pScanline << 3) );
+
+ MNG_COMPOSE8 (iRed, *pDataline, iA8, iRed );
+ MNG_COMPOSE8 (iGreen, *(pDataline+1), iA8, iGreen );
+ MNG_COMPOSE8 (iBlue, *(pDataline+2), iA8, iBlue );
+
+ *(pScanline+1) = (mng_uint8) ( ( iRed & 0xF8 ) | (iGreen>>5) );
+ *pScanline = (mng_uint8) ( ( iBlue >> 3 ) | ( (iGreen & 0xFC) << 3) );
+ }
+ }
+
+ pScanline += (pData->iColinc * 2);
+ pDataline += 4;
+ }
+ }
+ }
+ }
+
+ check_update_region (pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_BGR565, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_NO_16BIT_SUPPORT */
+#endif /* MNG_SKIPCANVAS_BGR565 */
+
+/* ************************************************************************** */
+
+#ifndef MNG_SKIPCANVAS_RGB565
+#ifndef MNG_NO_16BIT_SUPPORT
+#ifndef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
+mng_retcode mng_display_rgb565 (mng_datap pData)
+{
+ mng_uint8p pScanline;
+ mng_uint8p pDataline;
+ mng_int32 iX;
+ mng_uint16 iA16;
+ mng_uint16 iFGr16, iFGg16, iFGb16;
+ mng_uint16 iBGr16, iBGg16, iBGb16;
+ mng_uint8 iA8;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_RGB565, MNG_LC_START);
+#endif
+ /* viewable row ? */
+ if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
+ { /* address destination row */
+ pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ /* adjust destination row starting-point */
+ pScanline = pScanline + (pData->iCol * 2) + (pData->iDestl * 2);
+ pDataline = pData->pRGBArow; /* address source row */
+
+ if (pData->bIsRGBA16) /* adjust source row starting-point */
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 3);
+ else
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
+
+ if (pData->bIsOpaque) /* forget about transparency ? */
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* scale down by dropping the LSB */
+ *(pScanline+1) = (mng_uint8)( ( ( *(pDataline+4)) & 0xF8) | (*(pDataline+2) >> 5 ) );
+ *pScanline = (mng_uint8)( ( ( *(pDataline )) >> 3 ) | ((*(pDataline+2) & 0xFC) << 3) );
+
+ pScanline += (pData->iColinc * 2);
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* copy the values */
+ *(pScanline+1) = (mng_uint8)( ( (*(pDataline+2)) & 0xF8) | (*(pDataline+1) >> 5 ) );
+ *pScanline = (mng_uint8)( ( *(pDataline ) >> 3 ) | ((*(pDataline+1) & 0xFC) << 3) );
+
+ pScanline += (pData->iColinc * 2);
+ pDataline += 4;
+ }
+ }
+ }
+ else
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ {
+ iA16 = mng_get_uint16 (pDataline+6);
+
+ if (iA16) /* any opacity at all ? */
+ {
+ if (iA16 == 0xFFFF) /* fully opaque ? */
+ { /* scale down by dropping the LSB */
+ *(pScanline+1) = (mng_uint8)( ( (*(pDataline+4)) & 0xF8) | (*(pDataline+2)>>5) );
+ *pScanline = (mng_uint8)( ( (*(pDataline )) >> 3 ) | ((*(pDataline+2)&0xFC) << 3) );
+ }
+ else
+ { /* get the proper values */
+ iFGr16 = mng_get_uint16 (pDataline );
+ iFGg16 = mng_get_uint16 (pDataline+2);
+ iFGb16 = mng_get_uint16 (pDataline+4);
+
+ /* scale background up */
+ iBGr16 = (mng_uint8)( *(pScanline+1) & 0xF8 );
+ iBGg16 = (mng_uint8)( (*(pScanline+1) << 5) | ( ((*pScanline) & 0xE0) >> 3 ) );
+ iBGb16 = (mng_uint8)( *(pScanline ) << 3 );
+
+ iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
+ iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
+ iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
+ /* now compose */
+ MNG_COMPOSE16(iFGr16, iFGr16, iA16, iBGr16);
+ MNG_COMPOSE16(iFGg16, iFGg16, iA16, iBGg16);
+ MNG_COMPOSE16(iFGb16, iFGb16, iA16, iBGb16);
+ /* and return the composed values */
+ *(pScanline+1) = (mng_uint8)( (mng_uint8)((iFGb16 >> 8) &0xF8) | ( (mng_uint8)(iFGg16 >> 8) >> 5 ) );
+ *pScanline = (mng_uint8)( (mng_uint8) (iFGr16 >>11) | ( ( (mng_uint8)(iFGg16 >> 8) & 0xFC) << 3) );
+ }
+ }
+
+ pScanline += (pData->iColinc * 2);
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ {
+ iA8 = *(pDataline+3); /* get alpha value */
+
+ if (iA8) /* any opacity at all ? */
+ {
+ if (iA8 == 0xFF) /* fully opaque ? */
+ { /* then simply copy the values */
+ *(pScanline+1) = (mng_uint8)( ( (*(pDataline+2)) & 0xF8) | ( *(pDataline+1) >> 5 ) );
+ *pScanline = (mng_uint8)( ( (*(pDataline )) >> 3 ) | ( (*(pDataline+1) & 0xFC) << 3 ) );
+ }
+ else
+ { /* do alpha composing */
+ mng_uint8 iRed, iGreen, iBlue;
+
+ iRed = (mng_uint8)( *(pScanline+1) & 0xF8);
+ iGreen = (mng_uint8)( ( *(pScanline+1) << 5 ) | ( ( (*pScanline)&0xE0)>>3 ) );
+ iBlue = (mng_uint8)( *(pScanline ) << 3 );
+
+ MNG_COMPOSE8 (iRed, *(pDataline+2), iA8, iRed );
+ MNG_COMPOSE8 (iGreen, *(pDataline+1), iA8, iGreen );
+ MNG_COMPOSE8 (iBlue, *(pDataline+0), iA8, iBlue );
+
+ *(pScanline+1) = (mng_uint8)( ( iRed & 0xF8) | ( iGreen >> 5 ) );
+ *pScanline = (mng_uint8)( (iBlue >> 3 ) | ( (iGreen & 0xFC) << 3) );
+ }
+ }
+
+ pScanline += (pData->iColinc * 2);
+ pDataline += 4;
+ }
+ }
+ }
+ }
+
+ check_update_region (pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_RGB565, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#else /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
+mng_retcode mng_display_rgb565 (mng_datap pData)
+{
+ mng_uint8p pScanline;
+ mng_uint8p pDataline;
+ mng_int32 iX;
+ mng_uint16 iA16;
+ mng_uint16 iFGr16, iFGg16, iFGb16;
+ mng_uint16 iBGr16, iBGg16, iBGb16;
+ mng_uint8 iA8;
+ mng_uint8 iBps;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_RGB565, MNG_LC_START);
+#endif
+
+ iBps=(mng_uint8)(pData->bIsRGBA16 ? 2:1);
+ /* viewable row ? */
+ if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
+ { /* address destination row */
+ pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ /* adjust destination row starting-point */
+ pScanline = pScanline + (pData->iCol * 2) + (pData->iDestl * 2);
+ pDataline = pData->pRGBArow; /* address source row */
+
+ /* adjust source row starting-point */
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << (iBps+1));
+
+ if (pData->bIsOpaque) /* forget about transparency ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* scale down by dropping the LSB */
+ *(pScanline+1) = (mng_uint8)( ( ( *(pDataline+2*iBps)) & 0xF8) |
+ (*(pDataline+iBps) >> 5 ) );
+ *pScanline = (mng_uint8)( ( ( *(pDataline )) >> 3 ) |
+ ((*(pDataline+iBps) & 0xFC) << 3) );
+
+ pScanline += (pData->iColinc * 2);
+ pDataline += 4*iBps;
+ }
+ }
+ else
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ {
+ iA16 = mng_get_uint16 (pDataline+6);
+
+ if (iA16) /* any opacity at all ? */
+ {
+ if (iA16 == 0xFFFF) /* fully opaque ? */
+ { /* scale down by dropping the LSB */
+ *(pScanline+1) = (mng_uint8)( ( (*(pDataline+4)) & 0xF8) | (*(pDataline+2)>>5) );
+ *pScanline = (mng_uint8)( ( (*(pDataline )) >> 3 ) | ((*(pDataline+2)&0xFC) << 3) );
+ }
+ else
+ { /* get the proper values */
+ iFGr16 = mng_get_uint16 (pDataline );
+ iFGg16 = mng_get_uint16 (pDataline+2);
+ iFGb16 = mng_get_uint16 (pDataline+4);
+
+ /* scale background up */
+ iBGr16 = (mng_uint8)( *(pScanline+1) & 0xF8 );
+ iBGg16 = (mng_uint8)( (*(pScanline+1) << 5) | ( ((*pScanline) & 0xE0) >> 3 ) );
+ iBGb16 = (mng_uint8)( *(pScanline ) << 3 );
+
+ iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
+ iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
+ iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
+ /* now compose */
+ MNG_COMPOSE16(iFGr16, iFGr16, iA16, iBGr16);
+ MNG_COMPOSE16(iFGg16, iFGg16, iA16, iBGg16);
+ MNG_COMPOSE16(iFGb16, iFGb16, iA16, iBGb16);
+ /* and return the composed values */
+ *(pScanline+1) = (mng_uint8)( (mng_uint8)((iFGb16 >> 8) &0xF8) | ( (mng_uint8)(iFGg16 >> 8) >> 5 ) );
+ *pScanline = (mng_uint8)( (mng_uint8) (iFGr16 >>11) | ( ( (mng_uint8)(iFGg16 >> 8) & 0xFC) << 3) );
+ }
+ }
+
+ pScanline += (pData->iColinc * 2);
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ {
+ iA8 = *(pDataline+3); /* get alpha value */
+
+ if (iA8) /* any opacity at all ? */
+ {
+ if (iA8 == 0xFF) /* fully opaque ? */
+ { /* then simply copy the values */
+ *(pScanline+1) = (mng_uint8)( ( (*(pDataline+2)) & 0xF8) | ( *(pDataline+1) >> 5 ) );
+ *pScanline = (mng_uint8)( ( (*(pDataline )) >> 3 ) | ( (*(pDataline+1) & 0xFC) << 3 ) );
+ }
+ else
+ { /* do alpha composing */
+ mng_uint8 iRed, iGreen, iBlue;
+
+ iRed = (mng_uint8)( *(pScanline+1) & 0xF8);
+ iGreen = (mng_uint8)( ( *(pScanline+1) << 5 ) | ( ( (*pScanline)&0xE0)>>3 ) );
+ iBlue = (mng_uint8)( *(pScanline ) << 3 );
+
+ MNG_COMPOSE8 (iRed, *(pDataline+2), iA8, iRed );
+ MNG_COMPOSE8 (iGreen, *(pDataline+1), iA8, iGreen );
+ MNG_COMPOSE8 (iBlue, *(pDataline+0), iA8, iBlue );
+
+ *(pScanline+1) = (mng_uint8)( ( iRed & 0xF8) | ( iGreen >> 5 ) );
+ *pScanline = (mng_uint8)( (iBlue >> 3 ) | ( (iGreen & 0xFC) << 3) );
+ }
+ }
+
+ pScanline += (pData->iColinc * 2);
+ pDataline += 4;
+ }
+ }
+ }
+ }
+
+ check_update_region (pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_RGB565, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
+#else /* MNG_NO_16BIT_SUPPORT */
+mng_retcode mng_display_rgb565 (mng_datap pData)
+{
+ mng_uint8p pScanline;
+ mng_uint8p pDataline;
+ mng_int32 iX;
+ mng_uint8 iA8;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_RGB565, MNG_LC_START);
+#endif
+ /* viewable row ? */
+ if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
+ { /* address destination row */
+ pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ /* adjust destination row starting-point */
+ pScanline = pScanline + (pData->iCol * 2) + (pData->iDestl * 2);
+ pDataline = pData->pRGBArow; /* address source row */
+
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
+
+ if (pData->bIsOpaque) /* forget about transparency ? */
+ {
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* copy the values */
+ *(pScanline+1) = (mng_uint8)( ( (*(pDataline+2)) & 0xF8) | (*(pDataline+1) >> 5 ) );
+ *pScanline = (mng_uint8)( ( *(pDataline ) >> 3 ) | ((*(pDataline+1) & 0xFC) << 3) );
+
+ pScanline += (pData->iColinc * 2);
+ pDataline += 4;
+ }
+ }
+ }
+ else
+ {
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ {
+ iA8 = *(pDataline+3); /* get alpha value */
+
+ if (iA8) /* any opacity at all ? */
+ {
+ if (iA8 == 0xFF) /* fully opaque ? */
+ { /* then simply copy the values */
+ *(pScanline+1) = (mng_uint8)( ( (*(pDataline+2)) & 0xF8) | ( *(pDataline+1) >> 5 ) );
+ *pScanline = (mng_uint8)( ( (*(pDataline )) >> 3 ) | ( (*(pDataline+1) & 0xFC) << 3 ) );
+ }
+ else
+ { /* do alpha composing */
+ mng_uint8 iRed, iGreen, iBlue;
+
+ iRed = (mng_uint8)( *(pScanline+1) & 0xF8);
+ iGreen = (mng_uint8)( ( *(pScanline+1) << 5 ) | ( ( (*pScanline)&0xE0)>>3 ) );
+ iBlue = (mng_uint8)( *(pScanline ) << 3 );
+
+ MNG_COMPOSE8 (iRed, *(pDataline+2), iA8, iRed );
+ MNG_COMPOSE8 (iGreen, *(pDataline+1), iA8, iGreen );
+ MNG_COMPOSE8 (iBlue, *(pDataline+0), iA8, iBlue );
+
+ *(pScanline+1) = (mng_uint8)( ( iRed & 0xF8) | ( iGreen >> 5 ) );
+ *pScanline = (mng_uint8)( (iBlue >> 3 ) | ( (iGreen & 0xFC) << 3) );
+ }
+ }
+
+ pScanline += (pData->iColinc * 2);
+ pDataline += 4;
+ }
+ }
+ }
+ }
+
+ check_update_region (pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_RGB565, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_NO_16BIT_SUPPORT */
+#endif /* MNG_SKIPCANVAS_RGB565 */
+
+/* ************************************************************************** */
+
+#ifndef MNG_SKIPCANVAS_BGRA565
+#ifndef MNG_NO_16BIT_SUPPORT
+#ifndef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
+mng_retcode mng_display_bgra565 (mng_datap pData)
+{
+ mng_uint8p pScanline;
+ mng_uint8p pDataline;
+ mng_int32 iX;
+ mng_uint8 iFGa8, iBGa8, iCa8;
+ mng_uint16 iFGa16, iBGa16, iCa16;
+ mng_uint16 iFGr16, iFGg16, iFGb16;
+ mng_uint16 iBGr16, iBGg16, iBGb16;
+ mng_uint16 iCr16, iCg16, iCb16;
+ mng_uint8 iCr8, iCg8, iCb8;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_BGRA565, MNG_LC_START);
+#endif
+ /* viewable row ? */
+ if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
+ { /* address destination row */
+ pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ /* adjust destination row starting-point */
+ pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl * 3);
+ pDataline = pData->pRGBArow; /* address source row */
+
+ if (pData->bIsRGBA16) /* adjust source row starting-point */
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 3);
+ else
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
+
+ if (pData->bIsOpaque) /* forget about transparency ? */
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* scale down by dropping the LSB */
+ *(pScanline+1) = (mng_uint8)( ( (*(pDataline))&0xF8 ) | ( (*(pDataline+2)>>5) ) );
+ *pScanline = (mng_uint8)( ( (*(pDataline+4)) >>3) | ( (*(pDataline+2)&0xFC) << 3) );
+ *(pScanline+2) = *(pDataline+6);
+
+ pScanline += (pData->iColinc * 3);
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* copy the values */
+ *(pScanline+1) = (mng_uint8)( ( (*(pDataline))&0xF8 ) | ( (*(pDataline+1)>>5 ) ) );
+ *pScanline = (mng_uint8)( ( *(pDataline+2) >>3 ) | ( (*(pDataline+1)&0xFC ) << 3) );
+ *(pScanline+2) = *(pDataline+3);
+
+ pScanline += (pData->iColinc * 3);
+ pDataline += 4;
+ }
+ }
+ }
+ else
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* get alpha values */
+ iFGa16 = mng_get_uint16 (pDataline+6);
+ iBGa16 = (mng_uint16)(*(pScanline+2));
+ iBGa16 = (mng_uint16)(iBGa16 << 8) | iBGa16;
+
+ if (iFGa16) /* any opacity at all ? */
+ { /* fully opaque or background fully transparent ? */
+ if ((iFGa16 == 0xFFFF) || (iBGa16 == 0))
+ { /* plain copy it */
+ *(pScanline+1) = (mng_uint8)( (*(pDataline))&0xF8 ) | (mng_uint8)( (*(pDataline+2)>>5 ) );
+ *pScanline = (mng_uint8)( (*(pDataline+4)) >>3) | (mng_uint8)( (*(pDataline+2)&0xFC) << 3);
+ *(pScanline+2) = *(pDataline+6);
+ }
+ else
+ {
+ if (iBGa16 == 0xFFFF) /* background fully opaque ? */
+ { /* get the proper values */
+ iFGr16 = mng_get_uint16 (pDataline );
+ iFGg16 = mng_get_uint16 (pDataline+2);
+ iFGb16 = mng_get_uint16 (pDataline+4);
+ /* scale background up */
+ iBGb16 = (mng_uint16)( (*(pScanline+1)) & 0xF8 );
+ iBGg16 = (mng_uint16)( (*(pScanline+1) << 5) | (((*(pScanline )) & 0xE0) >>3 ) );
+ iBGr16 = (mng_uint16)( (*(pScanline )) << 3 );
+
+ iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
+ iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
+ iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
+
+ /* now compose */
+ MNG_COMPOSE16(iFGr16, iFGr16, iFGa16, iBGr16);
+ MNG_COMPOSE16(iFGg16, iFGg16, iFGa16, iBGg16);
+ MNG_COMPOSE16(iFGb16, iFGb16, iFGa16, iBGb16);
+ /* and return the composed values */
+ *(pScanline+1) = (mng_uint8) ( ( (iFGr16 >> 8)&0xF8 ) | ( (mng_uint8)(iFGg16>>8) >> 5) );
+ *pScanline = (mng_uint8) ( ( (iFGb16>>11) ) | (((mng_uint8)(iFGg16>>8)&0xFC) << 3) );
+ }
+ else
+ { /* scale background up */
+ iBGb16 = (mng_uint16)( (*(pScanline+1)) & 0xF8 );
+ iBGg16 = (mng_uint16)( (*(pScanline+1) << 5) | (((*(pScanline )) & 0xE0) >>3 ) );
+ iBGr16 = (mng_uint16)( (*(pScanline )) << 3 );
+
+ iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
+ iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
+ iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
+ /* let's blend */
+ MNG_BLEND16 (mng_get_uint16 (pDataline ),
+ mng_get_uint16 (pDataline+2),
+ mng_get_uint16 (pDataline+4), iFGa16,
+ iBGr16, iBGg16, iBGb16, iBGa16,
+ iCr16, iCg16, iCb16, iCa16);
+ /* and return the composed values */
+ *(pScanline+1) = (mng_uint8) ( ( (iCr16 >> 8) & 0xF8 ) | ( (mng_uint8)(iCg16 >> 8) >> 5 ) );
+ *pScanline = (mng_uint8) ( ( (iCb16 >> 11) ) | (((mng_uint8)(iCg16 >> 8) & 0xFC) << 3) );
+ *(pScanline+2) = (mng_uint8)(iCa16 >> 8);
+ }
+ }
+ }
+
+ pScanline += (pData->iColinc * 3);
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ {
+ iFGa8 = *(pDataline+3); /* get alpha values */
+ iBGa8 = *(pScanline+2);
+
+ if (iFGa8) /* any opacity at all ? */
+ { /* fully opaque or background fully transparent ? */
+ if ((iFGa8 == 0xFF) || (iBGa8 == 0))
+ { /* then simply copy the values */
+ *(pScanline+1) = (mng_uint8)( ( (*(pDataline)) &0xF8 ) | (*(pDataline+1) >>5 ) );
+ *pScanline = (mng_uint8)( ( ((*(pDataline+2))>>3) ) | ((*(pDataline+1)&0xFC) << 3) );
+ *(pScanline+2) = *(pDataline+3);
+ }
+ else
+ {
+ mng_uint8 iRed, iGreen, iBlue;
+
+ iRed = (mng_uint8) ( *(pScanline+1) & 0xF8 );
+ iGreen = (mng_uint8) ( (*(pScanline+1) << 5) | ( ((*pScanline) & 0xE0)>>3 ) );
+ iBlue = (mng_uint8) ( (*pScanline << 3) );
+
+ if (iBGa8 == 0xFF) /* background fully opaque ? */
+ { /* do alpha composing */
+ MNG_COMPOSE8 (iRed, *pDataline, iFGa8, iRed );
+ MNG_COMPOSE8 (iGreen, *(pDataline+1), iFGa8, iGreen );
+ MNG_COMPOSE8 (iBlue, *(pDataline+2), iFGa8, iBlue );
+ /* alpha remains fully opaque !!! */
+ *(pScanline+1) = (mng_uint8) ( ( iRed & 0xF8 ) | (iGreen>>5) );
+ *pScanline = (mng_uint8) ( ( iBlue >> 3 ) | ( (iGreen & 0xFC) << 3) );
+ }
+ else
+ { /* now blend */
+ MNG_BLEND8 (*pDataline, *(pDataline+1), *(pDataline+2), iFGa8,
+ iRed , iGreen , iBlue , iBGa8,
+ iCr8, iCg8, iCb8, iCa8);
+ /* and return the composed values */
+
+
+ *pScanline = (mng_uint8) ( ( iCb8 >> 3 ) | ( (iCg8 & 0xFC) << 3) );
+ *(pScanline+1) = (mng_uint8) ( ( iCr8 & 0xF8 ) | (iCg8>>5) );
+ *(pScanline+2) = (mng_uint8) iCa8;
+ }
+ }
+ }
+
+ pScanline += (pData->iColinc *3);
+ pDataline += 4;
+ }
+ }
+ }
+ }
+
+ check_update_region (pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_BGRA565, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#else /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
+mng_retcode mng_display_bgra565 (mng_datap pData)
+{
+ mng_uint8p pScanline;
+ mng_uint8p pDataline;
+ mng_int32 iX;
+ mng_uint8 iFGa8, iBGa8, iCa8;
+ mng_uint16 iFGa16, iBGa16, iCa16;
+ mng_uint16 iFGr16, iFGg16, iFGb16;
+ mng_uint16 iBGr16, iBGg16, iBGb16;
+ mng_uint16 iCr16, iCg16, iCb16;
+ mng_uint8 iCr8, iCg8, iCb8;
+ mng_uint8 iBps;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_BGRA565, MNG_LC_START);
+#endif
+
+ iBps=(mng_uint8)(pData->bIsRGBA16 ? 2:1);
+ /* viewable row ? */
+ if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
+ { /* address destination row */
+ pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ /* adjust destination row starting-point */
+ pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl * 3);
+ pDataline = pData->pRGBArow; /* address source row */
+
+ /* adjust source row starting-point */
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << (iBps+1));
+
+ if (pData->bIsOpaque) /* forget about transparency ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* scale down by dropping the LSB */
+ *(pScanline+1) = (mng_uint8)( ( (*(pDataline))&0xF8 ) |
+ ( (*(pDataline+iBps)>>5) ) );
+ *pScanline = (mng_uint8)( ( (*(pDataline+2*iBps)) >>3) |
+ ( (*(pDataline+iBps)&0xFC) << 3) );
+ *(pScanline+2) = *(pDataline+3*iBps);
+
+ pScanline += (pData->iColinc * 3);
+ pDataline += 4*iBps;
+ }
+ }
+ else
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* get alpha values */
+ iFGa16 = mng_get_uint16 (pDataline+6);
+ iBGa16 = (mng_uint16)(*(pScanline+2));
+ iBGa16 = (mng_uint16)(iBGa16 << 8) | iBGa16;
+
+ if (iFGa16) /* any opacity at all ? */
+ { /* fully opaque or background fully transparent ? */
+ if ((iFGa16 == 0xFFFF) || (iBGa16 == 0))
+ { /* plain copy it */
+ *(pScanline+1) = (mng_uint8)( (*(pDataline))&0xF8 ) | (mng_uint8)( (*(pDataline+2)>>5 ) );
+ *pScanline = (mng_uint8)( (*(pDataline+4)) >>3) | (mng_uint8)( (*(pDataline+2)&0xFC) << 3);
+ *(pScanline+2) = *(pDataline+6);
+ }
+ else
+ {
+ if (iBGa16 == 0xFFFF) /* background fully opaque ? */
+ { /* get the proper values */
+ iFGr16 = mng_get_uint16 (pDataline );
+ iFGg16 = mng_get_uint16 (pDataline+2);
+ iFGb16 = mng_get_uint16 (pDataline+4);
+ /* scale background up */
+ iBGb16 = (mng_uint16)( (*(pScanline+1)) & 0xF8 );
+ iBGg16 = (mng_uint16)( (*(pScanline+1) << 5) | (((*(pScanline )) & 0xE0) >>3 ) );
+ iBGr16 = (mng_uint16)( (*(pScanline )) << 3 );
+
+ iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
+ iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
+ iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
+
+ /* now compose */
+ MNG_COMPOSE16(iFGr16, iFGr16, iFGa16, iBGr16);
+ MNG_COMPOSE16(iFGg16, iFGg16, iFGa16, iBGg16);
+ MNG_COMPOSE16(iFGb16, iFGb16, iFGa16, iBGb16);
+ /* and return the composed values */
+ *(pScanline+1) = (mng_uint8) ( ( (iFGr16 >> 8)&0xF8 ) | ( (mng_uint8)(iFGg16>>8) >> 5) );
+ *pScanline = (mng_uint8) ( ( (iFGb16>>11) ) | (((mng_uint8)(iFGg16>>8)&0xFC) << 3) );
+ }
+ else
+ { /* scale background up */
+ iBGb16 = (mng_uint16)( (*(pScanline+1)) & 0xF8 );
+ iBGg16 = (mng_uint16)( (*(pScanline+1) << 5) | (((*(pScanline )) & 0xE0) >>3 ) );
+ iBGr16 = (mng_uint16)( (*(pScanline )) << 3 );
+
+ iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
+ iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
+ iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
+ /* let's blend */
+ MNG_BLEND16 (mng_get_uint16 (pDataline ),
+ mng_get_uint16 (pDataline+2),
+ mng_get_uint16 (pDataline+4), iFGa16,
+ iBGr16, iBGg16, iBGb16, iBGa16,
+ iCr16, iCg16, iCb16, iCa16);
+ /* and return the composed values */
+ *(pScanline+1) = (mng_uint8) ( ( (iCr16 >> 8) & 0xF8 ) | ( (mng_uint8)(iCg16 >> 8) >> 5 ) );
+ *pScanline = (mng_uint8) ( ( (iCb16 >> 11) ) | (((mng_uint8)(iCg16 >> 8) & 0xFC) << 3) );
+ *(pScanline+2) = (mng_uint8)(iCa16 >> 8);
+ }
+ }
+ }
+
+ pScanline += (pData->iColinc * 3);
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ {
+ iFGa8 = *(pDataline+3); /* get alpha values */
+ iBGa8 = *(pScanline+2);
+
+ if (iFGa8) /* any opacity at all ? */
+ { /* fully opaque or background fully transparent ? */
+ if ((iFGa8 == 0xFF) || (iBGa8 == 0))
+ { /* then simply copy the values */
+ *(pScanline+1) = (mng_uint8)( ( (*(pDataline)) &0xF8 ) | (*(pDataline+1) >>5 ) );
+ *pScanline = (mng_uint8)( ( ((*(pDataline+2))>>3) ) | ((*(pDataline+1)&0xFC) << 3) );
+ *(pScanline+2) = *(pDataline+3);
+ }
+ else
+ {
+ mng_uint8 iRed, iGreen, iBlue;
+
+ iRed = (mng_uint8) ( *(pScanline+1) & 0xF8 );
+ iGreen = (mng_uint8) ( (*(pScanline+1) << 5) | ( ((*pScanline) & 0xE0)>>3 ) );
+ iBlue = (mng_uint8) ( (*pScanline << 3) );
+
+ if (iBGa8 == 0xFF) /* background fully opaque ? */
+ { /* do alpha composing */
+ MNG_COMPOSE8 (iRed, *pDataline, iFGa8, iRed );
+ MNG_COMPOSE8 (iGreen, *(pDataline+1), iFGa8, iGreen );
+ MNG_COMPOSE8 (iBlue, *(pDataline+2), iFGa8, iBlue );
+ /* alpha remains fully opaque !!! */
+ *(pScanline+1) = (mng_uint8) ( ( iRed & 0xF8 ) | (iGreen>>5) );
+ *pScanline = (mng_uint8) ( ( iBlue >> 3 ) | ( (iGreen & 0xFC) << 3) );
+ }
+ else
+ { /* now blend */
+ MNG_BLEND8 (*pDataline, *(pDataline+1), *(pDataline+2), iFGa8,
+ iRed , iGreen , iBlue , iBGa8,
+ iCr8, iCg8, iCb8, iCa8);
+ /* and return the composed values */
+
+
+ *pScanline = (mng_uint8) ( ( iCb8 >> 3 ) | ( (iCg8 & 0xFC) << 3) );
+ *(pScanline+1) = (mng_uint8) ( ( iCr8 & 0xF8 ) | (iCg8>>5) );
+ *(pScanline+2) = (mng_uint8) iCa8;
+ }
+ }
+ }
+
+ pScanline += (pData->iColinc *3);
+ pDataline += 4;
+ }
+ }
+ }
+ }
+
+ check_update_region (pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_BGRA565, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
+#else /* MNG_NO_16BIT_SUPPORT */
+mng_retcode mng_display_bgra565 (mng_datap pData)
+{
+ mng_uint8p pScanline;
+ mng_uint8p pDataline;
+ mng_int32 iX;
+ mng_uint8 iFGa8, iBGa8, iCa8;
+ mng_uint8 iCr8, iCg8, iCb8;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_BGRA565, MNG_LC_START);
+#endif
+ /* viewable row ? */
+ if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
+ { /* address destination row */
+ pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ /* adjust destination row starting-point */
+ pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl * 3);
+ pDataline = pData->pRGBArow; /* address source row */
+
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
+
+ if (pData->bIsOpaque) /* forget about transparency ? */
+ {
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* copy the values */
+ *(pScanline+1) = (mng_uint8)( ( (*(pDataline))&0xF8 ) | ( (*(pDataline+1)>>5 ) ) );
+ *pScanline = (mng_uint8)( ( *(pDataline+2) >>3 ) | ( (*(pDataline+1)&0xFC ) << 3) );
+ *(pScanline+2) = *(pDataline+3);
+
+ pScanline += (pData->iColinc * 3);
+ pDataline += 4;
+ }
+ }
+ }
+ else
+ {
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ {
+ iFGa8 = *(pDataline+3); /* get alpha values */
+ iBGa8 = *(pScanline+2);
+
+ if (iFGa8) /* any opacity at all ? */
+ { /* fully opaque or background fully transparent ? */
+ if ((iFGa8 == 0xFF) || (iBGa8 == 0))
+ { /* then simply copy the values */
+ *(pScanline+1) = (mng_uint8)( ( (*(pDataline)) &0xF8 ) | (*(pDataline+1) >>5 ) );
+ *pScanline = (mng_uint8)( ( ((*(pDataline+2))>>3) ) | ((*(pDataline+1)&0xFC) << 3) );
+ *(pScanline+2) = *(pDataline+3);
+ }
+ else
+ {
+ mng_uint8 iRed, iGreen, iBlue;
+
+ iRed = (mng_uint8) ( *(pScanline+1) & 0xF8 );
+ iGreen = (mng_uint8) ( (*(pScanline+1) << 5) | ( ((*pScanline) & 0xE0)>>3 ) );
+ iBlue = (mng_uint8) ( (*pScanline << 3) );
+
+ if (iBGa8 == 0xFF) /* background fully opaque ? */
+ { /* do alpha composing */
+ MNG_COMPOSE8 (iRed, *pDataline, iFGa8, iRed );
+ MNG_COMPOSE8 (iGreen, *(pDataline+1), iFGa8, iGreen );
+ MNG_COMPOSE8 (iBlue, *(pDataline+2), iFGa8, iBlue );
+ /* alpha remains fully opaque !!! */
+ *(pScanline+1) = (mng_uint8) ( ( iRed & 0xF8 ) | (iGreen>>5) );
+ *pScanline = (mng_uint8) ( ( iBlue >> 3 ) | ( (iGreen & 0xFC) << 3) );
+ }
+ else
+ { /* now blend */
+ MNG_BLEND8 (*pDataline, *(pDataline+1), *(pDataline+2), iFGa8,
+ iRed , iGreen , iBlue , iBGa8,
+ iCr8, iCg8, iCb8, iCa8);
+ /* and return the composed values */
+
+
+ *pScanline = (mng_uint8) ( ( iCb8 >> 3 ) | ( (iCg8 & 0xFC) << 3) );
+ *(pScanline+1) = (mng_uint8) ( ( iCr8 & 0xF8 ) | (iCg8>>5) );
+ *(pScanline+2) = (mng_uint8) iCa8;
+ }
+ }
+ }
+
+ pScanline += (pData->iColinc *3);
+ pDataline += 4;
+ }
+ }
+ }
+ }
+
+ check_update_region (pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_BGRA565, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_NO_16BIT_SUPPORT */
+#endif /* MNG_SKIPCANVAS_BGRA565 */
+
+/* ************************************************************************** */
+
+#ifndef MNG_SKIPCANVAS_RGBA565
+#ifndef MNG_NO_16BIT_SUPPORT
+#ifndef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
+mng_retcode mng_display_rgba565 (mng_datap pData)
+{
+ mng_uint8p pScanline;
+ mng_uint8p pDataline;
+ mng_int32 iX;
+ mng_uint8 iFGa8, iBGa8, iCa8;
+ mng_uint16 iFGa16, iBGa16, iCa16;
+ mng_uint16 iFGr16, iFGg16, iFGb16;
+ mng_uint16 iBGr16, iBGg16, iBGb16;
+ mng_uint16 iCr16, iCg16, iCb16;
+ mng_uint8 iCr8, iCg8, iCb8;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_RGBA565, MNG_LC_START);
+#endif
+ /* viewable row ? */
+ if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
+ { /* address destination row */
+ pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ /* adjust destination row starting-point */
+ pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl * 3);
+ pDataline = pData->pRGBArow; /* address source row */
+
+ if (pData->bIsRGBA16) /* adjust source row starting-point */
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 3);
+ else
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
+
+ if (pData->bIsOpaque) /* forget about transparency ? */
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* scale down by dropping the LSB */
+ *(pScanline+1) = (mng_uint8)( ( (*(pDataline+4))&0xF8 ) | ( (*(pDataline+2)>>5) ) );
+ *pScanline = (mng_uint8)( ( (*(pDataline)) >>3) | ( (*(pDataline+2)&0xFC) << 3) );
+ *(pScanline+2) = *(pDataline+6);
+
+ pScanline += (pData->iColinc * 3);
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* copy the values */
+ *(pScanline+1) = (mng_uint8)( ( (*(pDataline+2))&0xF8 ) | ( (*(pDataline+1)>>5 ) ) );
+ *pScanline = (mng_uint8)( ( *(pDataline) >>3 ) | ( (*(pDataline+1)&0xFC ) << 3) );
+ *(pScanline+2) = *(pDataline+3);
+
+ pScanline += (pData->iColinc * 3);
+ pDataline += 4;
+ }
+ }
+ }
+ else
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* get alpha values */
+ iFGa16 = mng_get_uint16 (pDataline+6);
+ iBGa16 = (mng_uint16)(*(pScanline+2));
+ iBGa16 = (mng_uint16)(iBGa16 << 8) | iBGa16;
+
+ if (iFGa16) /* any opacity at all ? */
+ { /* fully opaque or background fully transparent ? */
+ if ((iFGa16 == 0xFFFF) || (iBGa16 == 0))
+ { /* plain copy it */
+ *(pScanline+1) = (mng_uint8)( (*(pDataline+4))&0xF8 ) | (mng_uint8)( (*(pDataline+2)>>5 ) );
+ *pScanline = (mng_uint8)( (*(pDataline)) >>3) | (mng_uint8)( (*(pDataline+2)&0xFC) << 3);
+ *(pScanline+2) = *(pDataline+6);
+ }
+ else
+ {
+ if (iBGa16 == 0xFFFF) /* background fully opaque ? */
+ { /* get the proper values */
+ iFGr16 = mng_get_uint16 (pDataline );
+ iFGg16 = mng_get_uint16 (pDataline+2);
+ iFGb16 = mng_get_uint16 (pDataline+4);
+ /* scale background up */
+ iBGr16 = (mng_uint16)( (*(pScanline+1)) & 0xF8 );
+ iBGg16 = (mng_uint16)( (*(pScanline+1) << 5) | (((*(pScanline )) & 0xE0) >>3 ) );
+ iBGb16 = (mng_uint16)( (*(pScanline )) << 3 );
+
+ iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
+ iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
+ iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
+
+ /* now compose */
+ MNG_COMPOSE16(iFGr16, iFGr16, iFGa16, iBGr16);
+ MNG_COMPOSE16(iFGg16, iFGg16, iFGa16, iBGg16);
+ MNG_COMPOSE16(iFGb16, iFGb16, iFGa16, iBGb16);
+ /* and return the composed values */
+ *(pScanline+1) = (mng_uint8) ( ( (iFGb16 >> 8)&0xF8 ) | ( (mng_uint8)(iFGg16>>8) >> 5) );
+ *pScanline = (mng_uint8) ( ( (iFGr16>>11) ) | (((mng_uint8)(iFGg16>>8)&0xFC) << 3) );
+ }
+ else
+ { /* scale background up */
+ iBGr16 = (mng_uint16)( (*(pScanline+1)) & 0xF8 );
+ iBGg16 = (mng_uint16)( (*(pScanline+1) << 5) | (((*(pScanline )) & 0xE0) >>3 ) );
+ iBGb16 = (mng_uint16)( (*(pScanline )) << 3 );
+
+ iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
+ iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
+ iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
+ /* let's blend */
+ MNG_BLEND16 (mng_get_uint16 (pDataline ),
+ mng_get_uint16 (pDataline+2),
+ mng_get_uint16 (pDataline+4), iFGa16,
+ iBGr16, iBGg16, iBGb16, iBGa16,
+ iCr16, iCg16, iCb16, iCa16);
+ /* and return the composed values */
+ *(pScanline+1) = (mng_uint8) ( ( (iCb16 >> 8) & 0xF8 ) | ( (mng_uint8)(iCg16 >> 8) >> 5 ) );
+ *pScanline = (mng_uint8) ( ( (iCr16 >> 11) ) | (((mng_uint8)(iCg16 >> 8) & 0xFC) << 3) );
+ *(pScanline+2) = (mng_uint8)(iCa16 >> 8);
+ }
+ }
+ }
+
+ pScanline += (pData->iColinc * 3);
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ {
+ iFGa8 = *(pDataline+3); /* get alpha values */
+ iBGa8 = *(pScanline+2);
+
+ if (iFGa8) /* any opacity at all ? */
+ { /* fully opaque or background fully transparent ? */
+ if ((iFGa8 == 0xFF) || (iBGa8 == 0))
+ { /* then simply copy the values */
+ *(pScanline+1) = (mng_uint8)( ( (*(pDataline+2)) &0xF8 ) | (*(pDataline+1) >>5 ) );
+ *pScanline = (mng_uint8)( ( ((*(pDataline))>>3) ) | ((*(pDataline+1)&0xFC) << 3) );
+ *(pScanline+2) = *(pDataline+3);
+ }
+ else
+ {
+ mng_uint8 iRed, iGreen, iBlue;
+
+ iBlue = (mng_uint8) ( *(pScanline+1) & 0xF8 );
+ iGreen = (mng_uint8) ( (*(pScanline+1) << 5) | ( ((*pScanline) & 0xE0)>>3 ) );
+ iRed = (mng_uint8) ( (*pScanline << 3) );
+
+ if (iBGa8 == 0xFF) /* background fully opaque ? */
+ { /* do alpha composing */
+ MNG_COMPOSE8 (iRed, *pDataline, iFGa8, iRed );
+ MNG_COMPOSE8 (iGreen, *(pDataline+1), iFGa8, iGreen );
+ MNG_COMPOSE8 (iBlue, *(pDataline+2), iFGa8, iBlue );
+ /* alpha remains fully opaque !!! */
+ *(pScanline+1) = (mng_uint8) ( ( iBlue & 0xF8 ) | (iGreen>>5) );
+ *pScanline = (mng_uint8) ( ( iRed >> 3 ) | ( (iGreen & 0xFC) << 3) );
+ }
+ else
+ { /* now blend */
+ MNG_BLEND8 (*pDataline, *(pDataline+1), *(pDataline+2), iFGa8,
+ iRed , iGreen , iBlue , iBGa8,
+ iCr8, iCg8, iCb8, iCa8);
+ /* and return the composed values */
+
+
+ *pScanline = (mng_uint8) ( ( iCr8 >> 3 ) | ( (iCg8 & 0xFC) << 3) );
+ *(pScanline+1) = (mng_uint8) ( ( iCb8 & 0xF8 ) | (iCg8>>5) );
+ *(pScanline+2) = (mng_uint8) iCa8;
+ }
+ }
+ }
+
+ pScanline += (pData->iColinc *3);
+ pDataline += 4;
+ }
+ }
+ }
+ }
+
+ check_update_region (pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_RGBA565, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#else /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
+mng_retcode mng_display_rgba565 (mng_datap pData)
+{
+ mng_uint8p pScanline;
+ mng_uint8p pDataline;
+ mng_int32 iX;
+ mng_uint8 iFGa8, iBGa8, iCa8;
+ mng_uint16 iFGa16, iBGa16, iCa16;
+ mng_uint16 iFGr16, iFGg16, iFGb16;
+ mng_uint16 iBGr16, iBGg16, iBGb16;
+ mng_uint16 iCr16, iCg16, iCb16;
+ mng_uint8 iCr8, iCg8, iCb8;
+ mng_uint8 iBps;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_RGBA565, MNG_LC_START);
+#endif
+
+ iBps=(mng_uint8)(pData->bIsRGBA16 ? 2:1);
+ /* viewable row ? */
+ if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
+ { /* address destination row */
+ pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ /* adjust destination row starting-point */
+ pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl * 3);
+ pDataline = pData->pRGBArow; /* address source row */
+
+ /* adjust source row starting-point */
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << (iBps+1));
+
+ if (pData->bIsOpaque) /* forget about transparency ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* scale down by dropping the LSB */
+ *(pScanline+1) = (mng_uint8)( ( (*(pDataline+2*iBps))&0xF8 ) |
+ ( (*(pDataline+iBps)>>5) ) );
+ *pScanline = (mng_uint8)( ( (*(pDataline)) >>3) |
+ ( (*(pDataline+iBps)&0xFC) << 3) );
+ *(pScanline+2) = *(pDataline+3*iBps);
+
+ pScanline += (pData->iColinc * 3);
+ pDataline += 4*iBps;
+ }
+ }
+ else
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* get alpha values */
+ iFGa16 = mng_get_uint16 (pDataline+6);
+ iBGa16 = (mng_uint16)(*(pScanline+2));
+ iBGa16 = (mng_uint16)(iBGa16 << 8) | iBGa16;
+
+ if (iFGa16) /* any opacity at all ? */
+ { /* fully opaque or background fully transparent ? */
+ if ((iFGa16 == 0xFFFF) || (iBGa16 == 0))
+ { /* plain copy it */
+ *(pScanline+1) = (mng_uint8)( (*(pDataline+4))&0xF8 ) | (mng_uint8)( (*(pDataline+2)>>5 ) );
+ *pScanline = (mng_uint8)( (*(pDataline)) >>3) | (mng_uint8)( (*(pDataline+2)&0xFC) << 3);
+ *(pScanline+2) = *(pDataline+6);
+ }
+ else
+ {
+ if (iBGa16 == 0xFFFF) /* background fully opaque ? */
+ { /* get the proper values */
+ iFGr16 = mng_get_uint16 (pDataline );
+ iFGg16 = mng_get_uint16 (pDataline+2);
+ iFGb16 = mng_get_uint16 (pDataline+4);
+ /* scale background up */
+ iBGr16 = (mng_uint16)( (*(pScanline+1)) & 0xF8 );
+ iBGg16 = (mng_uint16)( (*(pScanline+1) << 5) | (((*(pScanline )) & 0xE0) >>3 ) );
+ iBGb16 = (mng_uint16)( (*(pScanline )) << 3 );
+
+ iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
+ iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
+ iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
+
+ /* now compose */
+ MNG_COMPOSE16(iFGr16, iFGr16, iFGa16, iBGr16);
+ MNG_COMPOSE16(iFGg16, iFGg16, iFGa16, iBGg16);
+ MNG_COMPOSE16(iFGb16, iFGb16, iFGa16, iBGb16);
+ /* and return the composed values */
+ *(pScanline+1) = (mng_uint8) ( ( (iFGb16 >> 8)&0xF8 ) | ( (mng_uint8)(iFGg16>>8) >> 5) );
+ *pScanline = (mng_uint8) ( ( (iFGr16>>11) ) | (((mng_uint8)(iFGg16>>8)&0xFC) << 3) );
+ }
+ else
+ { /* scale background up */
+ iBGr16 = (mng_uint16)( (*(pScanline+1)) & 0xF8 );
+ iBGg16 = (mng_uint16)( (*(pScanline+1) << 5) | (((*(pScanline )) & 0xE0) >>3 ) );
+ iBGb16 = (mng_uint16)( (*(pScanline )) << 3 );
+
+ iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
+ iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
+ iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
+ /* let's blend */
+ MNG_BLEND16 (mng_get_uint16 (pDataline ),
+ mng_get_uint16 (pDataline+2),
+ mng_get_uint16 (pDataline+4), iFGa16,
+ iBGr16, iBGg16, iBGb16, iBGa16,
+ iCr16, iCg16, iCb16, iCa16);
+ /* and return the composed values */
+ *(pScanline+1) = (mng_uint8) ( ( (iCb16 >> 8) & 0xF8 ) | ( (mng_uint8)(iCg16 >> 8) >> 5 ) );
+ *pScanline = (mng_uint8) ( ( (iCr16 >> 11) ) | (((mng_uint8)(iCg16 >> 8) & 0xFC) << 3) );
+ *(pScanline+2) = (mng_uint8)(iCa16 >> 8);
+ }
+ }
+ }
+
+ pScanline += (pData->iColinc * 3);
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ {
+ iFGa8 = *(pDataline+3); /* get alpha values */
+ iBGa8 = *(pScanline+2);
+
+ if (iFGa8) /* any opacity at all ? */
+ { /* fully opaque or background fully transparent ? */
+ if ((iFGa8 == 0xFF) || (iBGa8 == 0))
+ { /* then simply copy the values */
+ *(pScanline+1) = (mng_uint8)( ( (*(pDataline+2)) &0xF8 ) | (*(pDataline+1) >>5 ) );
+ *pScanline = (mng_uint8)( ( ((*(pDataline))>>3) ) | ((*(pDataline+1)&0xFC) << 3) );
+ *(pScanline+2) = *(pDataline+3);
+ }
+ else
+ {
+ mng_uint8 iRed, iGreen, iBlue;
+
+ iBlue = (mng_uint8) ( *(pScanline+1) & 0xF8 );
+ iGreen = (mng_uint8) ( (*(pScanline+1) << 5) | ( ((*pScanline) & 0xE0)>>3 ) );
+ iRed = (mng_uint8) ( (*pScanline << 3) );
+
+ if (iBGa8 == 0xFF) /* background fully opaque ? */
+ { /* do alpha composing */
+ MNG_COMPOSE8 (iRed, *pDataline, iFGa8, iRed );
+ MNG_COMPOSE8 (iGreen, *(pDataline+1), iFGa8, iGreen );
+ MNG_COMPOSE8 (iBlue, *(pDataline+2), iFGa8, iBlue );
+ /* alpha remains fully opaque !!! */
+ *(pScanline+1) = (mng_uint8) ( ( iBlue & 0xF8 ) | (iGreen>>5) );
+ *pScanline = (mng_uint8) ( ( iRed >> 3 ) | ( (iGreen & 0xFC) << 3) );
+ }
+ else
+ { /* now blend */
+ MNG_BLEND8 (*pDataline, *(pDataline+1), *(pDataline+2), iFGa8,
+ iRed , iGreen , iBlue , iBGa8,
+ iCr8, iCg8, iCb8, iCa8);
+ /* and return the composed values */
+
+
+ *pScanline = (mng_uint8) ( ( iCr8 >> 3 ) | ( (iCg8 & 0xFC) << 3) );
+ *(pScanline+1) = (mng_uint8) ( ( iCb8 & 0xF8 ) | (iCg8>>5) );
+ *(pScanline+2) = (mng_uint8) iCa8;
+ }
+ }
+ }
+
+ pScanline += (pData->iColinc *3);
+ pDataline += 4;
+ }
+ }
+ }
+ }
+
+ check_update_region (pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_RGBA565, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
+#else /* MNG_NO_16BIT_SUPPORT */
+mng_retcode mng_display_rgba565 (mng_datap pData)
+{
+ mng_uint8p pScanline;
+ mng_uint8p pDataline;
+ mng_int32 iX;
+ mng_uint8 iFGa8, iBGa8, iCa8;
+ mng_uint8 iCr8, iCg8, iCb8;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_RGBA565, MNG_LC_START);
+#endif
+ /* viewable row ? */
+ if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
+ { /* address destination row */
+ pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ /* adjust destination row starting-point */
+ pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl * 3);
+ pDataline = pData->pRGBArow; /* address source row */
+
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
+
+ if (pData->bIsOpaque) /* forget about transparency ? */
+ {
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* copy the values */
+ *(pScanline+1) = (mng_uint8)( ( (*(pDataline+2))&0xF8 ) | ( (*(pDataline+1)>>5 ) ) );
+ *pScanline = (mng_uint8)( ( *(pDataline) >>3 ) | ( (*(pDataline+1)&0xFC ) << 3) );
+ *(pScanline+2) = *(pDataline+3);
+
+ pScanline += (pData->iColinc * 3);
+ pDataline += 4;
+ }
+ }
+ }
+ else
+ {
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ {
+ iFGa8 = *(pDataline+3); /* get alpha values */
+ iBGa8 = *(pScanline+2);
+
+ if (iFGa8) /* any opacity at all ? */
+ { /* fully opaque or background fully transparent ? */
+ if ((iFGa8 == 0xFF) || (iBGa8 == 0))
+ { /* then simply copy the values */
+ *(pScanline+1) = (mng_uint8)( ( (*(pDataline+2)) &0xF8 ) | (*(pDataline+1) >>5 ) );
+ *pScanline = (mng_uint8)( ( ((*(pDataline))>>3) ) | ((*(pDataline+1)&0xFC) << 3) );
+ *(pScanline+2) = *(pDataline+3);
+ }
+ else
+ {
+ mng_uint8 iRed, iGreen, iBlue;
+
+ iBlue = (mng_uint8) ( *(pScanline+1) & 0xF8 );
+ iGreen = (mng_uint8) ( (*(pScanline+1) << 5) | ( ((*pScanline) & 0xE0)>>3 ) );
+ iRed = (mng_uint8) ( (*pScanline << 3) );
+
+ if (iBGa8 == 0xFF) /* background fully opaque ? */
+ { /* do alpha composing */
+ MNG_COMPOSE8 (iRed, *pDataline, iFGa8, iRed );
+ MNG_COMPOSE8 (iGreen, *(pDataline+1), iFGa8, iGreen );
+ MNG_COMPOSE8 (iBlue, *(pDataline+2), iFGa8, iBlue );
+ /* alpha remains fully opaque !!! */
+ *(pScanline+1) = (mng_uint8) ( ( iBlue & 0xF8 ) | (iGreen>>5) );
+ *pScanline = (mng_uint8) ( ( iRed >> 3 ) | ( (iGreen & 0xFC) << 3) );
+ }
+ else
+ { /* now blend */
+ MNG_BLEND8 (*pDataline, *(pDataline+1), *(pDataline+2), iFGa8,
+ iRed , iGreen , iBlue , iBGa8,
+ iCr8, iCg8, iCb8, iCa8);
+ /* and return the composed values */
+
+
+ *pScanline = (mng_uint8) ( ( iCr8 >> 3 ) | ( (iCg8 & 0xFC) << 3) );
+ *(pScanline+1) = (mng_uint8) ( ( iCb8 & 0xF8 ) | (iCg8>>5) );
+ *(pScanline+2) = (mng_uint8) iCa8;
+ }
+ }
+ }
+
+ pScanline += (pData->iColinc *3);
+ pDataline += 4;
+ }
+ }
+ }
+ }
+
+ check_update_region (pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_RGBA565, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_NO_16BIT_SUPPORT */
+#endif /* MNG_SKIPCANVAS_RGBA565 */
+
+/* ************************************************************************** */
+
+#ifndef MNG_SKIPCANVAS_BGR565_A8
+#ifndef MNG_NO_16BIT_SUPPORT
+#ifndef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
+mng_retcode mng_display_bgr565_a8 (mng_datap pData)
+{
+ mng_uint8p pScanline;
+ mng_uint8p pAlphaline;
+ mng_uint8p pDataline;
+ mng_int32 iX;
+ mng_uint16 iA16;
+ mng_uint16 iFGr16, iFGg16, iFGb16;
+ mng_uint16 iBGr16, iBGg16, iBGb16, iBGa16;
+ mng_uint16 iCr16, iCg16, iCb16, iCa16;
+ mng_uint8 iA8, iBGa8, iCa8;
+ mng_uint8 iCr8, iCg8, iCb8;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_BGR565_A8, MNG_LC_START);
+#endif
+ /* viewable row ? */
+ if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
+ { /* address destination row */
+ pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ pAlphaline = (mng_uint8p)pData->fGetalphaline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ /* adjust destination row
+starting-point */
+ pScanline = pScanline + (pData->iCol * 2) + (pData->iDestl * 2);
+ pAlphaline = pAlphaline + pData->iCol + pData->iDestl;
+ pDataline = pData->pRGBArow; /* address source row */
+
+ if (pData->bIsRGBA16) /* adjust source row starting-point */
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 3);
+ else
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
+
+ if (pData->bIsOpaque) /* forget about transparency ? */
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* scale down by dropping the LSB */
+ *(pScanline+1) = (mng_uint8)( ( (*(pDataline))&0xF8 ) | ((*(pDataline+2)>>5) ) );
+ *pScanline = (mng_uint8)( ( (*(pDataline+4)) >>3) | ((*(pDataline+2)&0xFC) << 3) );
+ *pAlphaline = (mng_uint8)(*(pDataline+6));
+
+ pScanline += (pData->iColinc * 2);
+ pAlphaline += pData->iColinc;
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* copy the values */
+ *(pScanline+1) = (mng_uint8)( ( (*(pDataline))&0xF8 ) | ((*(pDataline+1)>>5 ) ) );
+ *pScanline = (mng_uint8)( ( *(pDataline+2) >>3 ) | ((*(pDataline+1)&0xFC ) << 3) );
+ *pAlphaline = (mng_uint8)(*(pDataline+3));
+
+ pScanline += (pData->iColinc * 2);
+ pAlphaline += pData->iColinc;
+ pDataline += 4;
+ }
+ }
+ }
+ else /* Not fully opaque */
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ {
+ iA16 = mng_get_uint16 (pDataline+6);
+ iBGa16 = (mng_uint16)(*pAlphaline);
+ iBGa16 = (mng_uint16)(iBGa16 << 8) | iBGa16;
+
+ if (iA16) /* any opacity at all ? */
+ {
+ if ((iA16 == 0xFFFF) || (iBGa16 == 0)) /* fully opaque or background fully transparent ? */
+ { /* scale down by dropping the LSB */
+ *(pScanline+1) = (mng_uint8)( (*(pDataline))&0xF8 ) | (mng_uint8)( (*(pDataline+2)>>5 ) );
+ *pScanline = (mng_uint8)( (*(pDataline+4)) >>3) | (mng_uint8)( (*(pDataline+2)&0xFC) << 3);
+ *pAlphaline = *(pDataline+6);
+ }
+ else
+ {
+ if (iBGa16 == 0xFFFF) /* background fully opaque ? */
+ {
+ /* get the proper values */
+ iFGr16 = mng_get_uint16 (pDataline );
+ iFGg16 = mng_get_uint16 (pDataline+2);
+ iFGb16 = mng_get_uint16 (pDataline+4);
+ /* scale background up */
+
+ iBGb16 = (mng_uint16)( (*(pScanline+1)) & 0xF8 );
+ iBGg16 = (mng_uint16)( (*(pScanline+1) << 5) | (((*(pScanline )) & 0xE0) >>3 ) );
+ iBGr16 = (mng_uint16)( (*(pScanline )) << 3 );
+
+ iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
+ iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
+ iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
+ /* now compose */
+ MNG_COMPOSE16(iFGr16, iFGr16, iA16, iBGr16);
+ MNG_COMPOSE16(iFGg16, iFGg16, iA16, iBGg16);
+ MNG_COMPOSE16(iFGb16, iFGb16, iA16, iBGb16);
+ /* and return the composed values */
+ *(pScanline+1) = (mng_uint8) ( ( (iFGr16 >> 8)&0xF8 ) | ( (mng_uint8)(iFGg16>>8) >> 5) );
+ *pScanline = (mng_uint8) ( ( (iFGb16>>11) ) | (((mng_uint8)(iFGg16>>8)&0xFC) << 3) );
+ *pAlphaline = (mng_uint8)(iA16>>8);
+ }
+ else /* background is not fully opaque */
+ { /* scale background up */
+ iBGb16 = (mng_uint16)( (*(pScanline+1)) & 0xF8 );
+ iBGg16 = (mng_uint16)( (*(pScanline+1) << 5) | (((*(pScanline )) & 0xE0) >>3 ) );
+ iBGr16 = (mng_uint16)( (*(pScanline )) << 3 );
+
+ iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
+ iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
+ iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
+ /* let's blend */
+ MNG_BLEND16 (mng_get_uint16 (pDataline ),
+ mng_get_uint16 (pDataline+2),
+ mng_get_uint16 (pDataline+4), iA16,
+ iBGr16, iBGg16, iBGb16, iBGa16,
+ iCr16, iCg16, iCb16, iCa16);
+ /* and return the composed values */
+ *(pScanline+1) = (mng_uint8) ( ( (iCr16 >> 8)&0xF8 ) | ( (mng_uint8)(iCg16>>8) >> 5) );
+ *pScanline = (mng_uint8) ( ( (iCb16>>11) ) | (((mng_uint8)(iCg16>>8)&0xFC) << 3) );
+ *pAlphaline = (mng_uint8)(iCa16 >> 8);
+ }
+ }
+ }
+
+ pScanline += (pData->iColinc * 2);
+ pAlphaline += pData->iColinc;
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+iX += pData->iColinc)
+ {
+ iA8 = *(pDataline+3); /* get alpha value */
+ iBGa8 = *pAlphaline;
+
+ if (iA8) /* any opacity at all ? */
+ { /* fully opaque or background fully transparent ? */
+ if ((iA8 == 0xFF) || (iBGa8 == 0))
+ { /* then simply copy the values */
+ *(pScanline+1) = (mng_uint8)( ( (*(pDataline)) &0xF8 ) | (*(pDataline+1) >>5 ) );
+ *pScanline = (mng_uint8)( ( ((*(pDataline+2))>>3) ) | ((*(pDataline+1)&0xFC) << 3) );
+ *pAlphaline = *(pDataline+3);
+ }
+ else
+ {
+ if (iBGa8 == 0xFF) /* background fully opaque ? */
+ {
+ /* do alpha composing */
+ mng_uint8 iRed, iGreen, iBlue;
+
+ iRed = (mng_uint8) ( *(pScanline+1) & 0xF8 );
+ iGreen = (mng_uint8) ( (*(pScanline+1) << 5) | (((*pScanline) & 0xE0)>>3 ) );
+ iBlue = (mng_uint8) ( (*pScanline << 3) );
+
+ MNG_COMPOSE8 (iRed, *pDataline, iA8, iRed );
+ MNG_COMPOSE8 (iGreen, *(pDataline+1), iA8, iGreen );
+ MNG_COMPOSE8 (iBlue, *(pDataline+2), iA8, iBlue );
+
+ *(pScanline+1) = (mng_uint8) ( ( iRed & 0xF8 ) | (iGreen>>5) );
+ *pScanline = (mng_uint8) ( ( iBlue >> 3 ) | ((iGreen & 0xFC) << 3) );
+ *pAlphaline = iA8;
+ }
+ else /* background not fully opaque */
+ {
+ MNG_BLEND8 (*pDataline, *(pDataline+1), *(pDataline+2), iA8,
+ *pScanline, *(pScanline+1), *(pScanline+2), iBGa8,
+ iCr8, iCg8, iCb8, iCa8);
+ /* and return the composed values */
+ *(pScanline+1) = (mng_uint8) ( ( iCr8 & 0xF8 ) | (iCg8>>5) );
+ *pScanline = (mng_uint8) ( ( iCb8 >> 3 ) | ((iCg8 & 0xFC) << 3) );
+ *pAlphaline = iCa8;
+ }
+ }
+ }
+
+ pScanline += (pData->iColinc * 2);
+ pAlphaline += pData->iColinc;
+ pDataline += 4;
+ }
+ }
+ }
+ }
+
+ check_update_region (pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_BGR565_A8, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#else /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
+mng_retcode mng_display_bgr565_a8 (mng_datap pData)
+{
+ mng_uint8p pScanline;
+ mng_uint8p pAlphaline;
+ mng_uint8p pDataline;
+ mng_int32 iX;
+ mng_uint16 iA16;
+ mng_uint16 iFGr16, iFGg16, iFGb16;
+ mng_uint16 iBGr16, iBGg16, iBGb16, iBGa16;
+ mng_uint16 iCr16, iCg16, iCb16, iCa16;
+ mng_uint8 iA8, iBGa8, iCa8;
+ mng_uint8 iCr8, iCg8, iCb8;
+ mng_uint8 iBps;
+
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_BGR565_A8, MNG_LC_START);
+#endif
+
+ iBps=(mng_uint8)(pData->bIsRGBA16 ? 2:1);
+ /* viewable row ? */
+ if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
+ { /* address destination row */
+ pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ pAlphaline = (mng_uint8p)pData->fGetalphaline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ /* adjust destination row
+starting-point */
+ pScanline = pScanline + (pData->iCol * 2) + (pData->iDestl * 2);
+ pAlphaline = pAlphaline + pData->iCol + pData->iDestl;
+ pDataline = pData->pRGBArow; /* address source row */
+
+ /* adjust source row starting-point */
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << (iBps+1));
+
+ if (pData->bIsOpaque) /* forget about transparency ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* scale down by dropping the LSB */
+ *(pScanline+1) = (mng_uint8)( ( (*(pDataline))&0xF8 ) |
+ ((*(pDataline+iBps)>>5) ) );
+ *pScanline = (mng_uint8)( ( (*(pDataline+2*iBps)) >>3) |
+ ((*(pDataline+iBps)&0xFC) << 3) );
+ *pAlphaline = (mng_uint8)(*(pDataline+6));
+
+ pScanline += (pData->iColinc * 2);
+ pAlphaline += pData->iColinc;
+ pDataline += 8;
+ }
+ }
+ else /* Not fully opaque */
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ {
+ iA16 = mng_get_uint16 (pDataline+6);
+ iBGa16 = (mng_uint16)(*pAlphaline);
+ iBGa16 = (mng_uint16)(iBGa16 << 8) | iBGa16;
+
+ if (iA16) /* any opacity at all ? */
+ {
+ if ((iA16 == 0xFFFF) || (iBGa16 == 0)) /* fully opaque or background fully transparent ? */
+ { /* scale down by dropping the LSB */
+ *(pScanline+1) = (mng_uint8)( (*(pDataline))&0xF8 ) | (mng_uint8)( (*(pDataline+2)>>5 ) );
+ *pScanline = (mng_uint8)( (*(pDataline+4)) >>3) | (mng_uint8)( (*(pDataline+2)&0xFC) << 3);
+ *pAlphaline = *(pDataline+6);
+ }
+ else
+ {
+ if (iBGa16 == 0xFFFF) /* background fully opaque ? */
+ {
+ /* get the proper values */
+ iFGr16 = mng_get_uint16 (pDataline );
+ iFGg16 = mng_get_uint16 (pDataline+2);
+ iFGb16 = mng_get_uint16 (pDataline+4);
+ /* scale background up */
+
+ iBGb16 = (mng_uint16)( (*(pScanline+1)) & 0xF8 );
+ iBGg16 = (mng_uint16)( (*(pScanline+1) << 5) | (((*(pScanline )) & 0xE0) >>3 ) );
+ iBGr16 = (mng_uint16)( (*(pScanline )) << 3 );
+
+ iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
+ iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
+ iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
+ /* now compose */
+ MNG_COMPOSE16(iFGr16, iFGr16, iA16, iBGr16);
+ MNG_COMPOSE16(iFGg16, iFGg16, iA16, iBGg16);
+ MNG_COMPOSE16(iFGb16, iFGb16, iA16, iBGb16);
+ /* and return the composed values */
+ *(pScanline+1) = (mng_uint8) ( ( (iFGr16 >> 8)&0xF8 ) | ( (mng_uint8)(iFGg16>>8) >> 5) );
+ *pScanline = (mng_uint8) ( ( (iFGb16>>11) ) | (((mng_uint8)(iFGg16>>8)&0xFC) << 3) );
+ *pAlphaline = (mng_uint8)(iA16>>8);
+ }
+ else /* background is not fully opaque */
+ { /* scale background up */
+ iBGb16 = (mng_uint16)( (*(pScanline+1)) & 0xF8 );
+ iBGg16 = (mng_uint16)( (*(pScanline+1) << 5) | (((*(pScanline )) & 0xE0) >>3 ) );
+ iBGr16 = (mng_uint16)( (*(pScanline )) << 3 );
+
+ iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
+ iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
+ iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
+ /* let's blend */
+ MNG_BLEND16 (mng_get_uint16 (pDataline ),
+ mng_get_uint16 (pDataline+2),
+ mng_get_uint16 (pDataline+4), iA16,
+ iBGr16, iBGg16, iBGb16, iBGa16,
+ iCr16, iCg16, iCb16, iCa16);
+ /* and return the composed values */
+ *(pScanline+1) = (mng_uint8) ( ( (iCr16 >> 8)&0xF8 ) | ( (mng_uint8)(iCg16>>8) >> 5) );
+ *pScanline = (mng_uint8) ( ( (iCb16>>11) ) | (((mng_uint8)(iCg16>>8)&0xFC) << 3) );
+ *pAlphaline = (mng_uint8)(iCa16 >> 8);
+ }
+ }
+ }
+
+ pScanline += (pData->iColinc * 2);
+ pAlphaline += pData->iColinc;
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+iX += pData->iColinc)
+ {
+ iA8 = *(pDataline+3); /* get alpha value */
+ iBGa8 = *pAlphaline;
+
+ if (iA8) /* any opacity at all ? */
+ { /* fully opaque or background fully transparent ? */
+ if ((iA8 == 0xFF) || (iBGa8 == 0))
+ { /* then simply copy the values */
+ *(pScanline+1) = (mng_uint8)( ( (*(pDataline)) &0xF8 ) | (*(pDataline+1) >>5 ) );
+ *pScanline = (mng_uint8)( ( ((*(pDataline+2))>>3) ) | ((*(pDataline+1)&0xFC) << 3) );
+ *pAlphaline = *(pDataline+3);
+ }
+ else
+ {
+ if (iBGa8 == 0xFF) /* background fully opaque ? */
+ {
+ /* do alpha composing */
+ mng_uint8 iRed, iGreen, iBlue;
+
+ iRed = (mng_uint8) ( *(pScanline+1) & 0xF8 );
+ iGreen = (mng_uint8) ( (*(pScanline+1) << 5) | (((*pScanline) & 0xE0)>>3 ) );
+ iBlue = (mng_uint8) ( (*pScanline << 3) );
+
+ MNG_COMPOSE8 (iRed, *pDataline, iA8, iRed );
+ MNG_COMPOSE8 (iGreen, *(pDataline+1), iA8, iGreen );
+ MNG_COMPOSE8 (iBlue, *(pDataline+2), iA8, iBlue );
+
+ *(pScanline+1) = (mng_uint8) ( ( iRed & 0xF8 ) | (iGreen>>5) );
+ *pScanline = (mng_uint8) ( ( iBlue >> 3 ) | ((iGreen & 0xFC) << 3) );
+ *pAlphaline = iA8;
+ }
+ else /* background not fully opaque */
+ {
+ MNG_BLEND8 (*pDataline, *(pDataline+1), *(pDataline+2), iA8,
+ *pScanline, *(pScanline+1), *(pScanline+2), iBGa8,
+ iCr8, iCg8, iCb8, iCa8);
+ /* and return the composed values */
+ *(pScanline+1) = (mng_uint8) ( ( iCr8 & 0xF8 ) | (iCg8>>5) );
+ *pScanline = (mng_uint8) ( ( iCb8 >> 3 ) | ((iCg8 & 0xFC) << 3) );
+ *pAlphaline = iCa8;
+ }
+ }
+ }
+
+ pScanline += (pData->iColinc * 2);
+ pAlphaline += pData->iColinc;
+ pDataline += 4;
+ }
+ }
+ }
+ }
+
+ check_update_region (pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_BGR565_A8, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
+#else /* MNG_NO_16BIT_SUPPORT */
+mng_retcode mng_display_bgr565_a8 (mng_datap pData)
+{
+ mng_uint8p pScanline;
+ mng_uint8p pAlphaline;
+ mng_uint8p pDataline;
+ mng_int32 iX;
+ mng_uint8 iA8, iBGa8, iCa8;
+ mng_uint8 iCr8, iCg8, iCb8;
+
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_BGR565_A8, MNG_LC_START);
+#endif
+ /* viewable row ? */
+ if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
+ { /* address destination row */
+ pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ pAlphaline = (mng_uint8p)pData->fGetalphaline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ /* adjust destination row
+starting-point */
+ pScanline = pScanline + (pData->iCol * 2) + (pData->iDestl * 2);
+ pAlphaline = pAlphaline + pData->iCol + pData->iDestl;
+ pDataline = pData->pRGBArow; /* address source row */
+
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
+
+ if (pData->bIsOpaque) /* forget about transparency ? */
+ {
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* copy the values */
+ *(pScanline+1) = (mng_uint8)( ( (*(pDataline))&0xF8 ) | ((*(pDataline+1)>>5 ) ) );
+ *pScanline = (mng_uint8)( ( *(pDataline+2) >>3 ) | ((*(pDataline+1)&0xFC ) << 3) );
+ *pAlphaline = (mng_uint8)(*(pDataline+3));
+
+ pScanline += (pData->iColinc * 2);
+ pAlphaline += pData->iColinc;
+ pDataline += 4;
+ }
+ }
+ }
+ else /* Not fully opaque */
+ {
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+iX += pData->iColinc)
+ {
+ iA8 = *(pDataline+3); /* get alpha value */
+ iBGa8 = *pAlphaline;
+
+ if (iA8) /* any opacity at all ? */
+ { /* fully opaque or background fully transparent ? */
+ if ((iA8 == 0xFF) || (iBGa8 == 0))
+ { /* then simply copy the values */
+ *(pScanline+1) = (mng_uint8)( ( (*(pDataline)) &0xF8 ) | (*(pDataline+1) >>5 ) );
+ *pScanline = (mng_uint8)( ( ((*(pDataline+2))>>3) ) | ((*(pDataline+1)&0xFC) << 3) );
+ *pAlphaline = *(pDataline+3);
+ }
+ else
+ {
+ if (iBGa8 == 0xFF) /* background fully opaque ? */
+ {
+ /* do alpha composing */
+ mng_uint8 iRed, iGreen, iBlue;
+
+ iRed = (mng_uint8) ( *(pScanline+1) & 0xF8 );
+ iGreen = (mng_uint8) ( (*(pScanline+1) << 5) | (((*pScanline) & 0xE0)>>3 ) );
+ iBlue = (mng_uint8) ( (*pScanline << 3) );
+
+ MNG_COMPOSE8 (iRed, *pDataline, iA8, iRed );
+ MNG_COMPOSE8 (iGreen, *(pDataline+1), iA8, iGreen );
+ MNG_COMPOSE8 (iBlue, *(pDataline+2), iA8, iBlue );
+
+ *(pScanline+1) = (mng_uint8) ( ( iRed & 0xF8 ) | (iGreen>>5) );
+ *pScanline = (mng_uint8) ( ( iBlue >> 3 ) | ((iGreen & 0xFC) << 3) );
+ *pAlphaline = iA8;
+ }
+ else /* background not fully opaque */
+ {
+ MNG_BLEND8 (*pDataline, *(pDataline+1), *(pDataline+2), iA8,
+ *pScanline, *(pScanline+1), *(pScanline+2), iBGa8,
+ iCr8, iCg8, iCb8, iCa8);
+ /* and return the composed values */
+ *(pScanline+1) = (mng_uint8) ( ( iCr8 & 0xF8 ) | (iCg8>>5) );
+ *pScanline = (mng_uint8) ( ( iCb8 >> 3 ) | ((iCg8 & 0xFC) << 3) );
+ *pAlphaline = iCa8;
+ }
+ }
+ }
+
+ pScanline += (pData->iColinc * 2);
+ pAlphaline += pData->iColinc;
+ pDataline += 4;
+ }
+ }
+ }
+ }
+
+ check_update_region (pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_BGR565_A8, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_NO_16BIT_SUPPORT */
+#endif /* MNG_SKIPCANVAS_BGR565_A8 */
+
+/* ************************************************************************** */
+
+#ifndef MNG_SKIPCANVAS_RGB555
+#ifndef MNG_NO_16BIT_SUPPORT
+#ifndef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
+mng_retcode mng_display_rgb555 (mng_datap pData)
+{
+ mng_uint8p pScanline;
+ mng_uint8p pDataline;
+ mng_int32 iX;
+ mng_uint16 iA16;
+ mng_uint16 iFGr16, iFGg16, iFGb16;
+ mng_uint16 iBGr16, iBGg16, iBGb16;
+ mng_uint8 iA8;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_RGB555, MNG_LC_START);
+#endif
+ /* viewable row ? */
+ if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
+ { /* address destination row */
+ pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ /* adjust destination row starting-point */
+ pScanline = pScanline + (pData->iCol * 2) + (pData->iDestl * 2);
+ pDataline = pData->pRGBArow; /* address source row */
+
+ if (pData->bIsRGBA16) /* adjust source row starting-point */
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 3);
+ else
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
+
+ if (pData->bIsOpaque) /* forget about transparency ? */
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* scale down by dropping the LSB */
+ *(pScanline+1) = (mng_uint8)( ((*(pDataline+4) & 0xF8) >> 1 ) | (*(pDataline+2) >> 6 ) );
+ *pScanline = (mng_uint8)( ( *(pDataline ) >> 3 ) | ((*(pDataline+2) & 0xF8) << 2 ) );
+
+ pScanline += (pData->iColinc * 2);
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* copy the values */
+ *(pScanline+1) = (mng_uint8)( ((*(pDataline+2) & 0xF8) >> 1 ) | (*(pDataline+1) >> 6 ) );
+ *pScanline = (mng_uint8)( ( *(pDataline ) >> 3 ) | ((*(pDataline+1) & 0xF8) << 2 ) );
+
+ pScanline += (pData->iColinc * 2);
+ pDataline += 4;
+ }
+ }
+ }
+ else
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ {
+ iA16 = mng_get_uint16 (pDataline+6);
+
+ if (iA16) /* any opacity at all ? */
+ {
+ if (iA16 == 0xFFFF) /* fully opaque ? */
+ { /* scale down by dropping the LSB */
+ *(pScanline+1) = (mng_uint8)( ((*(pDataline+4) & 0xF8) >> 1 ) | (*(pDataline+2) >> 6 ) );
+ *pScanline = (mng_uint8)( ( *(pDataline ) >> 3 ) | ((*(pDataline+2) & 0xF8) << 2 ) );
+ }
+ else
+ { /* get the proper values */
+ iFGr16 = mng_get_uint16 (pDataline );
+ iFGg16 = mng_get_uint16 (pDataline+2);
+ iFGb16 = mng_get_uint16 (pDataline+4);
+
+ /* scale background up */
+ iBGr16 = (mng_uint8)( (*(pScanline+1) & 0xF8) << 1 );
+ iBGg16 = (mng_uint8)( (*(pScanline+1) << 6 ) | ( ((*pScanline) & 0xE0) >> 2 ) );
+ iBGb16 = (mng_uint8)( *(pScanline ) << 3 );
+
+ iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
+ iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
+ iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
+ /* now compose */
+ MNG_COMPOSE16(iFGr16, iFGr16, iA16, iBGr16);
+ MNG_COMPOSE16(iFGg16, iFGg16, iA16, iBGg16);
+ MNG_COMPOSE16(iFGb16, iFGb16, iA16, iBGb16);
+ /* and return the composed values */
+ *(pScanline+1) = (mng_uint8)( (mng_uint8)(((iFGb16 >> 8) & 0xF8) >> 1 ) | ( (mng_uint8)(iFGg16 >> 8) >> 6 ) );
+ *pScanline = (mng_uint8)( (mng_uint8) ((iFGr16 >>11) >> 3 ) | ( ( (mng_uint8)(iFGg16 >> 8) & 0xF8) << 2 ) );
+ }
+ }
+
+ pScanline += (pData->iColinc * 2);
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ {
+ iA8 = *(pDataline+3); /* get alpha value */
+
+ if (iA8) /* any opacity at all ? */
+ {
+ if (iA8 == 0xFF) /* fully opaque ? */
+ { /* then simply copy the values */
+ *(pScanline+1) = (mng_uint8)( ((*(pDataline+2) & 0xF8) >> 1 ) | (*(pDataline+1) >> 6 ) );
+ *pScanline = (mng_uint8)( ( *(pDataline ) >> 3 ) | ((*(pDataline+1) & 0xF8) << 2 ) );
+ }
+ else
+ { /* do alpha composing */
+ mng_uint8 iRed, iGreen, iBlue;
+
+ iRed = (mng_uint8)( (*(pScanline+1) & 0xF8) << 1 );
+ iGreen = (mng_uint8)( (*(pScanline+1) << 6 ) | ( ((*pScanline) & 0xE0) >> 2 ) );
+ iBlue = (mng_uint8)( *(pScanline ) << 3 );
+
+ MNG_COMPOSE8 (iRed, *(pDataline+2), iA8, iRed );
+ MNG_COMPOSE8 (iGreen, *(pDataline+1), iA8, iGreen );
+ MNG_COMPOSE8 (iBlue, *(pDataline+0), iA8, iBlue );
+
+ *(pScanline+1) = (mng_uint8)( ( (iRed & 0xF8) >> 1 ) | ( iGreen >> 6 ) );
+ *pScanline = (mng_uint8)( (iBlue >> 3 ) | ( (iGreen & 0xF8) << 2 ) );
+ }
+ }
+
+ pScanline += (pData->iColinc * 2);
+ pDataline += 4;
+ }
+ }
+ }
+ }
+
+ check_update_region (pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_RGB555, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#else /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
+mng_retcode mng_display_rgb555 (mng_datap pData)
+{
+ mng_uint8p pScanline;
+ mng_uint8p pDataline;
+ mng_int32 iX;
+ mng_uint16 iA16;
+ mng_uint16 iFGr16, iFGg16, iFGb16;
+ mng_uint16 iBGr16, iBGg16, iBGb16;
+ mng_uint8 iA8;
+ mng_uint8 iBps;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_RGB555, MNG_LC_START);
+#endif
+
+ iBps=(mng_uint8)(pData->bIsRGBA16 ? 2:1);
+ /* viewable row ? */
+ if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
+ { /* address destination row */
+ pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ /* adjust destination row starting-point */
+ pScanline = pScanline + (pData->iCol * 2) + (pData->iDestl * 2);
+ pDataline = pData->pRGBArow; /* address source row */
+
+ /* adjust source row starting-point */
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << (iBps+1));
+
+ if (pData->bIsOpaque) /* forget about transparency ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* scale down by dropping the LSB */
+ *(pScanline+1) = (mng_uint8)( ((*(pDataline+2*iBps) & 0xF8) >> 1 ) | (*(pDataline+iBps) >> 6 ) );
+ *pScanline = (mng_uint8)( ( *(pDataline ) >> 3 ) | ((*(pDataline+iBps) & 0xF8) << 2 ) );
+
+ pScanline += (pData->iColinc * 2);
+ pDataline += 4*iBps;
+ }
+ }
+ else
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ {
+ iA16 = mng_get_uint16 (pDataline+6);
+
+ if (iA16) /* any opacity at all ? */
+ {
+ if (iA16 == 0xFFFF) /* fully opaque ? */
+ { /* scale down by dropping the LSB */
+ *(pScanline+1) = (mng_uint8)( ((*(pDataline+4) & 0xF8) >> 1 ) | (*(pDataline+2) >> 6 ) );
+ *pScanline = (mng_uint8)( ( *(pDataline ) >> 3 ) | ((*(pDataline+2) & 0xF8) << 2 ) );
+ }
+ else
+ { /* get the proper values */
+ iFGr16 = mng_get_uint16 (pDataline );
+ iFGg16 = mng_get_uint16 (pDataline+2);
+ iFGb16 = mng_get_uint16 (pDataline+4);
+
+ /* scale background up */
+ iBGr16 = (mng_uint8)( (*(pScanline+1) & 0xF8) << 1 );
+ iBGg16 = (mng_uint8)( (*(pScanline+1) << 6 ) | ( ((*pScanline) & 0xE0) >> 2 ) );
+ iBGb16 = (mng_uint8)( *(pScanline ) << 3 );
+
+ iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
+ iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
+ iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
+ /* now compose */
+ MNG_COMPOSE16(iFGr16, iFGr16, iA16, iBGr16);
+ MNG_COMPOSE16(iFGg16, iFGg16, iA16, iBGg16);
+ MNG_COMPOSE16(iFGb16, iFGb16, iA16, iBGb16);
+ /* and return the composed values */
+ *(pScanline+1) = (mng_uint8)( (mng_uint8)(((iFGb16 >> 8) & 0xF8) >> 1 ) | ( (mng_uint8)(iFGg16 >> 8) >> 6 ) );
+ *pScanline = (mng_uint8)( (mng_uint8) ((iFGr16 >>11) >> 3 ) | ( ( (mng_uint8)(iFGg16 >> 8) & 0xF8) << 2 ) );
+ }
+ }
+
+ pScanline += (pData->iColinc * 2);
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ {
+ iA8 = *(pDataline+3); /* get alpha value */
+
+ if (iA8) /* any opacity at all ? */
+ {
+ if (iA8 == 0xFF) /* fully opaque ? */
+ { /* then simply copy the values */
+ *(pScanline+1) = (mng_uint8)( ((*(pDataline+2) & 0xF8) >> 1 ) | (*(pDataline+1) >> 6 ) );
+ *pScanline = (mng_uint8)( ( *(pDataline ) >> 3 ) | ((*(pDataline+1) & 0xF8) << 2 ) );
+ }
+ else
+ { /* do alpha composing */
+ mng_uint8 iRed, iGreen, iBlue;
+
+ iRed = (mng_uint8)( (*(pScanline+1) & 0xF8) << 1 );
+ iGreen = (mng_uint8)( (*(pScanline+1) << 6 ) | ( ((*pScanline) & 0xE0) >> 2 ) );
+ iBlue = (mng_uint8)( *(pScanline ) << 3 );
+
+ MNG_COMPOSE8 (iRed, *(pDataline+2), iA8, iRed );
+ MNG_COMPOSE8 (iGreen, *(pDataline+1), iA8, iGreen );
+ MNG_COMPOSE8 (iBlue, *(pDataline+0), iA8, iBlue );
+
+ *(pScanline+1) = (mng_uint8)( ( (iRed & 0xF8) >> 1 ) | ( iGreen >> 6 ) );
+ *pScanline = (mng_uint8)( (iBlue >> 3 ) | ( (iGreen & 0xF8) << 2 ) );
+ }
+ }
+
+ pScanline += (pData->iColinc * 2);
+ pDataline += 4;
+ }
+ }
+ }
+ }
+
+ check_update_region (pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_RGB555, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
+#else /* MNG_NO_16BIT_SUPPORT */
+mng_retcode mng_display_rgb555 (mng_datap pData)
+{
+ mng_uint8p pScanline;
+ mng_uint8p pDataline;
+ mng_int32 iX;
+ mng_uint8 iA8;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_RGB555, MNG_LC_START);
+#endif
+ /* viewable row ? */
+ if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
+ { /* address destination row */
+ pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ /* adjust destination row starting-point */
+ pScanline = pScanline + (pData->iCol * 2) + (pData->iDestl * 2);
+ pDataline = pData->pRGBArow; /* address source row */
+
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
+
+ if (pData->bIsOpaque) /* forget about transparency ? */
+ {
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* copy the values */
+ *(pScanline+1) = (mng_uint8)( ((*(pDataline+2) & 0xF8) >> 1 ) | (*(pDataline+1) >> 6 ) );
+ *pScanline = (mng_uint8)( ( *(pDataline ) >> 3 ) | ((*(pDataline+1) & 0xF8) << 2 ) );
+
+ pScanline += (pData->iColinc * 2);
+ pDataline += 4;
+ }
+ }
+ }
+ else
+ {
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ {
+ iA8 = *(pDataline+3); /* get alpha value */
+
+ if (iA8) /* any opacity at all ? */
+ {
+ if (iA8 == 0xFF) /* fully opaque ? */
+ { /* then simply copy the values */
+ *(pScanline+1) = (mng_uint8)( ((*(pDataline+2) & 0xF8) >> 1 ) | (*(pDataline+1) >> 6 ) );
+ *pScanline = (mng_uint8)( ( *(pDataline ) >> 3 ) | ((*(pDataline+1) & 0xF8) << 2 ) );
+ }
+ else
+ { /* do alpha composing */
+ mng_uint8 iRed, iGreen, iBlue;
+
+ iRed = (mng_uint8)( (*(pScanline+1) & 0xF8) << 1 );
+ iGreen = (mng_uint8)( (*(pScanline+1) << 6 ) | ( ((*pScanline) & 0xE0) >> 2 ) );
+ iBlue = (mng_uint8)( *(pScanline ) << 3 );
+
+ MNG_COMPOSE8 (iRed, *(pDataline+2), iA8, iRed );
+ MNG_COMPOSE8 (iGreen, *(pDataline+1), iA8, iGreen );
+ MNG_COMPOSE8 (iBlue, *(pDataline+0), iA8, iBlue );
+
+ *(pScanline+1) = (mng_uint8)( ( (iRed & 0xF8) >> 1 ) | ( iGreen >> 6 ) );
+ *pScanline = (mng_uint8)( (iBlue >> 3 ) | ( (iGreen & 0xF8) << 2 ) );
+ }
+ }
+
+ pScanline += (pData->iColinc * 2);
+ pDataline += 4;
+ }
+ }
+ }
+ }
+
+ check_update_region (pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_RGB555, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_NO_16BIT_SUPPORT */
+#endif /* MNG_SKIPCANVAS_RGB555 */
+
+/* ************************************************************************** */
+
+#ifndef MNG_SKIPCANVAS_BGR555
+#ifndef MNG_NO_16BIT_SUPPORT
+#ifndef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
+mng_retcode mng_display_bgr555 (mng_datap pData)
+{
+ mng_uint8p pScanline;
+ mng_uint8p pDataline;
+ mng_int32 iX;
+ mng_uint16 iA16;
+ mng_uint16 iFGr16, iFGg16, iFGb16;
+ mng_uint16 iBGr16, iBGg16, iBGb16;
+ mng_uint8 iA8;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_BGR555, MNG_LC_START);
+#endif
+ /* viewable row ? */
+ if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
+ { /* address destination row */
+ pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ /* adjust destination row starting-point */
+ pScanline = pScanline + (pData->iCol * 2) + (pData->iDestl * 2);
+ pDataline = pData->pRGBArow; /* address source row */
+
+ if (pData->bIsRGBA16) /* adjust source row starting-point */
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 3);
+ else
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
+
+ if (pData->bIsOpaque) /* forget about transparency ? */
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* scale down by dropping the LSB */
+ *(pScanline+1) = (mng_uint8)( ((*(pDataline ) & 0xF8) >> 1 ) | (*(pDataline+2) >> 6 ) );
+ *pScanline = (mng_uint8)( ( *(pDataline+4) >> 3 ) | ((*(pDataline+2) & 0xF8) << 2 ) );
+
+ pScanline += (pData->iColinc * 2);
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* copy the values */
+ *(pScanline+1) = (mng_uint8)( ((*(pDataline ) & 0xF8) >> 1 ) | (*(pDataline+1) >> 6 ) );
+ *pScanline = (mng_uint8)( ( *(pDataline+2) >> 3 ) | ((*(pDataline+1) & 0xF8) << 2 ) );
+
+ pScanline += (pData->iColinc * 2);
+ pDataline += 4;
+ }
+ }
+ }
+ else
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ {
+ iA16 = mng_get_uint16 (pDataline+6);
+
+ if (iA16) /* any opacity at all ? */
+ {
+ if (iA16 == 0xFFFF) /* fully opaque ? */
+ { /* scale down by dropping the LSB */
+ *(pScanline+1) = (mng_uint8)( ((*(pDataline ) & 0xF8) >> 1 ) | (*(pDataline+2) >> 6 ) );
+ *pScanline = (mng_uint8)( ( *(pDataline+4) >> 3 ) | ((*(pDataline+2) & 0xF8) << 2 ) );
+ }
+ else
+ { /* get the proper values */
+ iFGr16 = mng_get_uint16 (pDataline );
+ iFGg16 = mng_get_uint16 (pDataline+2);
+ iFGb16 = mng_get_uint16 (pDataline+4);
+
+ /* scale background up */
+ iBGb16 = (mng_uint8)( (*(pScanline+1) & 0xF8) << 1 );
+ iBGg16 = (mng_uint8)( (*(pScanline+1) << 6 ) | ( ((*pScanline) & 0xE0) >> 2 ) );
+ iBGr16 = (mng_uint8)( *(pScanline ) << 3 );
+
+ iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
+ iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
+ iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
+ /* now compose */
+ MNG_COMPOSE16(iFGr16, iFGr16, iA16, iBGr16);
+ MNG_COMPOSE16(iFGg16, iFGg16, iA16, iBGg16);
+ MNG_COMPOSE16(iFGb16, iFGb16, iA16, iBGb16);
+ /* and return the composed values */
+ *(pScanline+1) = (mng_uint8)( (mng_uint8)(((iFGr16 >> 8) & 0xF8) >> 1 ) | ( (mng_uint8)(iFGg16 >> 8) >> 6 ) );
+ *pScanline = (mng_uint8)( (mng_uint8) ((iFGb16 >>11) >> 3 ) | ( ( (mng_uint8)(iFGg16 >> 8) & 0xF8) << 2 ) );
+ }
+ }
+
+ pScanline += (pData->iColinc * 2);
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ {
+ iA8 = *(pDataline+3); /* get alpha value */
+
+ if (iA8) /* any opacity at all ? */
+ {
+ if (iA8 == 0xFF) /* fully opaque ? */
+ { /* then simply copy the values */
+ *(pScanline+1) = (mng_uint8)( ((*(pDataline ) & 0xF8) >> 1 ) | (*(pDataline+1) >> 6 ) );
+ *pScanline = (mng_uint8)( ( *(pDataline+2) >> 3 ) | ((*(pDataline+1) & 0xF8) << 2 ) );
+ }
+ else
+ { /* do alpha composing */
+ mng_uint8 iRed, iGreen, iBlue;
+
+ iRed = (mng_uint8)( (*(pScanline+1) & 0xF8) << 1 );
+ iGreen = (mng_uint8)( (*(pScanline+1) << 6 ) | ( ((*pScanline) & 0xE0) >> 2 ) );
+ iBlue = (mng_uint8)( *(pScanline ) << 3 );
+
+ MNG_COMPOSE8 (iRed, *(pDataline+0), iA8, iRed );
+ MNG_COMPOSE8 (iGreen, *(pDataline+1), iA8, iGreen );
+ MNG_COMPOSE8 (iBlue, *(pDataline+2), iA8, iBlue );
+
+ *(pScanline+1) = (mng_uint8)( ( (iRed & 0xF8) >> 1 ) | ( iGreen >> 6 ) );
+ *pScanline = (mng_uint8)( (iBlue >> 3 ) | ( (iGreen & 0xF8) << 2 ) );
+ }
+ }
+
+ pScanline += (pData->iColinc * 2);
+ pDataline += 4;
+ }
+ }
+ }
+ }
+
+ check_update_region (pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_BGR555, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#else /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
+mng_retcode mng_display_bgr555 (mng_datap pData)
+{
+ mng_uint8p pScanline;
+ mng_uint8p pDataline;
+ mng_int32 iX;
+ mng_uint16 iA16;
+ mng_uint16 iFGr16, iFGg16, iFGb16;
+ mng_uint16 iBGr16, iBGg16, iBGb16;
+ mng_uint8 iA8;
+ mng_uint8 iBps;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_BGR555, MNG_LC_START);
+#endif
+
+ iBps=(mng_uint8)(pData->bIsRGBA16 ? 2:1);
+ /* viewable row ? */
+ if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
+ { /* address destination row */
+ pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ /* adjust destination row starting-point */
+ pScanline = pScanline + (pData->iCol * 2) + (pData->iDestl * 2);
+ pDataline = pData->pRGBArow; /* address source row */
+
+ /* adjust source row starting-point */
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << (iBps+1));
+
+ if (pData->bIsOpaque) /* forget about transparency ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* scale down by dropping the LSB */
+ *(pScanline+1) = (mng_uint8)( ((*(pDataline ) & 0xF8) >> 1 ) | (*(pDataline+iBps) >> 6 ) );
+ *pScanline = (mng_uint8)( ( *(pDataline+2*iBps) >> 3 ) | ((*(pDataline+iBps) & 0xF8) << 2 ) );
+
+ pScanline += (pData->iColinc * 2);
+ pDataline += 4*iBps;
+ }
+ }
+ else
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ {
+ iA16 = mng_get_uint16 (pDataline+6);
+
+ if (iA16) /* any opacity at all ? */
+ {
+ if (iA16 == 0xFFFF) /* fully opaque ? */
+ { /* scale down by dropping the LSB */
+ *(pScanline+1) = (mng_uint8)( ((*(pDataline ) & 0xF8) >> 1 ) | (*(pDataline+2) >> 6 ) );
+ *pScanline = (mng_uint8)( ( *(pDataline+4) >> 3 ) | ((*(pDataline+2) & 0xF8) << 2 ) );
+ }
+ else
+ { /* get the proper values */
+ iFGr16 = mng_get_uint16 (pDataline );
+ iFGg16 = mng_get_uint16 (pDataline+2);
+ iFGb16 = mng_get_uint16 (pDataline+4);
+
+ /* scale background up */
+ iBGb16 = (mng_uint8)( (*(pScanline+1) & 0xF8) << 1 );
+ iBGg16 = (mng_uint8)( (*(pScanline+1) << 6 ) | ( ((*pScanline) & 0xE0) >> 2 ) );
+ iBGr16 = (mng_uint8)( *(pScanline ) << 3 );
+
+ iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
+ iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
+ iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
+ /* now compose */
+ MNG_COMPOSE16(iFGr16, iFGr16, iA16, iBGr16);
+ MNG_COMPOSE16(iFGg16, iFGg16, iA16, iBGg16);
+ MNG_COMPOSE16(iFGb16, iFGb16, iA16, iBGb16);
+ /* and return the composed values */
+ *(pScanline+1) = (mng_uint8)( (mng_uint8)(((iFGr16 >> 8) & 0xF8) >> 1 ) | ( (mng_uint8)(iFGg16 >> 8) >> 6 ) );
+ *pScanline = (mng_uint8)( (mng_uint8) ((iFGb16 >>11) >> 3 ) | ( ( (mng_uint8)(iFGg16 >> 8) & 0xF8) << 2 ) );
+ }
+ }
+
+ pScanline += (pData->iColinc * 2);
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ {
+ iA8 = *(pDataline+3); /* get alpha value */
+
+ if (iA8) /* any opacity at all ? */
+ {
+ if (iA8 == 0xFF) /* fully opaque ? */
+ { /* then simply copy the values */
+ *(pScanline+1) = (mng_uint8)( ((*(pDataline ) & 0xF8) >> 1 ) | (*(pDataline+1) >> 6 ) );
+ *pScanline = (mng_uint8)( ( *(pDataline+2) >> 3 ) | ((*(pDataline+1) & 0xF8) << 2 ) );
+ }
+ else
+ { /* do alpha composing */
+ mng_uint8 iRed, iGreen, iBlue;
+
+ iRed = (mng_uint8)( (*(pScanline+1) & 0xF8) << 1 );
+ iGreen = (mng_uint8)( (*(pScanline+1) << 6 ) | ( ((*pScanline) & 0xE0) >> 2 ) );
+ iBlue = (mng_uint8)( *(pScanline ) << 3 );
+
+ MNG_COMPOSE8 (iRed, *(pDataline+0), iA8, iRed );
+ MNG_COMPOSE8 (iGreen, *(pDataline+1), iA8, iGreen );
+ MNG_COMPOSE8 (iBlue, *(pDataline+2), iA8, iBlue );
+
+ *(pScanline+1) = (mng_uint8)( ( (iRed & 0xF8) >> 1 ) | ( iGreen >> 6 ) );
+ *pScanline = (mng_uint8)( (iBlue >> 3 ) | ( (iGreen & 0xF8) << 2 ) );
+ }
+ }
+
+ pScanline += (pData->iColinc * 2);
+ pDataline += 4;
+ }
+ }
+ }
+ }
+
+ check_update_region (pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_BGR555, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
+#else /* MNG_NO_16BIT_SUPPORT */
+mng_retcode mng_display_bgr555 (mng_datap pData)
+{
+ mng_uint8p pScanline;
+ mng_uint8p pDataline;
+ mng_int32 iX;
+ mng_uint8 iA8;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_BGR555, MNG_LC_START);
+#endif
+ /* viewable row ? */
+ if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
+ { /* address destination row */
+ pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ /* adjust destination row starting-point */
+ pScanline = pScanline + (pData->iCol * 2) + (pData->iDestl * 2);
+ pDataline = pData->pRGBArow; /* address source row */
+
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
+
+ if (pData->bIsOpaque) /* forget about transparency ? */
+ {
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ { /* copy the values */
+ *(pScanline+1) = (mng_uint8)( ((*(pDataline ) & 0xF8) >> 1 ) | (*(pDataline+1) >> 6 ) );
+ *pScanline = (mng_uint8)( ( *(pDataline+2) >> 3 ) | ((*(pDataline+1) & 0xF8) << 2 ) );
+
+ pScanline += (pData->iColinc * 2);
+ pDataline += 4;
+ }
+ }
+ }
+ else
+ {
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
+ iX += pData->iColinc)
+ {
+ iA8 = *(pDataline+3); /* get alpha value */
+
+ if (iA8) /* any opacity at all ? */
+ {
+ if (iA8 == 0xFF) /* fully opaque ? */
+ { /* then simply copy the values */
+ *(pScanline+1) = (mng_uint8)( ((*(pDataline ) & 0xF8) >> 1 ) | (*(pDataline+1) >> 6 ) );
+ *pScanline = (mng_uint8)( ( *(pDataline+2) >> 3 ) | ((*(pDataline+1) & 0xF8) << 2 ) );
+ }
+ else
+ { /* do alpha composing */
+ mng_uint8 iRed, iGreen, iBlue;
+
+ iRed = (mng_uint8)( (*(pScanline+1) & 0xF8) << 1 );
+ iGreen = (mng_uint8)( (*(pScanline+1) << 6 ) | ( ((*pScanline) & 0xE0) >> 2 ) );
+ iBlue = (mng_uint8)( *(pScanline ) << 3 );
+
+ MNG_COMPOSE8 (iRed, *(pDataline+0), iA8, iRed );
+ MNG_COMPOSE8 (iGreen, *(pDataline+1), iA8, iGreen );
+ MNG_COMPOSE8 (iBlue, *(pDataline+2), iA8, iBlue );
+
+ *(pScanline+1) = (mng_uint8)( ( (iRed & 0xF8) >> 1 ) | ( iGreen >> 6 ) );
+ *pScanline = (mng_uint8)( (iBlue >> 3 ) | ( (iGreen & 0xF8) << 2 ) );
+ }
+ }
+
+ pScanline += (pData->iColinc * 2);
+ pDataline += 4;
+ }
+ }
+ }
+ }
+
+ check_update_region (pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_BGR555, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_NO_16BIT_SUPPORT */
+#endif /* MNG_SKIPCANVAS_BGR555 */
+
+
+#ifndef MNG_SKIPCHUNK_BACK
+/* ************************************************************************** */
+/* * * */
+/* * Background restore routines - restore the background with info from * */
+/* * the BACK and/or bKGD chunk or the app's background canvas * */
+/* * * */
+/* ************************************************************************** */
+
+mng_retcode mng_restore_bkgd_backimage (mng_datap pData)
+{
+ /* save some stuff */
+ mng_uint8p pRGBArow = pData->pRGBArow;
+ mng_int32 iRow = pData->iRow;
+ mng_int32 iRowsamples = pData->iRowsamples;
+
+ mng_retcode iRetcode; /* work variables */
+ mng_uint8p pTemp;
+ mng_uint8p pWork = pRGBArow;
+ mng_uint32 iX;
+ mng_int32 iZ;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RESTORE_BACKIMAGE, MNG_LC_START);
+#endif
+ /* determine row to retrieve */
+ pData->iRow = pData->iDestt + iRow + pData->iBackimgoffsy;
+
+ while (pData->iRow >= (mng_int32)pData->iBackimgheight)
+ pData->iRow -= (mng_int32)pData->iBackimgheight;
+ /* set width to that of background image */
+ pData->iRowsamples = pData->iBackimgwidth;
+ /* retrieve into alternate buffer ! */
+ pData->pRGBArow = pData->pPrevrow;
+ /* get it then */
+ iRetcode = ((mng_retrieverow)pData->fRetrieverow) (pData);
+
+ if (iRetcode) /* on error; bail out */
+ return iRetcode;
+ /* we got the full row; but now need to
+ paste it into the proper location */
+ iX = pData->iDestl - pData->iBackimgoffsx;
+
+ while (iX >= pData->iBackimgwidth)
+ iX -= pData->iBackimgwidth;
+
+#ifndef MNG_NO_16BIT_SUPPORT
+ if (pData->bIsRGBA16) /* 16-bit buffer ? */
+ {
+ pTemp = pData->pPrevrow + (iX << 3);
+
+ for (iZ = (pData->iDestr - pData->iDestl); iZ > 0; iZ--)
+ {
+ MNG_COPY (pWork, pTemp, 8);
+
+ pWork += 8;
+ pTemp += 8;
+ iX++;
+ /* reached end of bkgd-image line ? */
+ if (iX >= pData->iBackimgwidth)
+ {
+ iX = 0;
+ pTemp = pData->pPrevrow;
+ }
+ }
+ }
+ else
+#endif
+ {
+ pTemp = pData->pPrevrow + (iX << 2);
+
+ for (iZ = (pData->iDestr - pData->iDestl); iZ > 0; iZ--)
+ {
+ MNG_COPY (pWork, pTemp, 4);
+
+ pWork += 4;
+ pTemp += 4;
+ iX++;
+ /* reached end of bkgd-image line ? */
+ if (iX >= pData->iBackimgwidth)
+ {
+ iX = 0;
+ pTemp = pData->pPrevrow;
+ }
+ }
+ }
+
+ pData->pRGBArow = pRGBArow; /* restore original values */
+ pData->iRow = iRow;
+ pData->iRowsamples = iRowsamples;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RESTORE_BACKIMAGE, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif
+
+/* ************************************************************************** */
+
+mng_retcode mng_restore_bkgd_backcolor (mng_datap pData)
+{
+ mng_int32 iX;
+ mng_uint32p pWork32 = (mng_uint32p)pData->pRGBArow;
+ mng_uint32 iWrite;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RESTORE_BACKCOLOR, MNG_LC_START);
+#endif
+
+#ifdef MNG_BIGENDIAN_SUPPORTED
+ /* fast way for big endian */
+ iWrite = (((mng_uint8)(pData->iBACKred >> 8)) << 24) |
+ (((mng_uint8)(pData->iBACKgreen >> 8)) << 16) |
+ (((mng_uint8)(pData->iBACKblue >> 8)) << 8) |
+ ( 0xFF );
+#elif defined(MNG_LITTLEENDIAN_SUPPORTED)
+ /* fast way for little endian */
+ iWrite = ( 0xFF << 24) |
+ (((mng_uint8)(pData->iBACKblue >> 8)) << 16) |
+ (((mng_uint8)(pData->iBACKgreen >> 8)) << 8) |
+ (((mng_uint8)(pData->iBACKred >> 8)) );
+#else
+ /* generic way, works on all platforms */
+ /* put the data in memory in the correct order */
+ {
+ mng_uint8 aBytes[4];
+ aBytes[0] = (mng_uint8)(pData->iBACKred >> 8);
+ aBytes[1] = (mng_uint8)(pData->iBACKgreen >> 8);
+ aBytes[2] = (mng_uint8)(pData->iBACKblue >> 8);
+ aBytes[3] = 0xFF;
+ /* load that data into a register */
+ iWrite = *(mng_uint32*) aBytes;
+ }
+#endif
+ /* ok; drop the background-color in there */
+ for (iX = (pData->iSourcer - pData->iSourcel); iX > 0; iX--)
+ *pWork32++ = iWrite;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RESTORE_BACKCOLOR, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+#ifndef MNG_SKIPCHUNK_bKGD
+mng_retcode mng_restore_bkgd_bkgd (mng_datap pData)
+{
+ mng_int32 iX;
+ mng_uint8p pWork = pData->pRGBArow;
+ mng_imagep pImage = (mng_imagep)pData->pCurrentobj;
+ mng_imagedatap pBuf = pImage->pImgbuf;
+ mng_uint8 iRed = 0;
+ mng_uint8 iGreen = 0;
+ mng_uint8 iBlue = 0;
+ mng_uint32p pWork32 = (mng_uint32p)pWork;
+ mng_uint32 iWrite;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RESTORE_BKGD, MNG_LC_START);
+#endif
+
+ switch (pBuf->iColortype)
+ {
+ case 0 : ; /* gray types */
+ case 4 : {
+ mng_uint8 iGray;
+
+#ifndef MNG_NO_16BIT_SUPPORT
+ if (pBuf->iBitdepth > 8)
+ iGray = (mng_uint8)(pBuf->iBKGDgray >> 8);
+ else
+#endif
+ {
+#ifndef MNG_NO_1_2_4BIT_SUPPORT
+ /* LBR scaling */
+ mng_uint8 multiplier[]={0,255,85,0,17,0,0,0,1};
+ iGray = (mng_uint8)(multiplier[pBuf->iBitdepth] * pBuf->iBKGDgray);
+#else
+ iGray = (mng_uint8)pBuf->iBKGDgray;
+#endif
+ }
+
+ iRed = iGray;
+ iGreen = iGray;
+ iBlue = iGray;
+
+ break;
+ }
+
+ case 3 : { /* indexed type */
+ iRed = pBuf->aPLTEentries [pBuf->iBKGDindex].iRed;
+ iGreen = pBuf->aPLTEentries [pBuf->iBKGDindex].iGreen;
+ iBlue = pBuf->aPLTEentries [pBuf->iBKGDindex].iBlue;
+
+ break;
+ }
+
+ case 2 : ; /* rgb types */
+ case 6 : {
+#ifndef MNG_NO_16BIT_SUPPORT
+ if (pBuf->iBitdepth > 8)
+ {
+ iRed = (mng_uint8)(pBuf->iBKGDred >> 8);
+ iGreen = (mng_uint8)(pBuf->iBKGDgreen >> 8);
+ iBlue = (mng_uint8)(pBuf->iBKGDblue >> 8);
+ }
+ else
+#endif
+ {
+ iRed = (mng_uint8)(pBuf->iBKGDred );
+ iGreen = (mng_uint8)(pBuf->iBKGDgreen);
+ iBlue = (mng_uint8)(pBuf->iBKGDblue );
+ }
+
+ break;
+ }
+ }
+
+#ifdef MNG_BIGENDIAN_SUPPORTED
+ /* fast way for big endian */
+ iWrite = (iRed << 24) |
+ (iGreen << 16) |
+ (iBlue << 8);
+#elif defined(MNG_LITTLEENDIAN_SUPPORTED)
+ /* fast way for little endian */
+ iWrite = (iBlue << 16) |
+ (iGreen << 8) |
+ (iRed );
+#else
+ /* generic way, works on all platforms */
+ /* put the data in memory in the correct order */
+ {
+ mng_uint8 aBytes[4];
+ aBytes[0] = (mng_uint8)(iRed);
+ aBytes[1] = (mng_uint8)(iGreen);
+ aBytes[2] = (mng_uint8)(iBlue);
+ aBytes[3] = 0x00;
+ /* load that data into a register */
+ iWrite = *(mng_uint32*) aBytes;
+ }
+#endif
+ /* ok; drop it in there */
+ for (iX = (pData->iSourcer - pData->iSourcel); iX > 0; iX--)
+ *pWork32++ = iWrite;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RESTORE_BKGD, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif
+
+/* ************************************************************************** */
+
+mng_retcode mng_restore_bkgd_bgcolor (mng_datap pData)
+{
+ mng_int32 iX;
+ mng_uint32p pWork32 = (mng_uint32p)pData->pRGBArow;
+ mng_uint32 iWrite;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RESTORE_BGCOLOR, MNG_LC_START);
+#endif
+
+#ifdef MNG_BIGENDIAN_SUPPORTED
+ /* fast way for big endian */
+ iWrite = (((mng_uint8)(pData->iBGred >> 8)) << 24) |
+ (((mng_uint8)(pData->iBGgreen >> 8)) << 16) |
+ (((mng_uint8)(pData->iBGblue >> 8)) << 8);
+#elif defined(MNG_LITTLEENDIAN_SUPPORTED)
+ /* fast way for little endian */
+ iWrite = (((mng_uint8)(pData->iBGblue >> 8)) << 16) |
+ (((mng_uint8)(pData->iBGgreen >> 8)) << 8) |
+ (((mng_uint8)(pData->iBGred >> 8)) );
+#else
+ /* generic way, works on all platforms */
+ /* put the data in memory in the correct order */
+ {
+ mng_uint8 aBytes[4];
+ aBytes[0] = (mng_uint8)(pData->iBGred >> 8);
+ aBytes[1] = (mng_uint8)(pData->iBGgreen >> 8);
+ aBytes[2] = (mng_uint8)(pData->iBGblue >> 8);
+ aBytes[3] = 0x00;
+ /* load that data into a register */
+ iWrite = *(mng_uint32*) aBytes;
+ }
+#endif
+ /* ok; drop the background-color in there */
+ for (iX = (pData->iSourcer - pData->iSourcel); iX > 0; iX--)
+ *pWork32++ = iWrite;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RESTORE_BGCOLOR, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+#ifndef MNG_SKIPCANVAS_RGB8
+mng_retcode mng_restore_bkgd_rgb8 (mng_datap pData)
+{
+ mng_int32 iX;
+ mng_uint8p pBkgd;
+ mng_uint8p pWork = pData->pRGBArow;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RESTORE_RGB8, MNG_LC_START);
+#endif
+
+ if (pData->fGetbkgdline) /* can we access the background ? */
+ { /* point to the right pixel then */
+ pBkgd = (mng_uint8p)pData->fGetbkgdline ((mng_handle)pData,
+ pData->iRow + pData->iDestt) +
+ (3 * pData->iDestl);
+
+ for (iX = (pData->iSourcer - pData->iSourcel); iX > 0; iX--)
+ {
+ *pWork = *pBkgd; /* ok; copy the pixel */
+ *(pWork+1) = *(pBkgd+1);
+ *(pWork+2) = *(pBkgd+2);
+ *(pWork+3) = 0x00; /* transparant for alpha-canvasses */
+
+ pWork += 4;
+ pBkgd += 3;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RESTORE_RGB8, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_SKIPCANVAS_RGB8 */
+
+/* ************************************************************************** */
+
+#ifndef MNG_SKIPCANVAS_BGR8
+mng_retcode mng_restore_bkgd_bgr8 (mng_datap pData)
+{
+ mng_int32 iX;
+ mng_uint8p pBkgd;
+ mng_uint8p pWork = pData->pRGBArow;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RESTORE_BGR8, MNG_LC_START);
+#endif
+
+ if (pData->fGetbkgdline) /* can we access the background ? */
+ { /* point to the right pixel then */
+ pBkgd = (mng_uint8p)pData->fGetbkgdline ((mng_handle)pData,
+ pData->iRow + pData->iDestt) +
+ (3 * pData->iDestl);
+
+ for (iX = (pData->iSourcer - pData->iSourcel); iX > 0; iX--)
+ {
+ *pWork = *(pBkgd+2); /* ok; copy the pixel */
+ *(pWork+1) = *(pBkgd+1);
+ *(pWork+2) = *pBkgd;
+ *(pWork+3) = 0x00; /* transparant for alpha-canvasses */
+
+ pWork += 4;
+ pBkgd += 3;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RESTORE_BGR8, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_SKIPCANVAS_BGR8 */
+
+/* ************************************************************************** */
+
+#ifndef MNG_SKIPCANVAS_BGRX8
+mng_retcode mng_restore_bkgd_bgrx8 (mng_datap pData)
+{
+ mng_int32 iX;
+ mng_uint8p pBkgd;
+ mng_uint8p pWork = pData->pRGBArow;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RESTORE_BGRX8, MNG_LC_START);
+#endif
+
+ if (pData->fGetbkgdline) /* can we access the background ? */
+ { /* point to the right pixel then */
+ pBkgd = (mng_uint8p)pData->fGetbkgdline ((mng_handle)pData,
+ pData->iRow + pData->iDestt) +
+ (3 * pData->iDestl);
+
+ for (iX = (pData->iSourcer - pData->iSourcel); iX > 0; iX--)
+ {
+ *pWork = *(pBkgd+2); /* ok; copy the pixel */
+ *(pWork+1) = *(pBkgd+1);
+ *(pWork+2) = *pBkgd;
+ *(pWork+3) = 0x00; /* transparant for alpha-canvasses */
+
+ pWork += 4;
+ pBkgd += 4;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RESTORE_BGRX8, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_SKIPCANVAS_BGRX8 */
+
+/* ************************************************************************** */
+
+#ifndef MNG_SKIPCANVAS_BGR565
+mng_retcode mng_restore_bkgd_bgr565 (mng_datap pData)
+{
+ mng_int32 iX;
+ mng_uint8p pBkgd;
+ mng_uint8p pWork = pData->pRGBArow;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RESTORE_BGR565, MNG_LC_START);
+#endif
+
+ if (pData->fGetbkgdline) /* can we access the background ? */
+ { /* point to the right pixel then */
+ pBkgd = (mng_uint8p)pData->fGetbkgdline ((mng_handle)pData,
+ pData->iRow + pData->iDestt) +
+ (3 * pData->iDestl);
+
+ for (iX = (pData->iSourcer - pData->iSourcel); iX > 0; iX--)
+ {
+ *pWork = (mng_uint8)( *(pBkgd+1) & 0xF8); /* ok; copy the pixel */
+ *(pWork+1) = (mng_uint8)( (*(pBkgd+1) << 5 ) | ( ((*pBkgd)&0xE0)>>3 ) );
+ *(pWork+2) = (mng_uint8)( *(pBkgd) << 3 );
+ *(pWork+3) = 0x00; /* transparant for alpha-canvasses */
+
+ pWork += 4;
+ pBkgd += 2;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RESTORE_BGR565, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_SKIPCANVAS_BGR565 */
+
+/* ************************************************************************** */
+
+#ifndef MNG_SKIPCANVAS_RGB565
+mng_retcode mng_restore_bkgd_rgb565 (mng_datap pData)
+{
+ mng_int32 iX;
+ mng_uint8p pBkgd;
+ mng_uint8p pWork = pData->pRGBArow;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RESTORE_RGB565, MNG_LC_START);
+#endif
+
+ if (pData->fGetbkgdline) /* can we access the background ? */
+ { /* point to the right pixel then */
+ pBkgd = (mng_uint8p)pData->fGetbkgdline ((mng_handle)pData,
+ pData->iRow + pData->iDestt) +
+ (3 * pData->iDestl);
+
+ for (iX = (pData->iSourcer - pData->iSourcel); iX > 0; iX--)
+ {
+ *pWork = (mng_uint8)( *(pBkgd)&0xF8); /* ok; copy the pixel */
+ *(pWork+1) = (mng_uint8)( (*(pBkgd+1) << 5) | ( ((*pBkgd)&0xE0)>>3 ) );
+ *(pWork+2) = (mng_uint8)( *(pBkgd+1) << 3);
+ *(pWork+3) = 0x00; /* transparant for alpha-canvasses */
+
+ pWork += 4;
+ pBkgd += 2;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RESTORE_RGB565, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_SKIPCANVAS_RBB565 */
+
+
+/* ************************************************************************** */
+/* * * */
+/* * Row retrieval routines - retrieve processed & uncompressed row-data * */
+/* * from the current "object" * */
+/* * * */
+/* ************************************************************************** */
+
+/* TODO: a serious optimization is to retrieve only those pixels that will
+ actually be displayed; this would require changes in
+ the "display_image" routine (in mng_display.c) &
+ all the "retrieve_xxx" routines below &
+ the "display_xxx" routines above !!!!!
+ NOTE that "correct_xxx" routines would not require modification */
+
+mng_retcode mng_retrieve_g8 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pRetrieveobj)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pRGBArow;
+ mng_int32 iX;
+ mng_uint8 iG;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RETRIEVE_G8, MNG_LC_START);
+#endif
+
+ pRGBArow = pData->pRGBArow; /* temporary work pointers */
+ pWorkrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize);
+
+ if (pBuf->bHasTRNS) /* tRNS in buffer ? */
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ iG = *pWorkrow; /* get the gray-value */
+ /* is it transparent ? */
+ if ((mng_uint16)iG == pBuf->iTRNSgray)
+ {
+ *pRGBArow = 0x00; /* nuttin to display */
+ *(pRGBArow+1) = 0x00;
+ *(pRGBArow+2) = 0x00;
+ *(pRGBArow+3) = 0x00;
+ }
+ else
+ {
+#ifndef MNG_NO_1_2_4BIT_SUPPORT
+ mng_uint8 multiplier[]={0,255,85,0,17,0,0,0,1};
+ iG = (mng_uint8)(iG * multiplier[pBuf->iBitdepth]);
+#endif
+
+ *pRGBArow = iG; /* put in intermediate row */
+ *(pRGBArow+1) = iG;
+ *(pRGBArow+2) = iG;
+ *(pRGBArow+3) = 0xFF;
+ }
+
+ pWorkrow++; /* next pixel */
+ pRGBArow += 4;
+ }
+ }
+ else
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+#ifndef MNG_NO_1_2_4BIT_SUPPORT
+ mng_uint8 multiplier[]={0,255,85,0,17,0,0,0,1}; /* LBR scaling */
+ iG = (mng_uint8)(multiplier[pBuf->iBitdepth] * *pWorkrow);
+#else
+ iG = *pWorkrow; /* get the gray-value */
+#endif
+
+ *pRGBArow = iG; /* put in intermediate row */
+ *(pRGBArow+1) = iG;
+ *(pRGBArow+2) = iG;
+ *(pRGBArow+3) = 0xFF;
+
+ pWorkrow++; /* next pixel */
+ pRGBArow += 4;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RETRIEVE_G8, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_16BIT_SUPPORT
+mng_retcode mng_retrieve_g16 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pRetrieveobj)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pRGBArow;
+ mng_int32 iX;
+ mng_uint16 iG;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RETRIEVE_G16, MNG_LC_START);
+#endif
+ /* temporary work pointers */
+ pRGBArow = pData->pRGBArow;
+ pWorkrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize);
+
+ if (pBuf->bHasTRNS) /* tRNS in buffer ? */
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ iG = mng_get_uint16 (pWorkrow); /* get the gray-value */
+ /* is it transparent ? */
+ if (iG == pBuf->iTRNSgray)
+ { /* nuttin to display */
+ mng_put_uint16 (pRGBArow, 0x0000);
+ mng_put_uint16 (pRGBArow+2, 0x0000);
+ mng_put_uint16 (pRGBArow+4, 0x0000);
+ mng_put_uint16 (pRGBArow+6, 0x0000);
+ }
+ else
+ { /* put in intermediate row */
+ mng_put_uint16 (pRGBArow, iG);
+ mng_put_uint16 (pRGBArow+2, iG);
+ mng_put_uint16 (pRGBArow+4, iG);
+ mng_put_uint16 (pRGBArow+6, 0xFFFF);
+ }
+
+ pWorkrow += 2; /* next pixel */
+ pRGBArow += 8;
+ }
+ }
+ else
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ iG = mng_get_uint16 (pWorkrow); /* get the gray-value */
+
+ mng_put_uint16 (pRGBArow, iG); /* and put in intermediate row */
+ mng_put_uint16 (pRGBArow+2, iG);
+ mng_put_uint16 (pRGBArow+4, iG);
+ mng_put_uint16 (pRGBArow+6, 0xFFFF);
+
+ pWorkrow += 2; /* next pixel */
+ pRGBArow += 8;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RETRIEVE_G16, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif
+
+/* ************************************************************************** */
+
+mng_retcode mng_retrieve_rgb8 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pRetrieveobj)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pRGBArow;
+ mng_int32 iX;
+ mng_uint8 iR, iG, iB;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RETRIEVE_RGB8, MNG_LC_START);
+#endif
+
+ pRGBArow = pData->pRGBArow; /* temporary work pointers */
+ pWorkrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize);
+
+ if (pBuf->bHasTRNS) /* tRNS in buffer ? */
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ iR = *pWorkrow; /* get the rgb-values */
+ iG = *(pWorkrow+1);
+ iB = *(pWorkrow+2);
+ /* is it transparent ? */
+ if (((mng_uint16)iR == pBuf->iTRNSred ) &&
+ ((mng_uint16)iG == pBuf->iTRNSgreen) &&
+ ((mng_uint16)iB == pBuf->iTRNSblue ) )
+ {
+ *pRGBArow = 0x00; /* nothing to display */
+ *(pRGBArow+1) = 0x00;
+ *(pRGBArow+2) = 0x00;
+ *(pRGBArow+3) = 0x00;
+ }
+ else
+ {
+ *pRGBArow = iR; /* put in intermediate row */
+ *(pRGBArow+1) = iG;
+ *(pRGBArow+2) = iB;
+ *(pRGBArow+3) = 0xFF;
+ }
+
+ pWorkrow += 3; /* next pixel */
+ pRGBArow += 4;
+ }
+ }
+ else
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ *pRGBArow = *pWorkrow; /* just copy the pixel */
+ *(pRGBArow+1) = *(pWorkrow+1);
+ *(pRGBArow+2) = *(pWorkrow+2);
+ *(pRGBArow+3) = 0xFF;
+
+ pWorkrow += 3; /* next pixel */
+ pRGBArow += 4;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RETRIEVE_RGB8, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_16BIT_SUPPORT
+mng_retcode mng_retrieve_rgb16 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pRetrieveobj)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pRGBArow;
+ mng_int32 iX;
+ mng_uint16 iR, iG, iB;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RETRIEVE_RGB16, MNG_LC_START);
+#endif
+ /* temporary work pointers */
+ pRGBArow = pData->pRGBArow;
+ pWorkrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize);
+
+ if (pBuf->bHasTRNS) /* tRNS in buffer ? */
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ iR = mng_get_uint16 (pWorkrow); /* get the rgb-values */
+ iG = mng_get_uint16 (pWorkrow+2);
+ iB = mng_get_uint16 (pWorkrow+4);
+ /* is it transparent ? */
+ if ((iR == pBuf->iTRNSred ) &&
+ (iG == pBuf->iTRNSgreen) &&
+ (iB == pBuf->iTRNSblue ) )
+ { /* nothing to display */
+ mng_put_uint16 (pRGBArow, 0x0000);
+ mng_put_uint16 (pRGBArow+2, 0x0000);
+ mng_put_uint16 (pRGBArow+4, 0x0000);
+ mng_put_uint16 (pRGBArow+6, 0x0000);
+ }
+ else
+ { /* put in intermediate row */
+ mng_put_uint16 (pRGBArow, iR);
+ mng_put_uint16 (pRGBArow+2, iG);
+ mng_put_uint16 (pRGBArow+4, iB);
+ mng_put_uint16 (pRGBArow+6, 0xFFFF);
+ }
+
+ pWorkrow += 6; /* next pixel */
+ pRGBArow += 8;
+ }
+ }
+ else
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ { /* just copy the pixel */
+ mng_put_uint16 (pRGBArow, mng_get_uint16 (pWorkrow ));
+ mng_put_uint16 (pRGBArow+2, mng_get_uint16 (pWorkrow+2));
+ mng_put_uint16 (pRGBArow+4, mng_get_uint16 (pWorkrow+4));
+ mng_put_uint16 (pRGBArow+6, 0xFFFF);
+
+ pWorkrow += 6; /* next pixel */
+ pRGBArow += 8;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RETRIEVE_RGB16, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif
+
+/* ************************************************************************** */
+
+mng_retcode mng_retrieve_idx8 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pRetrieveobj)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pRGBArow;
+ mng_int32 iX;
+ mng_uint8 iQ;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RETRIEVE_IDX8, MNG_LC_START);
+#endif
+
+ pRGBArow = pData->pRGBArow; /* temporary work pointers */
+ pWorkrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize);
+
+ if (pBuf->bHasTRNS) /* tRNS in buffer ? */
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ iQ = *pWorkrow; /* get the index */
+ /* is it valid ? */
+ if ((mng_uint32)iQ < pBuf->iPLTEcount)
+ { /* put in intermediate row */
+ *pRGBArow = pBuf->aPLTEentries [iQ].iRed;
+ *(pRGBArow+1) = pBuf->aPLTEentries [iQ].iGreen;
+ *(pRGBArow+2) = pBuf->aPLTEentries [iQ].iBlue;
+ /* transparency for this index ? */
+ if ((mng_uint32)iQ < pBuf->iTRNScount)
+ *(pRGBArow+3) = pBuf->aTRNSentries [iQ];
+ else
+ *(pRGBArow+3) = 0xFF;
+ }
+ else
+ MNG_ERROR (pData, MNG_PLTEINDEXERROR);
+
+ pWorkrow++; /* next pixel */
+ pRGBArow += 4;
+ }
+ }
+ else
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ iQ = *pWorkrow; /* get the index */
+ /* is it valid ? */
+ if ((mng_uint32)iQ < pBuf->iPLTEcount)
+ { /* put in intermediate row */
+ *pRGBArow = pBuf->aPLTEentries [iQ].iRed;
+ *(pRGBArow+1) = pBuf->aPLTEentries [iQ].iGreen;
+ *(pRGBArow+2) = pBuf->aPLTEentries [iQ].iBlue;
+ *(pRGBArow+3) = 0xFF;
+ }
+ else
+ MNG_ERROR (pData, MNG_PLTEINDEXERROR);
+
+ pWorkrow++; /* next pixel */
+ pRGBArow += 4;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RETRIEVE_IDX8, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode mng_retrieve_ga8 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pRetrieveobj)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pRGBArow;
+ mng_int32 iX;
+ mng_uint8 iG;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RETRIEVE_GA8, MNG_LC_START);
+#endif
+
+ pRGBArow = pData->pRGBArow; /* temporary work pointers */
+ pWorkrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize);
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ iG = *pWorkrow; /* get the gray-value */
+ *pRGBArow = iG; /* put in intermediate row */
+ *(pRGBArow+1) = iG;
+ *(pRGBArow+2) = iG;
+ *(pRGBArow+3) = *(pWorkrow+1);
+
+ pWorkrow += 2; /* next pixel */
+ pRGBArow += 4;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RETRIEVE_GA8, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_16BIT_SUPPORT
+mng_retcode mng_retrieve_ga16 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pRetrieveobj)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pRGBArow;
+ mng_int32 iX;
+ mng_uint16 iG;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RETRIEVE_GA16, MNG_LC_START);
+#endif
+ /* temporary work pointers */
+ pRGBArow = pData->pRGBArow;
+ pWorkrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize);
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ iG = mng_get_uint16 (pWorkrow); /* get the gray-value */
+
+ mng_put_uint16 (pRGBArow, iG); /* and put in intermediate row */
+ mng_put_uint16 (pRGBArow+2, iG);
+ mng_put_uint16 (pRGBArow+4, iG);
+ mng_put_uint16 (pRGBArow+6, mng_get_uint16 (pWorkrow+2));
+
+ pWorkrow += 4; /* next pixel */
+ pRGBArow += 8;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RETRIEVE_GA16, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif
+
+/* ************************************************************************** */
+
+mng_retcode mng_retrieve_rgba8 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pRetrieveobj)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pRGBArow;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RETRIEVE_RGBA8, MNG_LC_START);
+#endif
+
+ pRGBArow = pData->pRGBArow; /* temporary work pointers */
+ pWorkrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize);
+ /* can't be easier than this ! */
+ MNG_COPY (pRGBArow, pWorkrow, pBuf->iRowsize);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RETRIEVE_RGBA8, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_16BIT_SUPPORT
+mng_retcode mng_retrieve_rgba16 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pRetrieveobj)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pRGBArow;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RETRIEVE_RGBA16, MNG_LC_START);
+#endif
+ /* temporary work pointers */
+ pRGBArow = pData->pRGBArow;
+ pWorkrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize);
+ /* can't be easier than this ! */
+ MNG_COPY (pRGBArow, pWorkrow, pBuf->iRowsize);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RETRIEVE_RGBA16, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif
+
+/* ************************************************************************** */
+/* * * */
+/* * Row storage routines - store processed & uncompressed row-data * */
+/* * into the current "object" * */
+/* * * */
+/* ************************************************************************** */
+
+#ifndef MNG_NO_1_2_4BIT_SUPPORT
+mng_retcode mng_store_g1 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+ mng_uint8 iB;
+ mng_uint8 iM;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_G1, MNG_LC_START);
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize);
+ iM = 0; /* start at pixel 0 */
+ iB = 0;
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ if (!iM) /* mask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0x80;
+ }
+
+ if (iB & iM) /* is it white ? */
+ *pOutrow = 0x01; /* white */
+ else
+ *pOutrow = 0x00; /* black */
+
+ pOutrow += pData->iColinc; /* next pixel */
+ iM >>= 1;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_G1, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode mng_store_g2 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+ mng_uint8 iB;
+ mng_uint8 iM;
+ mng_uint32 iS;
+ mng_uint8 iQ;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_G2, MNG_LC_START);
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize);
+ iM = 0; /* start at pixel 0 */
+ iB = 0;
+ iS = 0;
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ if (!iM) /* mask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0xC0;
+ iS = 6;
+ }
+
+ iQ = (mng_uint8)((iB & iM) >> iS); /* get the gray level */
+ *pOutrow = iQ; /* put in object buffer */
+
+ pOutrow += pData->iColinc; /* next pixel */
+ iM >>= 2;
+ iS -= 2;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_G2, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode mng_store_g4 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+ mng_uint8 iB;
+ mng_uint8 iM;
+ mng_uint32 iS;
+ mng_uint8 iQ;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_G4, MNG_LC_START);
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize);
+ iM = 0; /* start at pixel 0 */
+ iB = 0;
+ iS = 0;
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ if (!iM) /* mask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0xF0;
+ iS = 4;
+ }
+
+ iQ = (mng_uint8)((iB & iM) >> iS); /* get the gray level */
+ *pOutrow = iQ; /* put in object buffer */
+
+ pOutrow += pData->iColinc; /* next pixel */
+ iM >>= 4;
+ iS -= 4;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_G4, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif
+
+/* ************************************************************************** */
+
+mng_retcode mng_store_g8 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_G8, MNG_LC_START);
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize);
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ *pOutrow = *pWorkrow; /* put in object buffer */
+
+ pOutrow += pData->iColinc; /* next pixel */
+ pWorkrow++;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_G8, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_16BIT_SUPPORT
+mng_retcode mng_store_g16 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_G16, MNG_LC_START);
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize);
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ { /* copy into object buffer */
+ mng_put_uint16 (pOutrow, mng_get_uint16 (pWorkrow));
+
+ pOutrow += (pData->iColinc << 1); /* next pixel */
+ pWorkrow += 2;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_G16, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif
+
+/* ************************************************************************** */
+
+mng_retcode mng_store_rgb8 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_RGB8, MNG_LC_START);
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize);
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ *pOutrow = *pWorkrow; /* copy the RGB bytes */
+ *(pOutrow+1) = *(pWorkrow+1);
+ *(pOutrow+2) = *(pWorkrow+2);
+
+ pWorkrow += 3; /* next pixel */
+ pOutrow += (pData->iColinc * 3);
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_RGB8, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_16BIT_SUPPORT
+mng_retcode mng_store_rgb16 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_RGB16, MNG_LC_START);
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize);
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ MNG_COPY (pOutrow, pWorkrow, 6); /* copy the RGB bytes */
+
+ pWorkrow += 6; /* next pixel */
+ pOutrow += (pData->iColinc * 6);
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_RGB16, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_1_2_4BIT_SUPPORT
+mng_retcode mng_store_idx1 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+ mng_uint8 iB;
+ mng_uint8 iM;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_IDX1, MNG_LC_START);
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize);
+ iM = 0; /* start at pixel 0 */
+ iB = 0;
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ if (!iM) /* mask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0x80;
+ }
+
+ if (iB & iM) /* store the index */
+ *pOutrow = 0x01;
+ else
+ *pOutrow = 0x00;
+
+ pOutrow += pData->iColinc; /* next pixel */
+ iM >>= 1;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_IDX1, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode mng_store_idx2 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+ mng_uint8 iB;
+ mng_uint8 iM;
+ mng_uint32 iS;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_IDX2, MNG_LC_START);
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize);
+ iM = 0; /* start at pixel 0 */
+ iB = 0;
+ iS = 0;
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ if (!iM) /* mask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0xC0;
+ iS = 6;
+ }
+ /* store the index */
+ *pOutrow = (mng_uint8)((iB & iM) >> iS);
+
+ pOutrow += pData->iColinc; /* next pixel */
+ iM >>= 2;
+ iS -= 2;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_IDX2, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode mng_store_idx4 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+ mng_uint8 iB;
+ mng_uint8 iM;
+ mng_uint32 iS;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_IDX4, MNG_LC_START);
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize);
+ iM = 0; /* start at pixel 0 */
+ iB = 0;
+ iS = 0;
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ if (!iM) /* mask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0xF0;
+ iS = 4;
+ }
+ /* store the index */
+ *pOutrow = (mng_uint8)((iB & iM) >> iS);
+
+ pOutrow += pData->iColinc; /* next pixel */
+ iM >>= 4;
+ iS -= 4;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_IDX4, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif
+
+/* ************************************************************************** */
+
+mng_retcode mng_store_idx8 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_IDX8, MNG_LC_START);
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize);
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ *pOutrow = *pWorkrow; /* put in object buffer */
+
+ pOutrow += pData->iColinc; /* next pixel */
+ pWorkrow++;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_IDX8, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode mng_store_ga8 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_GA8, MNG_LC_START);
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize);
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ *pOutrow = *pWorkrow; /* copy the GA bytes */
+ *(pOutrow+1) = *(pWorkrow+1);
+
+ pWorkrow += 2; /* next pixel */
+ pOutrow += (pData->iColinc << 1);
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_GA8, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_16BIT_SUPPORT
+mng_retcode mng_store_ga16 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_GA16, MNG_LC_START);
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize);
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ MNG_COPY (pOutrow, pWorkrow, 4); /* copy the GA bytes */
+
+ pWorkrow += 4; /* next pixel */
+ pOutrow += (pData->iColinc << 2);
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_GA16, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif
+
+/* ************************************************************************** */
+
+mng_retcode mng_store_rgba8 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_RGBA8, MNG_LC_START);
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize);
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ *pOutrow = *pWorkrow; /* copy the RGBA bytes */
+ *(pOutrow+1) = *(pWorkrow+1);
+ *(pOutrow+2) = *(pWorkrow+2);
+ *(pOutrow+3) = *(pWorkrow+3);
+
+ pWorkrow += 4; /* next pixel */
+ pOutrow += (pData->iColinc << 2);
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_RGBA8, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_16BIT_SUPPORT
+mng_retcode mng_store_rgba16 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_RGBA16, MNG_LC_START);
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize);
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ MNG_COPY (pOutrow, pWorkrow, 8); /* copy the RGBA bytes */
+
+ pWorkrow += 8; /* next pixel */
+ pOutrow += (pData->iColinc << 3);
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_RGBA16, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif
+
+/* ************************************************************************** */
+/* * * */
+/* * Row storage routines (JPEG) - store processed & uncompressed row-data * */
+/* * into the current "object" * */
+/* * * */
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_JNG
+
+/* ************************************************************************** */
+
+mng_retcode mng_store_jpeg_g8 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_G8, MNG_LC_START);
+#endif
+
+ pWorkrow = pData->pJPEGrow; /* temporary work pointers */
+ pOutrow = pBuf->pImgdata + (pData->iJPEGrow * pBuf->iRowsize);
+ /* easy as pie ... */
+ MNG_COPY (pOutrow, pWorkrow, pData->iRowsamples);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_G8, MNG_LC_END);
+#endif
+
+ return mng_next_jpeg_row (pData); /* we've got one more row of gray-samples */
+}
+
+/* ************************************************************************** */
+
+mng_retcode mng_store_jpeg_rgb8 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+#if RGB_PIXELSIZE != 3
+ mng_int32 iX;
+#endif
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_RGB8, MNG_LC_START);
+#endif
+
+ pWorkrow = pData->pJPEGrow; /* temporary work pointers */
+ pOutrow = pBuf->pImgdata + (pData->iJPEGrow * pBuf->iRowsize);
+
+#if RGB_PIXELSIZE == 3
+ /* easy as pie ... */
+ MNG_COPY (pOutrow, pWorkrow, pData->iRowsamples * 3);
+#else
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ *pOutrow = *pWorkrow; /* copy pixel into object buffer */
+ *(pOutrow+1) = *(pWorkrow+1);
+ *(pOutrow+2) = *(pWorkrow+2);
+
+ pOutrow += 3; /* next pixel */
+ pWorkrow += RGB_PIXELSIZE;
+ }
+#endif
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_RGB8, MNG_LC_END);
+#endif
+
+ return mng_next_jpeg_row (pData); /* we've got one more row of rgb-samples */
+}
+
+/* ************************************************************************** */
+
+mng_retcode mng_store_jpeg_ga8 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_GA8, MNG_LC_START);
+#endif
+
+ pWorkrow = pData->pJPEGrow; /* temporary work pointers */
+ pOutrow = pBuf->pImgdata + (pData->iJPEGrow * pBuf->iRowsize);
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ *pOutrow = *pWorkrow; /* copy into object buffer */
+
+ pOutrow += 2; /* next pixel */
+ pWorkrow++;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_GA8, MNG_LC_END);
+#endif
+
+ return mng_next_jpeg_row (pData); /* we've got one more row of gray-samples */
+}
+
+/* ************************************************************************** */
+
+mng_retcode mng_store_jpeg_rgba8 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_RGBA8, MNG_LC_START);
+#endif
+
+ pWorkrow = pData->pJPEGrow; /* temporary work pointers */
+ pOutrow = pBuf->pImgdata + (pData->iJPEGrow * pBuf->iRowsize);
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ *pOutrow = *pWorkrow; /* copy pixel into object buffer */
+ *(pOutrow+1) = *(pWorkrow+1);
+ *(pOutrow+2) = *(pWorkrow+2);
+
+ pOutrow += 4; /* next pixel */
+ pWorkrow += RGB_PIXELSIZE;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_RGBA8, MNG_LC_END);
+#endif
+
+ return mng_next_jpeg_row (pData); /* we've got one more row of rgb-samples */
+}
+
+/* ************************************************************************** */
+
+mng_retcode mng_store_jpeg_g8_alpha (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_G8_ALPHA, MNG_LC_START);
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pJPEGrow2;
+ pOutrow = pBuf->pImgdata + (pData->iJPEGalpharow * pBuf->iRowsize) + 1;
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ *pOutrow = *pWorkrow; /* put in object buffer */
+
+ pOutrow += 2; /* next pixel */
+ pWorkrow++;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_G8_ALPHA, MNG_LC_END);
+#endif
+ /* we've got one more row of alpha-samples */
+ return mng_next_jpeg_alpharow (pData);
+}
+
+/* ************************************************************************** */
+
+mng_retcode mng_store_jpeg_rgb8_alpha (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_RGB8_ALPHA, MNG_LC_START);
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pJPEGrow2;
+ pOutrow = pBuf->pImgdata + (pData->iJPEGalpharow * pBuf->iRowsize) + 3;
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ *pOutrow = *pWorkrow; /* put in object buffer */
+
+ pOutrow += 4; /* next pixel */
+ pWorkrow++;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_RGB8_ALPHA, MNG_LC_END);
+#endif
+ /* we've got one more row of alpha-samples */
+ return mng_next_jpeg_alpharow (pData);
+}
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_1_2_4BIT_SUPPORT
+mng_retcode mng_store_jpeg_g8_a1 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+ mng_uint8 iB;
+ mng_uint8 iM;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_G8_A1, MNG_LC_START);
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize) + 1;
+ iM = 0; /* start at pixel 0 */
+ iB = 0;
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ if (!iM) /* mask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0x80;
+ }
+
+ if (iB & iM) /* is it opaque ? */
+ *pOutrow = 0xFF; /* opaque */
+ else
+ *pOutrow = 0x00; /* transparent */
+
+ pOutrow += 2; /* next pixel */
+ iM >>= 1;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_G8_A1, MNG_LC_END);
+#endif
+ /* we've got one more row of alpha-samples */
+ return mng_next_jpeg_alpharow (pData);
+}
+
+/* ************************************************************************** */
+
+mng_retcode mng_store_jpeg_g8_a2 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+ mng_uint8 iB;
+ mng_uint8 iM;
+ mng_uint32 iS;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_G8_A2, MNG_LC_START);
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize) + 1;
+ iM = 0; /* start at pixel 0 */
+ iB = 0;
+ iS = 0;
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ if (!iM) /* mask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0xC0;
+ iS = 6;
+ }
+
+#ifdef MNG_OPTIMIZE_FOOTPRINT_SWITCH
+ {
+ const mng_uint8 alpha_level[4] = { 0x00, 0x55, 0xAA, 0xFF};
+ *pOutrow = alpha_level[((iB & iM) >> iS)] ;
+ }
+#else
+ switch ((iB & iM) >> iS) /* determine the alpha level */
+ {
+ case 0x03 : { *pOutrow = 0xFF; break; }
+ case 0x02 : { *pOutrow = 0xAA; break; }
+ case 0x01 : { *pOutrow = 0x55; break; }
+ default : { *pOutrow = 0x00; }
+ }
+#endif
+
+ pOutrow += 2; /* next pixel */
+ iM >>= 2;
+ iS -= 2;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_G8_A2, MNG_LC_END);
+#endif
+ /* we've got one more row of alpha-samples */
+ return mng_next_jpeg_alpharow (pData);
+}
+
+/* ************************************************************************** */
+
+mng_retcode mng_store_jpeg_g8_a4 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+ mng_uint8 iB;
+ mng_uint8 iM;
+ mng_uint32 iS;
+ mng_uint8 iQ;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_G8_A4, MNG_LC_START);
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize) + 1;
+ iM = 0; /* start at pixel 0 */
+ iB = 0;
+ iS = 0;
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ if (!iM) /* mask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0xF0;
+ iS = 4;
+ }
+ /* get the alpha level */
+ iQ = (mng_uint8)((iB & iM) >> iS);
+ iQ = (mng_uint8)(iQ + (iQ << 4)); /* expand to 8-bit by replication */
+
+ *pOutrow = iQ; /* put in object buffer */
+
+ pOutrow += 2; /* next pixel */
+ iM >>= 4;
+ iS -= 4;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_G8_A4, MNG_LC_END);
+#endif
+ /* we've got one more row of alpha-samples */
+ return mng_next_jpeg_alpharow (pData);
+}
+#endif
+
+/* ************************************************************************** */
+
+mng_retcode mng_store_jpeg_g8_a8 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_G8_A8, MNG_LC_START);
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize) + 1;
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ *pOutrow = *pWorkrow; /* put in object buffer */
+
+ pOutrow += 2; /* next pixel */
+ pWorkrow++;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_G8_A8, MNG_LC_END);
+#endif
+ /* we've got one more row of alpha-samples */
+ return mng_next_jpeg_alpharow (pData);
+}
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_16BIT_SUPPORT
+mng_retcode mng_store_jpeg_g8_a16 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_G8_A16, MNG_LC_START);
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize) + 1;
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ *pOutrow = *pWorkrow; /* only high-order byte! */
+
+ pOutrow += 2; /* next pixel */
+ pWorkrow += 2;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_G8_A16, MNG_LC_END);
+#endif
+ /* we've got one more row of alpha-samples */
+ return mng_next_jpeg_alpharow (pData);
+}
+#endif
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_1_2_4BIT_SUPPORT
+mng_retcode mng_store_jpeg_rgb8_a1 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+ mng_uint8 iB;
+ mng_uint8 iM;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_RGB8_A1, MNG_LC_START);
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize) + 3;
+ iM = 0; /* start at pixel 0 */
+ iB = 0;
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ if (!iM) /* mask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0x80;
+ }
+
+ if (iB & iM) /* is it opaque ? */
+ *pOutrow = 0xFF; /* opaque */
+ else
+ *pOutrow = 0x00; /* transparent */
+
+ pOutrow += 4; /* next pixel */
+ iM >>= 1;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_RGB8_A1, MNG_LC_END);
+#endif
+ /* we've got one more row of alpha-samples */
+ return mng_next_jpeg_alpharow (pData);
+}
+
+/* ************************************************************************** */
+
+mng_retcode mng_store_jpeg_rgb8_a2 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+ mng_uint8 iB;
+ mng_uint8 iM;
+ mng_uint32 iS;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_RGB8_A2, MNG_LC_START);
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize) + 3;
+ iM = 0; /* start at pixel 0 */
+ iB = 0;
+ iS = 0;
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ if (!iM) /* mask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0xC0;
+ iS = 6;
+ }
+
+#ifdef MNG_OPTIMIZE_FOOTPRINT_SWITCH
+ {
+ const mng_uint8 alpha_level[4] = { 0x00, 0x55, 0xAA, 0xFF};
+ *pOutrow = alpha_level[((iB & iM) >> iS)] ;
+ }
+#else
+ switch ((iB & iM) >> iS) /* determine the alpha level */
+ {
+ case 0x03 : { *pOutrow = 0xFF; break; }
+ case 0x02 : { *pOutrow = 0xAA; break; }
+ case 0x01 : { *pOutrow = 0x55; break; }
+ default : { *pOutrow = 0x00; }
+ }
+#endif
+
+ pOutrow += 4; /* next pixel */
+ iM >>= 2;
+ iS -= 2;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_RGB8_A2, MNG_LC_END);
+#endif
+ /* we've got one more row of alpha-samples */
+ return mng_next_jpeg_alpharow (pData);
+}
+
+/* ************************************************************************** */
+
+mng_retcode mng_store_jpeg_rgb8_a4 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+ mng_uint8 iB;
+ mng_uint8 iM;
+ mng_uint32 iS;
+ mng_uint8 iQ;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_RGB8_A4, MNG_LC_START);
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize) + 3;
+ iM = 0; /* start at pixel 0 */
+ iB = 0;
+ iS = 0;
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ if (!iM) /* mask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0xF0;
+ iS = 4;
+ }
+ /* get the alpha level */
+ iQ = (mng_uint8)((iB & iM) >> iS);
+ iQ = (mng_uint8)(iQ + (iQ << 4)); /* expand to 8-bit by replication */
+
+ *pOutrow = iQ; /* put in object buffer */
+
+ pOutrow += 4; /* next pixel */
+ iM >>= 4;
+ iS -= 4;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_RGB8_A4, MNG_LC_END);
+#endif
+ /* we've got one more row of alpha-samples */
+ return mng_next_jpeg_alpharow (pData);
+}
+#endif
+
+/* ************************************************************************** */
+
+mng_retcode mng_store_jpeg_rgb8_a8 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_RGB8_A8, MNG_LC_START);
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize) + 3;
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ *pOutrow = *pWorkrow; /* put in buffer */
+
+ pOutrow += 4; /* next pixel */
+ pWorkrow++;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_RGB8_A8, MNG_LC_END);
+#endif
+ /* we've got one more row of alpha-samples */
+ return mng_next_jpeg_alpharow (pData);
+}
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_16BIT_SUPPORT
+mng_retcode mng_store_jpeg_rgb8_a16 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_RGB8_A16, MNG_LC_START);
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize) + 3;
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ *pOutrow = *pWorkrow; /* only high-order byte */
+
+ pOutrow += 4; /* next pixel */
+ pWorkrow += 2;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_RGB8_A16, MNG_LC_END);
+#endif
+ /* we've got one more row of alpha-samples */
+ return mng_next_jpeg_alpharow (pData);
+}
+#endif
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_JPEG12
+mng_retcode mng_store_jpeg_g12_a1 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+ mng_uint8 iB;
+ mng_uint8 iM;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_G12_A1, MNG_LC_START);
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize) + 2;
+ iM = 0; /* start at pixel 0 */
+ iB = 0;
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ if (!iM) /* mask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0x80;
+ }
+
+ if (iB & iM) /* opaque ? */
+ mng_put_uint16 (pOutrow, 0xFFFF);/* opaque */
+ else
+ mng_put_uint16 (pOutrow, 0x0000);/* transparent */
+
+ pOutrow += 4; /* next pixel */
+ iM >>= 1;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_G12_A1, MNG_LC_END);
+#endif
+ /* we've got one more row of alpha-samples */
+ return mng_next_jpeg_alpharow (pData);
+}
+#endif /* MNG_SUPPORT_JPEG12 */
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_JPEG12
+mng_retcode mng_store_jpeg_g12_a2 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+ mng_uint8 iB;
+ mng_uint8 iM;
+ mng_uint32 iS;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_G12_A2, MNG_LC_START);
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize) + 2;
+ iM = 0; /* start at pixel 0 */
+ iB = 0;
+ iS = 0;
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ if (!iM) /* mask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0xC0;
+ iS = 6;
+ }
+
+#ifdef MNG_OPTIMIZE_FOOTPRINT_SWITCH
+ {
+ const mng_uint16 gray_level[4] = { 0x0000, 0x5555, 0xAAAA, 0xFFFF};
+ mng_put_uint16 (pOutrow, gray_level[((iB & iM) >> iS)]) ;
+ }
+#else
+ switch ((iB & iM) >> iS) /* determine the gray level */
+ {
+ case 0x03 : { mng_put_uint16 (pOutrow, 0xFFFF); break; }
+ case 0x02 : { mng_put_uint16 (pOutrow, 0xAAAA); break; }
+ case 0x01 : { mng_put_uint16 (pOutrow, 0x5555); break; }
+ default : { mng_put_uint16 (pOutrow, 0x0000); }
+ }
+#endif
+
+ pOutrow += 4; /* next pixel */
+ iM >>= 2;
+ iS -= 2;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_G12_A2, MNG_LC_END);
+#endif
+ /* we've got one more row of alpha-samples */
+ return mng_next_jpeg_alpharow (pData);
+}
+#endif /* MNG_SUPPORT_JPEG12 */
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_JPEG12
+mng_retcode mng_store_jpeg_g12_a4 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+ mng_uint8 iB;
+ mng_uint8 iM;
+ mng_uint32 iS;
+ mng_uint16 iQ;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_G12_A4, MNG_LC_START);
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize) + 2;
+ iM = 0; /* start at pixel 0 */
+ iB = 0;
+ iS = 0;
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ if (!iM) /* mask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0xF0;
+ iS = 4;
+ }
+ /* get the gray level */
+ iQ = (mng_uint16)((iB & iM) >> iS);
+ iQ = (mng_uint16)(iQ + (iQ << 4)); /* expand to 16-bit by replication */
+ iQ = (mng_uint16)(iQ + (iQ << 8));
+ /* put in object buffer */
+ mng_put_uint16 (pOutrow, iQ);
+
+ pOutrow += 4; /* next pixel */
+ iM >>= 4;
+ iS -= 4;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_G12_A4, MNG_LC_END);
+#endif
+ /* we've got one more row of alpha-samples */
+ return mng_next_jpeg_alpharow (pData);
+}
+#endif /* MNG_SUPPORT_JPEG12 */
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_JPEG12
+mng_retcode mng_store_jpeg_g12_a8 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+ mng_uint16 iW;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_G12_A8, MNG_LC_START);
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize) + 2;
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ iW = (mng_uint16)(*pWorkrow); /* get input byte */
+ iW = (mng_uint16)(iW + (iW << 8)); /* expand to 16-bit by replication */
+
+ mng_put_uint16 (pOutrow, iW); /* put in object buffer */
+
+ pOutrow += 4; /* next pixel */
+ pWorkrow++;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_G12_A8, MNG_LC_END);
+#endif
+ /* we've got one more row of alpha-samples */
+ return mng_next_jpeg_alpharow (pData);
+}
+#endif /* MNG_SUPPORT_JPEG12 */
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_JPEG12
+#ifndef MNG_NO_16BIT_SUPPORT
+mng_retcode mng_store_jpeg_g12_a16 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_G12_A16, MNG_LC_START);
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize) + 2;
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ { /* copy it */
+ mng_put_uint16 (pOutrow, mng_get_uint16 (pWorkrow));
+
+ pOutrow += 4; /* next pixel */
+ pWorkrow += 2;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_G12_A16, MNG_LC_END);
+#endif
+ /* we've got one more row of alpha-samples */
+ return mng_next_jpeg_alpharow (pData);
+}
+#endif
+#endif /* MNG_SUPPORT_JPEG12 */
+
+/* ************************************************************************** */
+
+#endif /* MNG_INCLUDE_JNG */
+
+#ifndef MNG_NO_DELTA_PNG
+/* ************************************************************************** */
+/* * * */
+/* * Delta-image row routines - apply the processed & uncompressed row-data * */
+/* * onto the target "object" * */
+/* * * */
+/* ************************************************************************** */
+
+#ifndef MNG_NO_1_2_4BIT_SUPPORT
+mng_retcode mng_delta_g1 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pDeltaImage)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+ mng_uint8 iB;
+ mng_uint8 iM;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_G1, MNG_LC_START);
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iDeltaBlocky * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize) +
+ (pData->iDeltaBlockx * pBuf->iSamplesize);
+ iM = 0; /* start at pixel 0 */
+ iB = 0;
+ /* pixel replace ? */
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ if (!iM) /* mask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0x80;
+ }
+
+ if (iB & iM) /* is it white ? */
+ *pOutrow = 0xFF; /* white */
+ else
+ *pOutrow = 0x00; /* black */
+
+ pOutrow += pData->iColinc; /* next pixel */
+ iM >>= 1;
+ }
+ }
+ else
+ { /* pixel add ! */
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ if (!iM) /* mask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0x80;
+ }
+
+ if (iB & iM) /* invert if it is white ? */
+ *pOutrow = (mng_uint8)(*pOutrow ^ 0xFF);
+
+ pOutrow += pData->iColinc; /* next pixel */
+ iM >>= 1;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_G1, MNG_LC_END);
+#endif
+
+ return mng_store_g1 (pData);
+}
+
+/* ************************************************************************** */
+
+mng_retcode mng_delta_g2 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pDeltaImage)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+ mng_uint8 iB;
+ mng_uint8 iM;
+ mng_uint32 iS;
+#ifdef MNG_OPTIMIZE_FOOTPRINT_SWITCH
+ const mng_uint8 level[4] = { 0x00, 0x55, 0xAA, 0xFF};
+#endif
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_G2, MNG_LC_START);
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iDeltaBlocky * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize) +
+ (pData->iDeltaBlockx * pBuf->iSamplesize);
+ iM = 0; /* start at pixel 0 */
+ iB = 0;
+ iS = 0;
+ /* pixel replace ? */
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ if (!iM) /* mask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0xC0;
+ iS = 6;
+ }
+
+#ifdef MNG_OPTIMIZE_FOOTPRINT_SWITCH
+ *pOutrow = level[((iB & iM) >> iS)] ;
+#else
+ switch ((iB & iM) >> iS) /* determine the alpha level */
+ {
+ case 0x03 : { *pOutrow = 0xFF; break; }
+ case 0x02 : { *pOutrow = 0xAA; break; }
+ case 0x01 : { *pOutrow = 0x55; break; }
+ default : { *pOutrow = 0x00; }
+ }
+#endif
+
+ pOutrow += pData->iColinc; /* next pixel */
+ iM >>= 2;
+ iS -= 2;
+ }
+ }
+ else
+ { /* pixel add ! */
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ if (!iM) /* mask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0xC0;
+ iS = 6;
+ }
+
+#ifdef MNG_OPTIMIZE_FOOTPRINT_SWITCH
+ *pOutrow = level[((*pOutrow >> 6) + ((iB & iM) >> iS)) & 0x03] ;
+#else
+ switch (((*pOutrow >> 6) + ((iB & iM) >> iS)) & 0x03)
+ {
+ case 0x03 : { *pOutrow = 0xFF; break; }
+ case 0x02 : { *pOutrow = 0xAA; break; }
+ case 0x01 : { *pOutrow = 0x55; break; }
+ default : { *pOutrow = 0x00; }
+ }
+#endif
+
+ pOutrow += pData->iColinc; /* next pixel */
+ iM >>= 2;
+ iS -= 2;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_G2, MNG_LC_END);
+#endif
+
+ return mng_store_g2 (pData);
+}
+
+/* ************************************************************************** */
+
+mng_retcode mng_delta_g4 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pDeltaImage)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+ mng_uint8 iB;
+ mng_uint8 iM;
+ mng_uint32 iS;
+ mng_uint8 iQ;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_G4, MNG_LC_START);
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iDeltaBlocky * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize) +
+ (pData->iDeltaBlockx * pBuf->iSamplesize);
+ iM = 0; /* start at pixel 0 */
+ iB = 0;
+ iS = 0;
+ /* pixel replace ? */
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ if (!iM) /* mask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0xF0;
+ iS = 4;
+ }
+ /* get the gray level */
+ iQ = (mng_uint8)((iB & iM) >> iS);
+ /* expand to 8-bit by replication */
+ iQ = (mng_uint8)(iQ + (iQ << 4));
+
+ *pOutrow = iQ; /* put in object buffer */
+
+ pOutrow += pData->iColinc; /* next pixel */
+ iM >>= 4;
+ iS -= 4;
+ }
+ }
+ else
+ { /* pixel add ! */
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ if (!iM) /* mask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0xF0;
+ iS = 4;
+ }
+ /* get the gray level */
+ iQ = (mng_uint8)(((*pOutrow >> 4) + ((iB & iM) >> iS)) & 0x0F);
+ /* expand to 8-bit by replication */
+ iQ = (mng_uint8)(iQ + (iQ << 4));
+
+ *pOutrow = iQ; /* put in object buffer */
+
+ pOutrow += pData->iColinc; /* next pixel */
+ iM >>= 4;
+ iS -= 4;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_G4, MNG_LC_END);
+#endif
+
+ return mng_store_g4 (pData);
+}
+#endif /* MNG_NO_1_2_4BIT_SUPPORT */
+
+/* ************************************************************************** */
+
+mng_retcode mng_delta_g8 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pDeltaImage)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_G8, MNG_LC_START);
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iDeltaBlocky * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize) +
+ (pData->iDeltaBlockx * pBuf->iSamplesize);
+ /* pixel replace ? */
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ *pOutrow = *pWorkrow; /* put in object buffer */
+
+ pOutrow += pData->iColinc; /* next pixel */
+ pWorkrow++;
+ }
+ }
+ else
+ { /* pixel add ! */
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ { /* add to object buffer */
+ *pOutrow = (mng_uint8)(*pOutrow + *pWorkrow);
+
+ pOutrow += pData->iColinc; /* next pixel */
+ pWorkrow++;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_G8, MNG_LC_END);
+#endif
+
+ return mng_store_g8 (pData);
+}
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_16BIT_SUPPORT
+mng_retcode mng_delta_g16 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pDeltaImage)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_G16, MNG_LC_START);
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iDeltaBlocky * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize) +
+ (pData->iDeltaBlockx * pBuf->iSamplesize);
+ /* pixel replace ? */
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ *pOutrow = *pWorkrow; /* put in object buffer */
+ *(pOutrow+1) = *(pWorkrow+1);
+ /* next pixel */
+ pOutrow += (pData->iColinc << 1);
+ pWorkrow += 2;
+ }
+ }
+ else
+ { /* pixel add ! */
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ { /* add to object buffer */
+ mng_put_uint16 (pOutrow, (mng_uint16)(mng_get_uint16 (pOutrow ) +
+ mng_get_uint16 (pWorkrow) ));
+ /* next pixel */
+ pOutrow += (pData->iColinc << 1);
+ pWorkrow += 2;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_G16, MNG_LC_END);
+#endif
+
+ return mng_store_g16 (pData);
+}
+#endif
+
+/* ************************************************************************** */
+
+mng_retcode mng_delta_rgb8 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pDeltaImage)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_RGB8, MNG_LC_START);
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iDeltaBlocky * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize) +
+ (pData->iDeltaBlockx * pBuf->iSamplesize);
+ /* pixel replace ? */
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ *pOutrow = *pWorkrow; /* put in object buffer */
+ *(pOutrow+1) = *(pWorkrow+1);
+ *(pOutrow+2) = *(pWorkrow+2);
+ /* next pixel */
+ pOutrow += (pData->iColinc * 3);
+ pWorkrow += 3;
+ }
+ }
+ else
+ { /* pixel add ! */
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ { /* add to object buffer */
+ *pOutrow = (mng_uint8)(*pOutrow + *pWorkrow );
+ *(pOutrow+1) = (mng_uint8)(*(pOutrow+1) + *(pWorkrow+1));
+ *(pOutrow+2) = (mng_uint8)(*(pOutrow+2) + *(pWorkrow+2));
+ /* next pixel */
+ pOutrow += (pData->iColinc * 3);
+ pWorkrow += 3;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_RGB8, MNG_LC_END);
+#endif
+
+ return mng_store_rgb8 (pData);
+}
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_16BIT_SUPPORT
+mng_retcode mng_delta_rgb16 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pDeltaImage)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_RGB16, MNG_LC_START);
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iDeltaBlocky * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize) +
+ (pData->iDeltaBlockx * pBuf->iSamplesize);
+ /* pixel replace ? */
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ *pOutrow = *pWorkrow; /* put in object buffer */
+ *(pOutrow+1) = *(pWorkrow+1);
+ *(pOutrow+2) = *(pWorkrow+2);
+ *(pOutrow+3) = *(pWorkrow+3);
+ *(pOutrow+4) = *(pWorkrow+4);
+ *(pOutrow+5) = *(pWorkrow+5);
+ /* next pixel */
+ pOutrow += (pData->iColinc * 6);
+ pWorkrow += 6;
+ }
+ }
+ else
+ { /* pixel add ! */
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ { /* add to object buffer */
+ mng_put_uint16 (pOutrow, (mng_uint16)(mng_get_uint16 (pOutrow ) +
+ mng_get_uint16 (pWorkrow ) ));
+ mng_put_uint16 (pOutrow+2, (mng_uint16)(mng_get_uint16 (pOutrow+2 ) +
+ mng_get_uint16 (pWorkrow+2) ));
+ mng_put_uint16 (pOutrow+4, (mng_uint16)(mng_get_uint16 (pOutrow+4 ) +
+ mng_get_uint16 (pWorkrow+4) ));
+ /* next pixel */
+ pOutrow += (pData->iColinc * 6);
+ pWorkrow += 6;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_RGB16, MNG_LC_END);
+#endif
+
+ return mng_store_rgb16 (pData);
+}
+#endif
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_1_2_4BIT_SUPPORT
+mng_retcode mng_delta_idx1 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pDeltaImage)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+ mng_uint8 iB;
+ mng_uint8 iM;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_IDX1, MNG_LC_START);
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iDeltaBlocky * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize) +
+ (pData->iDeltaBlockx * pBuf->iSamplesize);
+ iM = 0; /* start at pixel 0 */
+ iB = 0;
+ /* pixel replace ? */
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ if (!iM) /* mask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0x80;
+ }
+
+ if (iB & iM) /* put the right index value */
+ *pOutrow = 1;
+ else
+ *pOutrow = 0;
+
+ pOutrow += pData->iColinc; /* next pixel */
+ iM >>= 1;
+ }
+ }
+ else
+ { /* pixel add ! */
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ if (!iM) /* mask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0x80;
+ }
+
+ if (iB & iM) /* invert if it is non-zero index */
+ *pOutrow = (mng_uint8)(*pOutrow ^ 0x01);
+
+ pOutrow += pData->iColinc; /* next pixel */
+ iM >>= 1;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_IDX1, MNG_LC_END);
+#endif
+
+ return mng_store_idx1 (pData);
+}
+
+/* ************************************************************************** */
+
+mng_retcode mng_delta_idx2 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pDeltaImage)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+ mng_uint8 iB;
+ mng_uint8 iM;
+ mng_uint32 iS;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_IDX2, MNG_LC_START);
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iDeltaBlocky * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize) +
+ (pData->iDeltaBlockx * pBuf->iSamplesize);
+ iM = 0; /* start at pixel 0 */
+ iB = 0;
+ iS = 0;
+ /* pixel replace ? */
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ if (!iM) /* mask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0xC0;
+ iS = 6;
+ }
+ /* put the index */
+ *pOutrow = (mng_uint8)((iB & iM) >> iS);
+
+ pOutrow += pData->iColinc; /* next pixel */
+ iM >>= 2;
+ iS -= 2;
+ }
+ }
+ else
+ { /* pixel add ! */
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ if (!iM) /* mask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0xC0;
+ iS = 6;
+ }
+ /* calculate the index */
+ *pOutrow = (mng_uint8)((*pOutrow + ((iB & iM) >> iS)) & 0x03);
+
+ pOutrow += pData->iColinc; /* next pixel */
+ iM >>= 2;
+ iS -= 2;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_IDX2, MNG_LC_END);
+#endif
+
+ return mng_store_idx2 (pData);
+}
+
+/* ************************************************************************** */
+
+mng_retcode mng_delta_idx4 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pDeltaImage)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+ mng_uint8 iB;
+ mng_uint8 iM;
+ mng_uint32 iS;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_IDX4, MNG_LC_START);
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iDeltaBlocky * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize) +
+ (pData->iDeltaBlockx * pBuf->iSamplesize);
+ iM = 0; /* start at pixel 0 */
+ iB = 0;
+ iS = 0;
+ /* pixel replace ? */
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ if (!iM) /* mask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0xF0;
+ iS = 4;
+ }
+ /* put the index */
+ *pOutrow = (mng_uint8)((iB & iM) >> iS);
+
+ pOutrow += pData->iColinc; /* next pixel */
+ iM >>= 4;
+ iS -= 4;
+ }
+ }
+ else
+ { /* pixel add ! */
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ if (!iM) /* mask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0xF0;
+ iS = 4;
+ }
+ /* calculate the index */
+ *pOutrow = (mng_uint8)((*pOutrow + ((iB & iM) >> iS)) & 0x0F);
+
+ pOutrow += pData->iColinc; /* next pixel */
+ iM >>= 4;
+ iS -= 4;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_IDX4, MNG_LC_END);
+#endif
+
+ return mng_store_idx4 (pData);
+}
+#endif
+
+/* ************************************************************************** */
+
+mng_retcode mng_delta_idx8 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pDeltaImage)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_IDX8, MNG_LC_START);
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iDeltaBlocky * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize) +
+ (pData->iDeltaBlockx * pBuf->iSamplesize);
+ /* pixel replace ? */
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ *pOutrow = *pWorkrow; /* put in object buffer */
+
+ pOutrow += pData->iColinc; /* next pixel */
+ pWorkrow++;
+ }
+ }
+ else
+ { /* pixel add ! */
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ { /* add to object buffer */
+ *pOutrow = (mng_uint8)(*pOutrow + *pWorkrow);
+
+ pOutrow += pData->iColinc; /* next pixel */
+ pWorkrow++;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_IDX8, MNG_LC_END);
+#endif
+
+ return mng_store_idx8 (pData);
+}
+
+/* ************************************************************************** */
+
+mng_retcode mng_delta_ga8 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pDeltaImage)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_GA8, MNG_LC_START);
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iDeltaBlocky * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize) +
+ (pData->iDeltaBlockx * pBuf->iSamplesize);
+ /* pixel replace ? */
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ *pOutrow = *pWorkrow; /* put in object buffer */
+ *(pOutrow+1) = *(pWorkrow+1);
+ /* next pixel */
+ pOutrow += (pData->iColinc << 1);
+ pWorkrow += 2;
+ }
+ }
+ else
+ { /* pixel add ! */
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ { /* add to object buffer */
+ *pOutrow = (mng_uint8)(*pOutrow + *pWorkrow );
+ *(pOutrow+1) = (mng_uint8)(*(pOutrow+1) + *(pWorkrow+1));
+ /* next pixel */
+ pOutrow += (pData->iColinc << 1);
+ pWorkrow += 2;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_GA8, MNG_LC_END);
+#endif
+
+ return mng_store_ga8 (pData);
+}
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_16BIT_SUPPORT
+mng_retcode mng_delta_ga16 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pDeltaImage)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_GA16, MNG_LC_START);
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iDeltaBlocky * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize) +
+ (pData->iDeltaBlockx * pBuf->iSamplesize);
+ /* pixel replace ? */
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ *pOutrow = *pWorkrow; /* put in object buffer */
+ *(pOutrow+1) = *(pWorkrow+1);
+ *(pOutrow+2) = *(pWorkrow+2);
+ *(pOutrow+3) = *(pWorkrow+3);
+ /* next pixel */
+ pOutrow += (pData->iColinc << 2);
+ pWorkrow += 4;
+ }
+ }
+ else
+ { /* pixel add ! */
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ { /* add to object buffer */
+ mng_put_uint16 (pOutrow, (mng_uint16)(mng_get_uint16 (pOutrow ) +
+ mng_get_uint16 (pWorkrow ) ));
+ mng_put_uint16 (pOutrow+2, (mng_uint16)(mng_get_uint16 (pOutrow+2 ) +
+ mng_get_uint16 (pWorkrow+2) ));
+ /* next pixel */
+ pOutrow += (pData->iColinc << 2);
+ pWorkrow += 4;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_GA16, MNG_LC_END);
+#endif
+
+ return mng_store_ga16 (pData);
+}
+#endif
+
+/* ************************************************************************** */
+
+mng_retcode mng_delta_rgba8 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pDeltaImage)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_RGBA8, MNG_LC_START);
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iDeltaBlocky * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize) +
+ (pData->iDeltaBlockx * pBuf->iSamplesize);
+ /* pixel replace ? */
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ *pOutrow = *pWorkrow; /* put in object buffer */
+ *(pOutrow+1) = *(pWorkrow+1);
+ *(pOutrow+2) = *(pWorkrow+2);
+ *(pOutrow+3) = *(pWorkrow+3);
+ /* next pixel */
+ pOutrow += (pData->iColinc << 2);
+ pWorkrow += 4;
+ }
+ }
+ else
+ { /* pixel add ! */
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ { /* add to object buffer */
+ *pOutrow = (mng_uint8)(*pOutrow + *pWorkrow );
+ *(pOutrow+1) = (mng_uint8)(*(pOutrow+1) + *(pWorkrow+1));
+ *(pOutrow+2) = (mng_uint8)(*(pOutrow+2) + *(pWorkrow+2));
+ *(pOutrow+3) = (mng_uint8)(*(pOutrow+3) + *(pWorkrow+3));
+ /* next pixel */
+ pOutrow += (pData->iColinc << 2);
+ pWorkrow += 4;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_RGBA8, MNG_LC_END);
+#endif
+
+ return mng_store_rgba8 (pData);
+}
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_16BIT_SUPPORT
+mng_retcode mng_delta_rgba16 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pDeltaImage)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_RGBA16, MNG_LC_START);
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iDeltaBlocky * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize) +
+ (pData->iDeltaBlockx * pBuf->iSamplesize);
+ /* pixel replace ? */
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ MNG_COPY (pOutrow, pWorkrow, 8); /* put in object buffer */
+ /* next pixel */
+ pOutrow += (pData->iColinc << 3);
+ pWorkrow += 8;
+ }
+ }
+ else
+ { /* pixel add ! */
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ { /* add to object buffer */
+ mng_put_uint16 (pOutrow, (mng_uint16)(mng_get_uint16 (pOutrow ) +
+ mng_get_uint16 (pWorkrow ) ));
+ mng_put_uint16 (pOutrow+2, (mng_uint16)(mng_get_uint16 (pOutrow+2 ) +
+ mng_get_uint16 (pWorkrow+2) ));
+ mng_put_uint16 (pOutrow+4, (mng_uint16)(mng_get_uint16 (pOutrow+4 ) +
+ mng_get_uint16 (pWorkrow+4) ));
+ mng_put_uint16 (pOutrow+6, (mng_uint16)(mng_get_uint16 (pOutrow+6 ) +
+ mng_get_uint16 (pWorkrow+6) ));
+ /* next pixel */
+ pOutrow += (pData->iColinc << 3);
+ pWorkrow += 8;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_RGBA16, MNG_LC_END);
+#endif
+
+ return mng_store_rgba16 (pData);
+}
+#endif
+
+/* ************************************************************************** */
+/* * * */
+/* * Delta-image row routines - apply the source row onto the target * */
+/* * * */
+/* ************************************************************************** */
+
+#ifndef MNG_NO_1_2_4BIT_SUPPORT
+mng_retcode mng_delta_g1_g1 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_G1_G1, MNG_LC_START);
+#endif
+
+ pWorkrow = pData->pRGBArow;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize);
+
+ if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE ) ||
+ (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE) )
+ {
+ MNG_COPY (pOutrow, pWorkrow, pData->iRowsamples);
+ }
+ else
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD)
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ *pOutrow = (mng_uint8)(((mng_uint16)*pOutrow +
+ (mng_uint16)*pWorkrow) & 0x01);
+
+ pOutrow++;
+ pWorkrow++;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_G1_G1, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode mng_delta_g2_g2 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_G2_G2, MNG_LC_START);
+#endif
+
+ pWorkrow = pData->pRGBArow;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize);
+
+ if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE ) ||
+ (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE) )
+ {
+ MNG_COPY (pOutrow, pWorkrow, pData->iRowsamples);
+ }
+ else
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD)
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ *pOutrow = (mng_uint8)(((mng_uint16)*pOutrow +
+ (mng_uint16)*pWorkrow) & 0x03);
+
+ pOutrow++;
+ pWorkrow++;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_G2_G2, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode mng_delta_g4_g4 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_G4_G4, MNG_LC_START);
+#endif
+
+ pWorkrow = pData->pRGBArow;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize);
+
+ if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE ) ||
+ (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE) )
+ {
+ MNG_COPY (pOutrow, pWorkrow, pData->iRowsamples);
+ }
+ else
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD)
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ *pOutrow = (mng_uint8)(((mng_uint16)*pOutrow +
+ (mng_uint16)*pWorkrow) & 0x0F);
+
+ pOutrow++;
+ pWorkrow++;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_G4_G4, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif
+
+/* ************************************************************************** */
+
+mng_retcode mng_delta_g8_g8 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_G8_G8, MNG_LC_START);
+#endif
+
+ pWorkrow = pData->pRGBArow;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize);
+
+ if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE ) ||
+ (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE) )
+ {
+ MNG_COPY (pOutrow, pWorkrow, pData->iRowsamples);
+ }
+ else
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD)
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ *pOutrow = (mng_uint8)(((mng_uint16)*pOutrow +
+ (mng_uint16)*pWorkrow) & 0xFF);
+
+ pOutrow++;
+ pWorkrow++;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_G8_G8, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_16BIT_SUPPORT
+mng_retcode mng_delta_g16_g16 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_G16_G16, MNG_LC_START);
+#endif
+
+ pWorkrow = pData->pRGBArow;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize);
+
+ if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE ) ||
+ (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE) )
+ {
+ MNG_COPY (pOutrow, pWorkrow, (pData->iRowsamples << 1));
+ }
+ else
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD)
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ mng_put_uint16 (pOutrow, (mng_uint16)((mng_get_uint16 (pOutrow) +
+ mng_get_uint16 (pWorkrow)) & 0xFFFF));
+
+ pOutrow += 2;
+ pWorkrow += 2;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_G16_G16, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif
+#endif /* MNG_NO_DELTA_PNG */
+
+/* ************************************************************************** */
+
+mng_retcode mng_delta_rgb8_rgb8 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_RGB8_RGB8, MNG_LC_START);
+#endif
+
+ pWorkrow = pData->pRGBArow;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize);
+
+ if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE ) ||
+ (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE) )
+ {
+ MNG_COPY (pOutrow, pWorkrow, pData->iRowsamples * 3);
+ }
+ else
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD)
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples*3; iX > 0; iX--)
+#else
+ for (iX = 0; iX < (pData->iRowsamples * 3); iX++)
+#endif
+ {
+ *pOutrow = (mng_uint8)(((mng_uint16)*pOutrow +
+ (mng_uint16)*pWorkrow) & 0xFF);
+
+ pOutrow++;
+ pWorkrow++;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_RGB8_RGB8, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_16BIT_SUPPORT
+mng_retcode mng_delta_rgb16_rgb16 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_RGB16_RGB16, MNG_LC_START);
+#endif
+
+ pWorkrow = pData->pRGBArow;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize);
+
+ if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE ) ||
+ (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE) )
+ {
+ MNG_COPY (pOutrow, pWorkrow, (pData->iRowsamples * 6));
+ }
+ else
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD)
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ mng_put_uint16 (pOutrow, (mng_uint16)((mng_get_uint16 (pOutrow ) +
+ mng_get_uint16 (pWorkrow )) & 0xFFFF));
+ mng_put_uint16 (pOutrow+2, (mng_uint16)((mng_get_uint16 (pOutrow+2) +
+ mng_get_uint16 (pWorkrow+2)) & 0xFFFF));
+ mng_put_uint16 (pOutrow+4, (mng_uint16)((mng_get_uint16 (pOutrow+4) +
+ mng_get_uint16 (pWorkrow+4)) & 0xFFFF));
+
+ pOutrow += 6;
+ pWorkrow += 6;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_RGB16_RGB16, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_DELTA_PNG
+mng_retcode mng_delta_ga8_ga8 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_GA8_GA8, MNG_LC_START);
+#endif
+
+ pWorkrow = pData->pRGBArow;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize);
+
+ if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE ) ||
+ (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE) )
+ {
+ MNG_COPY (pOutrow, pWorkrow, pData->iRowsamples << 1);
+ }
+ else
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD)
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = (pData->iRowsamples<<1); iX > 0; iX--)
+#else
+ for (iX = 0; iX < (pData->iRowsamples << 1); iX++)
+#endif
+ {
+ *pOutrow = (mng_uint8)(((mng_uint16)*pOutrow +
+ (mng_uint16)*pWorkrow) & 0xFF);
+
+ pOutrow++;
+ pWorkrow++;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_GA8_GA8, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode mng_delta_ga8_g8 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_GA8_G8, MNG_LC_START);
+#endif
+
+ pWorkrow = pData->pRGBArow;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize);
+
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORREPLACE)
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ *pOutrow = *pWorkrow;
+
+ pOutrow += 2;
+ pWorkrow++;
+ }
+ }
+ else
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORADD)
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ *pOutrow = (mng_uint8)(((mng_uint16)*pOutrow +
+ (mng_uint16)*pWorkrow) & 0xFF);
+
+ pOutrow += 2;
+ pWorkrow++;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_GA8_G8, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode mng_delta_ga8_a8 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_GA8_A8, MNG_LC_START);
+#endif
+
+ pWorkrow = pData->pRGBArow;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize) + 1;
+
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAREPLACE)
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ *pOutrow = *pWorkrow;
+
+ pOutrow += 2;
+ pWorkrow++;
+ }
+ }
+ else
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAADD)
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ *pOutrow = (mng_uint8)(((mng_uint16)*pOutrow +
+ (mng_uint16)*pWorkrow) & 0xFF);
+
+ pOutrow += 2;
+ pWorkrow++;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_GA8_A8, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_16BIT_SUPPORT
+mng_retcode mng_delta_ga16_ga16 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_GA16_GA16, MNG_LC_START);
+#endif
+
+ pWorkrow = pData->pRGBArow;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize);
+
+ if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE ) ||
+ (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE) )
+ {
+ MNG_COPY (pOutrow, pWorkrow, (pData->iRowsamples << 2));
+ }
+ else
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD)
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ mng_put_uint16 (pOutrow, (mng_uint16)((mng_get_uint16 (pOutrow ) +
+ mng_get_uint16 (pWorkrow )) & 0xFFFF));
+ mng_put_uint16 (pOutrow+2, (mng_uint16)((mng_get_uint16 (pOutrow+2) +
+ mng_get_uint16 (pWorkrow+2)) & 0xFFFF));
+
+ pOutrow += 4;
+ pWorkrow += 4;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_GA16_GA16, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_16BIT_SUPPORT
+mng_retcode mng_delta_ga16_g16 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_GA16_G16, MNG_LC_START);
+#endif
+
+ pWorkrow = pData->pRGBArow;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize);
+
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORREPLACE)
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ mng_put_uint16 (pOutrow, mng_get_uint16 (pWorkrow));
+
+ pOutrow += 4;
+ pWorkrow += 2;
+ }
+ }
+ else
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORADD)
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ mng_put_uint16 (pOutrow, (mng_uint16)((mng_get_uint16 (pOutrow) +
+ mng_get_uint16 (pWorkrow)) & 0xFFFF));
+
+ pOutrow += 4;
+ pWorkrow += 2;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_GA16_G16, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_16BIT_SUPPORT
+mng_retcode mng_delta_ga16_a16 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_GA16_A16, MNG_LC_START);
+#endif
+
+ pWorkrow = pData->pRGBArow;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize);
+
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAREPLACE)
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ mng_put_uint16 (pOutrow+2, mng_get_uint16 (pWorkrow));
+
+ pOutrow += 4;
+ pWorkrow += 2;
+ }
+ }
+ else
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAADD)
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ mng_put_uint16 (pOutrow+2, (mng_uint16)((mng_get_uint16 (pOutrow+2) +
+ mng_get_uint16 (pWorkrow)) & 0xFFFF));
+
+ pOutrow += 4;
+ pWorkrow += 2;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_GA16_A16, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif
+#endif /* MNG_NO_DELTA_PNG */
+
+/* ************************************************************************** */
+
+mng_retcode mng_delta_rgba8_rgba8 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_RGBA8_RGBA8, MNG_LC_START);
+#endif
+
+ pWorkrow = pData->pRGBArow;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize);
+
+ if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE ) ||
+ (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE) )
+ {
+ MNG_COPY (pOutrow, pWorkrow, pData->iRowsamples << 2);
+ }
+ else
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD)
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = (pData->iRowsamples << 2); iX > 0; iX--)
+#else
+ for (iX = 0; iX < (pData->iRowsamples << 2); iX++)
+#endif
+ {
+ *pOutrow = (mng_uint8)(((mng_uint16)*pOutrow +
+ (mng_uint16)*pWorkrow) & 0xFF);
+
+ pOutrow++;
+ pWorkrow++;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_RGBA8_RGBA8, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_DELTA_PNG
+mng_retcode mng_delta_rgba8_rgb8 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_RGBA8_RGB8, MNG_LC_START);
+#endif
+
+ pWorkrow = pData->pRGBArow;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize);
+
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORREPLACE)
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ *pOutrow = *pWorkrow;
+ *(pOutrow+1) = *(pWorkrow+1);
+ *(pOutrow+2) = *(pWorkrow+2);
+
+ pOutrow += 4;
+ pWorkrow += 3;
+ }
+ }
+ else
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORADD)
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ *pOutrow = (mng_uint8)(((mng_uint16)*pOutrow +
+ (mng_uint16)*pWorkrow ) & 0xFF);
+ *(pOutrow+1) = (mng_uint8)(((mng_uint16)*(pOutrow+1) +
+ (mng_uint16)*(pWorkrow+1)) & 0xFF);
+ *(pOutrow+2) = (mng_uint8)(((mng_uint16)*(pOutrow+2) +
+ (mng_uint16)*(pWorkrow+2)) & 0xFF);
+
+ pOutrow += 4;
+ pWorkrow += 3;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_RGBA8_RGB8, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode mng_delta_rgba8_a8 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_RGBA8_A8, MNG_LC_START);
+#endif
+
+ pWorkrow = pData->pRGBArow;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize) + 3;
+
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAREPLACE)
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ *pOutrow = *pWorkrow;
+
+ pOutrow += 4;
+ pWorkrow++;
+ }
+ }
+ else
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAADD)
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ *pOutrow = (mng_uint8)(((mng_uint16)*pOutrow +
+ (mng_uint16)*pWorkrow) & 0xFF);
+
+ pOutrow += 4;
+ pWorkrow++;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_RGBA8_A8, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_NO_DELTA_PNG */
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_16BIT_SUPPORT
+mng_retcode mng_delta_rgba16_rgba16 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_RGBA16_RGBA16, MNG_LC_START);
+#endif
+
+ pWorkrow = pData->pRGBArow;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize);
+
+ if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE ) ||
+ (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE) )
+ {
+ MNG_COPY (pOutrow, pWorkrow, (pData->iRowsamples << 3));
+ }
+ else
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD)
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ mng_put_uint16 (pOutrow, (mng_uint16)((mng_get_uint16 (pOutrow ) +
+ mng_get_uint16 (pWorkrow )) & 0xFFFF));
+ mng_put_uint16 (pOutrow+2, (mng_uint16)((mng_get_uint16 (pOutrow+2) +
+ mng_get_uint16 (pWorkrow+2)) & 0xFFFF));
+ mng_put_uint16 (pOutrow+4, (mng_uint16)((mng_get_uint16 (pOutrow+4) +
+ mng_get_uint16 (pWorkrow+4)) & 0xFFFF));
+ mng_put_uint16 (pOutrow+6, (mng_uint16)((mng_get_uint16 (pOutrow+6) +
+ mng_get_uint16 (pWorkrow+6)) & 0xFFFF));
+
+ pOutrow += 8;
+ pWorkrow += 8;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_RGBA16_RGBA16, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_DELTA_PNG
+#ifndef MNG_NO_16BIT_SUPPORT
+mng_retcode mng_delta_rgba16_rgb16 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_RGBA16_RGB16, MNG_LC_START);
+#endif
+
+ pWorkrow = pData->pRGBArow;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize);
+
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORREPLACE)
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ mng_put_uint16 (pOutrow, mng_get_uint16 (pWorkrow ));
+ mng_put_uint16 (pOutrow+2, mng_get_uint16 (pWorkrow+2));
+ mng_put_uint16 (pOutrow+4, mng_get_uint16 (pWorkrow+4));
+
+ pOutrow += 8;
+ pWorkrow += 6;
+ }
+ }
+ else
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORADD)
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ mng_put_uint16 (pOutrow, (mng_uint16)((mng_get_uint16 (pOutrow ) +
+ mng_get_uint16 (pWorkrow )) & 0xFFFF));
+ mng_put_uint16 (pOutrow+2, (mng_uint16)((mng_get_uint16 (pOutrow+2) +
+ mng_get_uint16 (pWorkrow+2)) & 0xFFFF));
+ mng_put_uint16 (pOutrow+4, (mng_uint16)((mng_get_uint16 (pOutrow+4) +
+ mng_get_uint16 (pWorkrow+4)) & 0xFFFF));
+
+ pOutrow += 8;
+ pWorkrow += 6;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_RGBA16_RGB16, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_16BIT_SUPPORT
+mng_retcode mng_delta_rgba16_a16 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_RGBA16_A16, MNG_LC_START);
+#endif
+
+ pWorkrow = pData->pRGBArow;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize);
+
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAREPLACE)
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ mng_put_uint16 (pOutrow+6, mng_get_uint16 (pWorkrow));
+
+ pOutrow += 8;
+ pWorkrow += 2;
+ }
+ }
+ else
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAADD)
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ mng_put_uint16 (pOutrow+6, (mng_uint16)((mng_get_uint16 (pOutrow+6) +
+ mng_get_uint16 (pWorkrow)) & 0xFFFF));
+
+ pOutrow += 8;
+ pWorkrow += 2;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_RGBA16_A16, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif
+#endif /* MNG_NO_DELTA_PNG */
+
+/* ************************************************************************** */
+/* * * */
+/* * Delta-image row routines - scale the delta to bitdepth of target * */
+/* * * */
+/* ************************************************************************** */
+
+#ifndef MNG_NO_DELTA_PNG
+#ifndef MNG_NO_1_2_4BIT_SUPPORT
+mng_retcode mng_scale_g1_g2 (mng_datap pData)
+{
+ mng_uint8p pWorkrow = pData->pRGBArow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_SCALE_G1_G2, MNG_LC_START);
+#endif
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ *pWorkrow = (mng_uint8)(*pWorkrow << 1);
+ pWorkrow++;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_SCALE_G1_G2, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode mng_scale_g1_g4 (mng_datap pData)
+{
+ mng_uint8p pWorkrow = pData->pRGBArow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_SCALE_G1_G4, MNG_LC_START);
+#endif
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ *pWorkrow = (mng_uint8)(*pWorkrow << 3);
+ pWorkrow++;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_SCALE_G1_G4, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode mng_scale_g1_g8 (mng_datap pData)
+{
+ mng_uint8p pWorkrow = pData->pRGBArow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_SCALE_G1_G8, MNG_LC_START);
+#endif
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ *pWorkrow = (mng_uint8)(*pWorkrow << 7);
+ pWorkrow++;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_SCALE_G1_G8, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_16BIT_SUPPORT
+mng_retcode mng_scale_g1_g16 (mng_datap pData)
+{
+ mng_uint8p pWorkrow = pData->pRGBArow;
+ mng_uint8p pOutrow = pData->pRGBArow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_SCALE_G1_G16, MNG_LC_START);
+#endif
+
+ pWorkrow = pWorkrow + (pData->iRowsamples - 1);
+ pOutrow = pOutrow + ((pData->iRowsamples - 1) << 1);
+/* pWorkrow = (mng_uint8p)((mng_uint32)pWorkrow + pData->iRowsamples - 1); */
+/* pOutrow = (mng_uint8p)((mng_uint32)pOutrow + ((pData->iRowsamples - 1) << 1)); */
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ *(pOutrow+1) = 0;
+ *pOutrow = (mng_uint8)(*pWorkrow << 7);
+
+ pWorkrow--;
+ pOutrow -= 2;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_SCALE_G1_G16, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif
+
+/* ************************************************************************** */
+
+mng_retcode mng_scale_g2_g4 (mng_datap pData)
+{
+ mng_uint8p pWorkrow = pData->pRGBArow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_SCALE_G2_G4, MNG_LC_START);
+#endif
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ *pWorkrow = (mng_uint8)(*pWorkrow << 2);
+ pWorkrow++;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_SCALE_G2_G4, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode mng_scale_g2_g8 (mng_datap pData)
+{
+ mng_uint8p pWorkrow = pData->pRGBArow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_SCALE_G2_G8, MNG_LC_START);
+#endif
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ *pWorkrow = (mng_uint8)(*pWorkrow << 6);
+ pWorkrow++;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_SCALE_G2_G8, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_16BIT_SUPPORT
+mng_retcode mng_scale_g2_g16 (mng_datap pData)
+{
+ mng_uint8p pWorkrow = pData->pRGBArow;
+ mng_uint8p pOutrow = pData->pRGBArow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_SCALE_G2_G16, MNG_LC_START);
+#endif
+
+ pWorkrow = pWorkrow + (pData->iRowsamples - 1);
+ pOutrow = pOutrow + ((pData->iRowsamples - 1) << 1);
+/* pWorkrow = (mng_uint8p)((mng_uint32)pWorkrow + pData->iRowsamples - 1); */
+/* pOutrow = (mng_uint8p)((mng_uint32)pOutrow + ((pData->iRowsamples - 1) << 1)); */
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ *(pOutrow+1) = 0;
+ *pOutrow = (mng_uint8)(*pWorkrow << 6);
+
+ pWorkrow--;
+ pOutrow -= 2;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_SCALE_G2_G16, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif
+
+/* ************************************************************************** */
+
+mng_retcode mng_scale_g4_g8 (mng_datap pData)
+{
+ mng_uint8p pWorkrow = pData->pRGBArow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_SCALE_G4_G8, MNG_LC_START);
+#endif
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ *pWorkrow = (mng_uint8)(*pWorkrow << 4);
+ pWorkrow++;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_SCALE_G4_G8, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_16BIT_SUPPORT
+mng_retcode mng_scale_g4_g16 (mng_datap pData)
+{
+ mng_uint8p pWorkrow = pData->pRGBArow;
+ mng_uint8p pOutrow = pData->pRGBArow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_SCALE_G4_G16, MNG_LC_START);
+#endif
+
+ pWorkrow = pWorkrow + (pData->iRowsamples - 1);
+ pOutrow = pOutrow + ((pData->iRowsamples - 1) << 1);
+/* pWorkrow = (mng_uint8p)((mng_uint32)pWorkrow + pData->iRowsamples - 1); */
+/* pOutrow = (mng_uint8p)((mng_uint32)pOutrow + ((pData->iRowsamples - 1) << 1)); */
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ *(pOutrow+1) = 0;
+ *pOutrow = (mng_uint8)(*pWorkrow << 4);
+
+ pWorkrow--;
+ pOutrow -= 2;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_SCALE_G4_G16, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif
+#endif /* MNG_NO_1_2_4BIT_SUPPORT */
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_16BIT_SUPPORT
+mng_retcode mng_scale_g8_g16 (mng_datap pData)
+{
+ mng_uint8p pWorkrow = pData->pRGBArow;
+ mng_uint8p pOutrow = pData->pRGBArow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_SCALE_G8_G16, MNG_LC_START);
+#endif
+
+ pWorkrow = pWorkrow + (pData->iRowsamples - 1);
+ pOutrow = pOutrow + ((pData->iRowsamples - 1) << 1);
+/* pWorkrow = (mng_uint8p)((mng_uint32)pWorkrow + pData->iRowsamples - 1); */
+/* pOutrow = (mng_uint8p)((mng_uint32)pOutrow + ((pData->iRowsamples - 1) << 1)); */
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ *(pOutrow+1) = 0;
+ *pOutrow = *pWorkrow;
+
+ pWorkrow--;
+ pOutrow -= 2;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_SCALE_G8_G16, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_16BIT_SUPPORT
+mng_retcode mng_scale_ga8_ga16 (mng_datap pData)
+{
+ mng_uint8p pWorkrow = pData->pRGBArow;
+ mng_uint8p pOutrow = pData->pRGBArow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_SCALE_GA8_GA16, MNG_LC_START);
+#endif
+
+ pWorkrow = pWorkrow + ((pData->iRowsamples - 1) << 1);
+ pOutrow = pOutrow + ((pData->iRowsamples - 1) << 2);
+/* pWorkrow = (mng_uint8p)((mng_uint32)pWorkrow + ((pData->iRowsamples - 1) << 1)); */
+/* pOutrow = (mng_uint8p)((mng_uint32)pOutrow + ((pData->iRowsamples - 1) << 2)); */
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ *(pOutrow+3) = 0;
+ *(pOutrow+2) = *(pWorkrow+1);
+ *(pOutrow+1) = 0;
+ *pOutrow = *pWorkrow;
+
+ pWorkrow -= 2;
+ pOutrow -= 4;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_SCALE_GA8_GA16, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_16BIT_SUPPORT
+mng_retcode mng_scale_rgb8_rgb16 (mng_datap pData)
+{
+ mng_uint8p pWorkrow = pData->pRGBArow;
+ mng_uint8p pOutrow = pData->pRGBArow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_SCALE_RGB8_RGB16, MNG_LC_START);
+#endif
+
+ pWorkrow = pWorkrow + (3 * (pData->iRowsamples - 1));
+ pOutrow = pOutrow + (6 * (pData->iRowsamples - 1));
+/* pWorkrow = (mng_uint8p)((mng_uint32)pWorkrow + 3 * (pData->iRowsamples - 1)); */
+/* pOutrow = (mng_uint8p)((mng_uint32)pOutrow + 6 * (pData->iRowsamples - 1)); */
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ *(pOutrow+5) = 0;
+ *(pOutrow+4) = *(pWorkrow+2);
+ *(pOutrow+3) = 0;
+ *(pOutrow+2) = *(pWorkrow+1);
+ *(pOutrow+1) = 0;
+ *pOutrow = *pWorkrow;
+
+ pWorkrow -= 3;
+ pOutrow -= 6;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_SCALE_RGB8_RGB16, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_16BIT_SUPPORT
+mng_retcode mng_scale_rgba8_rgba16 (mng_datap pData)
+{
+ mng_uint8p pWorkrow = pData->pRGBArow;
+ mng_uint8p pOutrow = pData->pRGBArow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_SCALE_RGBA8_RGBA16, MNG_LC_START);
+#endif
+
+ pWorkrow = pWorkrow + ((pData->iRowsamples - 1) << 2);
+ pOutrow = pOutrow + ((pData->iRowsamples - 1) << 3);
+/* pWorkrow = (mng_uint8p)((mng_uint32)pWorkrow + ((pData->iRowsamples - 1) << 2)); */
+/* pOutrow = (mng_uint8p)((mng_uint32)pOutrow + ((pData->iRowsamples - 1) << 3)); */
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ *(pOutrow+7) = 0;
+ *(pOutrow+6) = *(pWorkrow+3);
+ *(pOutrow+5) = 0;
+ *(pOutrow+4) = *(pWorkrow+2);
+ *(pOutrow+3) = 0;
+ *(pOutrow+2) = *(pWorkrow+1);
+ *(pOutrow+1) = 0;
+ *pOutrow = *pWorkrow;
+
+ pWorkrow -= 4;
+ pOutrow -= 8;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_SCALE_RGBA8_RGBA16, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_1_2_4BIT_SUPPORT
+mng_retcode mng_scale_g2_g1 (mng_datap pData)
+{
+ mng_uint8p pWorkrow = pData->pRGBArow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_SCALE_G2_G1, MNG_LC_START);
+#endif
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ *pWorkrow = (mng_uint8)(*pWorkrow >> 1);
+ pWorkrow++;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_SCALE_G2_G1, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode mng_scale_g4_g1 (mng_datap pData)
+{
+ mng_uint8p pWorkrow = pData->pRGBArow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_SCALE_G4_G1, MNG_LC_START);
+#endif
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ *pWorkrow = (mng_uint8)(*pWorkrow >> 3);
+ pWorkrow++;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_SCALE_G4_G1, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode mng_scale_g8_g1 (mng_datap pData)
+{
+ mng_uint8p pWorkrow = pData->pRGBArow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_SCALE_G8_G1, MNG_LC_START);
+#endif
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ *pWorkrow = (mng_uint8)(*pWorkrow >> 7);
+ pWorkrow++;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_SCALE_G8_G1, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_16BIT_SUPPORT
+mng_retcode mng_scale_g16_g1 (mng_datap pData)
+{
+ mng_uint8p pWorkrow = pData->pRGBArow;
+ mng_uint8p pOutrow = pData->pRGBArow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_SCALE_G16_G1, MNG_LC_START);
+#endif
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ *pOutrow = (mng_uint8)(mng_get_uint16 (pWorkrow) >> 15);
+ pOutrow++;
+ pWorkrow += 2;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_SCALE_G16_G1, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif
+
+/* ************************************************************************** */
+
+mng_retcode mng_scale_g4_g2 (mng_datap pData)
+{
+ mng_uint8p pWorkrow = pData->pRGBArow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_SCALE_G4_G2, MNG_LC_START);
+#endif
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ *pWorkrow = (mng_uint8)(*pWorkrow >> 2);
+ pWorkrow++;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_SCALE_G4_G2, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode mng_scale_g8_g2 (mng_datap pData)
+{
+ mng_uint8p pWorkrow = pData->pRGBArow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_SCALE_G8_G2, MNG_LC_START);
+#endif
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ *pWorkrow = (mng_uint8)(*pWorkrow >> 6);
+ pWorkrow++;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_SCALE_G8_G2, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_16BIT_SUPPORT
+mng_retcode mng_scale_g16_g2 (mng_datap pData)
+{
+ mng_uint8p pWorkrow = pData->pRGBArow;
+ mng_uint8p pOutrow = pData->pRGBArow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_SCALE_G16_G2, MNG_LC_START);
+#endif
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ *pOutrow = (mng_uint8)(mng_get_uint16 (pWorkrow) >> 14);
+ pOutrow++;
+ pWorkrow += 2;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_SCALE_G16_G2, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif
+
+/* ************************************************************************** */
+
+mng_retcode mng_scale_g8_g4 (mng_datap pData)
+{
+ mng_uint8p pWorkrow = pData->pRGBArow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_SCALE_G8_G4, MNG_LC_START);
+#endif
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ *pWorkrow = (mng_uint8)(*pWorkrow >> 4);
+ pWorkrow++;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_SCALE_G8_G4, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_16BIT_SUPPORT
+mng_retcode mng_scale_g16_g4 (mng_datap pData)
+{
+ mng_uint8p pWorkrow = pData->pRGBArow;
+ mng_uint8p pOutrow = pData->pRGBArow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_SCALE_G16_G4, MNG_LC_START);
+#endif
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ *pOutrow = (mng_uint8)(mng_get_uint16 (pWorkrow) >> 12);
+ pOutrow++;
+ pWorkrow += 2;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_SCALE_G16_G4, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif
+#endif /* NO_1_2_4BIT_SUPPORT */
+
+/* ************************************************************************** */
+
+mng_retcode mng_scale_g16_g8 (mng_datap pData)
+{
+ mng_uint8p pWorkrow = pData->pRGBArow;
+ mng_uint8p pOutrow = pData->pRGBArow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_SCALE_G16_G8, MNG_LC_START);
+#endif
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ *pOutrow = (mng_uint8)(mng_get_uint16 (pWorkrow) >> 8);
+ pOutrow++;
+ pWorkrow += 2;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_SCALE_G16_G8, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode mng_scale_ga16_ga8 (mng_datap pData)
+{
+ mng_uint8p pWorkrow = pData->pRGBArow;
+ mng_uint8p pOutrow = pData->pRGBArow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_SCALE_GA16_GA8, MNG_LC_START);
+#endif
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ *pOutrow = (mng_uint8)(mng_get_uint16 (pWorkrow) >> 8);
+ pOutrow++;
+ pWorkrow += 2;
+ *pOutrow = (mng_uint8)(mng_get_uint16 (pWorkrow) >> 8);
+ pOutrow++;
+ pWorkrow += 2;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_SCALE_GA16_GA8, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode mng_scale_rgb16_rgb8 (mng_datap pData)
+{
+ mng_uint8p pWorkrow = pData->pRGBArow;
+ mng_uint8p pOutrow = pData->pRGBArow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_SCALE_RGB16_RGB8, MNG_LC_START);
+#endif
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ *pOutrow = (mng_uint8)(mng_get_uint16 (pWorkrow) >> 8);
+ pOutrow++;
+ pWorkrow += 2;
+ *pOutrow = (mng_uint8)(mng_get_uint16 (pWorkrow) >> 8);
+ pOutrow++;
+ pWorkrow += 2;
+ *pOutrow = (mng_uint8)(mng_get_uint16 (pWorkrow) >> 8);
+ pOutrow++;
+ pWorkrow += 2;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_SCALE_RGB16_RGB8, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode mng_scale_rgba16_rgba8 (mng_datap pData)
+{
+ mng_uint8p pWorkrow = pData->pRGBArow;
+ mng_uint8p pOutrow = pData->pRGBArow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_SCALE_RGBA16_RGBA8, MNG_LC_START);
+#endif
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ *pOutrow = (mng_uint8)(mng_get_uint16 (pWorkrow) >> 8);
+ pOutrow++;
+ pWorkrow += 2;
+ *pOutrow = (mng_uint8)(mng_get_uint16 (pWorkrow) >> 8);
+ pOutrow++;
+ pWorkrow += 2;
+ *pOutrow = (mng_uint8)(mng_get_uint16 (pWorkrow) >> 8);
+ pOutrow++;
+ pWorkrow += 2;
+ *pOutrow = (mng_uint8)(mng_get_uint16 (pWorkrow) >> 8);
+ pOutrow++;
+ pWorkrow += 2;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_SCALE_RGBA16_RGBA8, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif
+
+/* ************************************************************************** */
+/* * * */
+/* * Delta-image bit routines - promote bit_depth * */
+/* * * */
+/* ************************************************************************** */
+
+#ifndef MNG_NO_1_2_4BIT_SUPPORT
+mng_uint8 mng_promote_replicate_1_2 (mng_uint8 iB)
+{
+ return (mng_uint8)((iB << 1) | iB);
+}
+
+/* ************************************************************************** */
+
+mng_uint8 mng_promote_replicate_1_4 (mng_uint8 iB)
+{
+ iB = (mng_uint8)((iB << 1) + iB);
+ return (mng_uint8)((iB << 2) + iB);
+}
+
+/* ************************************************************************** */
+
+mng_uint8 mng_promote_replicate_1_8 (mng_uint8 iB)
+{
+ iB = (mng_uint8)((iB << 1) + iB);
+ iB = (mng_uint8)((iB << 2) + iB);
+ return (mng_uint8)((iB << 4) + iB);
+}
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_16BIT_SUPPORT
+mng_uint16 mng_promote_replicate_1_16 (mng_uint8 iB)
+{
+ iB = (mng_uint8)((iB << 1) + iB);
+ iB = (mng_uint8)((iB << 2) + iB);
+ iB = (mng_uint8)((iB << 4) + iB);
+ return (mng_uint16)(((mng_uint16)iB << 8) + (mng_uint16)iB);
+}
+#endif
+
+/* ************************************************************************** */
+
+mng_uint8 mng_promote_replicate_2_4 (mng_uint8 iB)
+{
+ return (mng_uint8)((iB << 2) + iB);
+}
+
+/* ************************************************************************** */
+
+mng_uint8 mng_promote_replicate_2_8 (mng_uint8 iB)
+{
+ iB = (mng_uint8)((iB << 2) + iB);
+ return (mng_uint8)((iB << 4) + iB);
+}
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_16BIT_SUPPORT
+mng_uint16 mng_promote_replicate_2_16 (mng_uint8 iB)
+{
+ iB = (mng_uint8)((iB << 2) + iB);
+ iB = (mng_uint8)((iB << 4) + iB);
+ return (mng_uint16)(((mng_uint16)iB << 8) + (mng_uint16)iB);
+}
+#endif
+
+/* ************************************************************************** */
+
+mng_uint8 mng_promote_replicate_4_8 (mng_uint8 iB)
+{
+ return (mng_uint8)((iB << 4) + iB);
+}
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_16BIT_SUPPORT
+mng_uint16 mng_promote_replicate_4_16 (mng_uint8 iB)
+{
+ iB = (mng_uint8)((iB << 4) + iB);
+ return (mng_uint16)(((mng_uint16)iB << 8) + (mng_uint16)iB);
+}
+#endif
+#endif /* NO_1_2_4BIT_SUPPORT */
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_16BIT_SUPPORT
+mng_uint16 mng_promote_replicate_8_16 (mng_uint8 iB)
+{
+ return (mng_uint16)(((mng_uint16)iB << 8) + (mng_uint16)iB);
+}
+#endif
+
+/* ************************************************************************** */
+
+#if !defined(MNG_NO_DELTA_PNG)
+#ifndef MNG_NO_1_2_4BIT_SUPPORT
+mng_uint8 mng_promote_zerofill_1_2 (mng_uint8 iB)
+{
+ return (mng_uint8)(iB << 1);
+}
+
+/* ************************************************************************** */
+
+mng_uint8 mng_promote_zerofill_1_4 (mng_uint8 iB)
+{
+ return (mng_uint8)(iB << 3);
+}
+
+/* ************************************************************************** */
+
+mng_uint8 mng_promote_zerofill_1_8 (mng_uint8 iB)
+{
+ return (mng_uint8)(iB << 7);
+}
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_16BIT_SUPPORT
+mng_uint16 mng_promote_zerofill_1_16 (mng_uint8 iB)
+{
+ return (mng_uint16)((mng_uint16)iB << 15);
+}
+#endif
+
+/* ************************************************************************** */
+
+mng_uint8 mng_promote_zerofill_2_4 (mng_uint8 iB)
+{
+ return (mng_uint8)(iB << 2);
+}
+
+/* ************************************************************************** */
+
+mng_uint8 mng_promote_zerofill_2_8 (mng_uint8 iB)
+{
+ return (mng_uint8)(iB << 6);
+}
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_16BIT_SUPPORT
+mng_uint16 mng_promote_zerofill_2_16 (mng_uint8 iB)
+{
+ return (mng_uint16)((mng_uint16)iB << 14);
+}
+#endif
+
+/* ************************************************************************** */
+
+mng_uint8 mng_promote_zerofill_4_8 (mng_uint8 iB)
+{
+ return (mng_uint8)(iB << 4);
+}
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_16BIT_SUPPORT
+mng_uint16 mng_promote_zerofill_4_16 (mng_uint8 iB)
+{
+ return (mng_uint16)((mng_uint16)iB << 12);
+}
+#endif
+#endif /* MNG_NO_1_2_4BIT_SUPPORT */
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_16BIT_SUPPORT
+mng_uint16 mng_promote_zerofill_8_16 (mng_uint8 iB)
+{
+ return (mng_uint16)((mng_uint16)iB << 8);
+}
+#endif
+#endif /* MNG_NO_DELTA_PNG */
+
+/* ************************************************************************** */
+/* * * */
+/* * Delta-image row routines - promote color_type * */
+/* * * */
+/* ************************************************************************** */
+
+#if !defined(MNG_NO_DELTA_PNG) || !defined(MNG_SKIPCHUNK_PAST) || !defined(MNG_SKIPCHUNK_MAGN)
+mng_retcode mng_promote_g8_g8 (mng_datap pData)
+{
+ mng_uint8p pSrcline = (mng_uint8p)pData->pPromSrc;
+ mng_uint8p pDstline = (mng_uint8p)pData->pPromDst;
+ mng_uint32 iX;
+ mng_uint8 iB;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROMOTE_G8_G8, MNG_LC_START);
+#endif
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iPromWidth; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iPromWidth; iX++)
+#endif
+ {
+ iB = *pSrcline;
+ if (pData->fPromBitdepth) /* bitdepth promoted ? */
+ iB = ((mng_bitdepth_8)pData->fPromBitdepth) (iB);
+ *pDstline = iB;
+
+ pSrcline++;
+ pDstline++;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROMOTE_G8_G8, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_16BIT_SUPPORT
+mng_retcode mng_promote_g8_g16 (mng_datap pData)
+{
+ mng_uint8p pSrcline = (mng_uint8p)pData->pPromSrc;
+ mng_uint8p pDstline = (mng_uint8p)pData->pPromDst;
+ mng_uint32 iX;
+ mng_uint16 iW;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROMOTE_G8_G16, MNG_LC_START);
+#endif
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iPromWidth; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iPromWidth; iX++)
+#endif
+ {
+ iW = ((mng_bitdepth_16)pData->fPromBitdepth) (*pSrcline);
+
+ *pDstline = (mng_uint8)(iW >> 8);
+ *(pDstline+1) = (mng_uint8)(iW && 0xFF);
+
+ pSrcline++;
+ pDstline += 2;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROMOTE_G8_G16, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode mng_promote_g16_g16 (mng_datap pData)
+{
+ mng_uint16p pSrcline = (mng_uint16p)pData->pPromSrc;
+ mng_uint16p pDstline = (mng_uint16p)pData->pPromDst;
+ mng_uint32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROMOTE_G16_G16, MNG_LC_START);
+#endif
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iPromWidth; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iPromWidth; iX++)
+#endif
+ {
+ *pDstline = *pSrcline;
+ pSrcline++;
+ pDstline++;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROMOTE_G16_G16, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif
+
+/* ************************************************************************** */
+
+mng_retcode mng_promote_g8_ga8 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pPromBuf;
+ mng_uint8p pSrcline = (mng_uint8p)pData->pPromSrc;
+ mng_uint8p pDstline = (mng_uint8p)pData->pPromDst;
+ mng_uint32 iX;
+ mng_uint8 iB;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROMOTE_G8_GA8, MNG_LC_START);
+#endif
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iPromWidth; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iPromWidth; iX++)
+#endif
+ {
+ iB = *pSrcline;
+ /* no cheap transparency ? */
+ if ((!pBuf->bHasTRNS) || ((mng_uint16)iB != pBuf->iTRNSgray))
+ *(pDstline+1) = 0xFF;
+
+ if (pData->fPromBitdepth) /* bitdepth promoted ? */
+ iB = ((mng_bitdepth_8)pData->fPromBitdepth) (iB);
+
+ *pDstline = iB;
+
+ pSrcline++;
+ pDstline += 2;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROMOTE_G8_GA8, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_16BIT_SUPPORT
+mng_retcode mng_promote_g8_ga16 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pPromBuf;
+ mng_uint8p pSrcline = (mng_uint8p)pData->pPromSrc;
+ mng_uint8p pDstline = (mng_uint8p)pData->pPromDst;
+ mng_uint32 iX;
+ mng_uint8 iB;
+ mng_uint16 iW;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROMOTE_G8_GA16, MNG_LC_START);
+#endif
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iPromWidth; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iPromWidth; iX++)
+#endif
+ {
+ iB = *pSrcline;
+ /* no cheap transparency ? */
+ if ((!pBuf->bHasTRNS) || ((mng_uint16)iB != pBuf->iTRNSgray))
+ {
+ *(pDstline+2) = 0xFF;
+ *(pDstline+3) = 0xFF;
+ }
+
+ iW = ((mng_bitdepth_16)pData->fPromBitdepth) (iB);
+
+ *pDstline = (mng_uint8)(iW >> 8);
+ *(pDstline+1) = (mng_uint8)(iW && 0xFF);
+
+ pSrcline++;
+ pDstline += 4;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROMOTE_G8_GA16, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_16BIT_SUPPORT
+mng_retcode mng_promote_g16_ga16 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pPromBuf;
+ mng_uint16p pSrcline = (mng_uint16p)pData->pPromSrc;
+ mng_uint16p pDstline = (mng_uint16p)pData->pPromDst;
+ mng_uint32 iX;
+ mng_uint16 iW;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROMOTE_G16_GA16, MNG_LC_START);
+#endif
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iPromWidth; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iPromWidth; iX++)
+#endif
+ {
+ iW = *pSrcline;
+ /* no cheap transparency ? */
+ if ((!pBuf->bHasTRNS) || ((mng_uint16)iW != pBuf->iTRNSgray))
+ *(pDstline+1) = 0xFFFF;
+
+ *pDstline = iW;
+
+ pSrcline++;
+ pDstline += 2;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROMOTE_G16_GA16, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif
+
+/* ************************************************************************** */
+
+mng_retcode mng_promote_g8_rgb8 (mng_datap pData)
+{
+ mng_uint8p pSrcline = (mng_uint8p)pData->pPromSrc;
+ mng_uint8p pDstline = (mng_uint8p)pData->pPromDst;
+ mng_uint32 iX;
+ mng_uint8 iB;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROMOTE_G8_RGB8, MNG_LC_START);
+#endif
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iPromWidth; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iPromWidth; iX++)
+#endif
+ {
+ iB = *pSrcline;
+
+ if (pData->fPromBitdepth) /* bitdepth promoted ? */
+ iB = ((mng_bitdepth_8)pData->fPromBitdepth) (iB);
+
+ *pDstline = iB;
+ *(pDstline+1) = iB;
+ *(pDstline+2) = iB;
+
+ pSrcline++;
+ pDstline += 3;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROMOTE_G8_RGB8, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_16BIT_SUPPORT
+mng_retcode mng_promote_g8_rgb16 (mng_datap pData)
+{
+ mng_uint8p pSrcline = (mng_uint8p)pData->pPromSrc;
+ mng_uint8p pDstline = (mng_uint8p)pData->pPromDst;
+ mng_uint32 iX;
+ mng_uint8 iB;
+ mng_uint16 iW;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROMOTE_G8_RGB16, MNG_LC_START);
+#endif
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iPromWidth; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iPromWidth; iX++)
+#endif
+ {
+ iB = *pSrcline;
+ iW = ((mng_bitdepth_16)pData->fPromBitdepth) (iB);
+
+ iB = (mng_uint8)(iW >> 8);
+ *pDstline = iB;
+ *(pDstline+2) = iB;
+ *(pDstline+4) = iB;
+ iB = (mng_uint8)(iW && 0xFF);
+ *(pDstline+1) = iB;
+ *(pDstline+3) = iB;
+ *(pDstline+5) = iB;
+
+ pSrcline++;
+ pDstline += 6;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROMOTE_G8_RGB16, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_16BIT_SUPPORT
+mng_retcode mng_promote_g16_rgb16 (mng_datap pData)
+{
+ mng_uint16p pSrcline = (mng_uint16p)pData->pPromSrc;
+ mng_uint16p pDstline = (mng_uint16p)pData->pPromDst;
+ mng_uint32 iX;
+ mng_uint16 iW;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROMOTE_G16_RGB16, MNG_LC_START);
+#endif
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iPromWidth; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iPromWidth; iX++)
+#endif
+ {
+ iW = *pSrcline;
+
+ *pDstline = iW;
+ *(pDstline+1) = iW;
+ *(pDstline+2) = iW;
+
+ pSrcline++;
+ pDstline += 3;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROMOTE_G16_RGB16, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif
+
+/* ************************************************************************** */
+
+mng_retcode mng_promote_g8_rgba8 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pPromBuf;
+ mng_uint8p pSrcline = (mng_uint8p)pData->pPromSrc;
+ mng_uint8p pDstline = (mng_uint8p)pData->pPromDst;
+ mng_uint32 iX;
+ mng_uint8 iB;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROMOTE_G8_RGBA8, MNG_LC_START);
+#endif
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iPromWidth; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iPromWidth; iX++)
+#endif
+ {
+ iB = *pSrcline;
+ /* no cheap transparency ? */
+ if ((!pBuf->bHasTRNS) || ((mng_uint16)iB != pBuf->iTRNSgray))
+ *(pDstline+3) = 0xFF;
+
+ if (pData->fPromBitdepth) /* bitdepth promoted ? */
+ iB = ((mng_bitdepth_8)pData->fPromBitdepth) (iB);
+
+ *pDstline = iB;
+ *(pDstline+1) = iB;
+ *(pDstline+2) = iB;
+
+ pSrcline++;
+ pDstline += 4;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROMOTE_G8_RGBA8, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_16BIT_SUPPORT
+mng_retcode mng_promote_g8_rgba16 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pPromBuf;
+ mng_uint8p pSrcline = (mng_uint8p)pData->pPromSrc;
+ mng_uint8p pDstline = (mng_uint8p)pData->pPromDst;
+ mng_uint32 iX;
+ mng_uint8 iB;
+ mng_uint16 iW;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROMOTE_G8_RGBA16, MNG_LC_START);
+#endif
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iPromWidth; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iPromWidth; iX++)
+#endif
+ {
+ iB = *pSrcline;
+ /* no cheap transparency ? */
+ if ((!pBuf->bHasTRNS) || ((mng_uint16)iB != pBuf->iTRNSgray))
+ {
+ *(pDstline+6) = 0xFF;
+ *(pDstline+7) = 0xFF;
+ }
+
+ iW = ((mng_bitdepth_16)pData->fPromBitdepth) (iB);
+
+ iB = (mng_uint8)(iW >> 8);
+ *pDstline = iB;
+ *(pDstline+2) = iB;
+ *(pDstline+4) = iB;
+ iB = (mng_uint8)(iW && 0xFF);
+ *(pDstline+1) = iB;
+ *(pDstline+3) = iB;
+ *(pDstline+5) = iB;;
+
+ pSrcline++;
+ pDstline += 8;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROMOTE_G8_RGBA16, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_16BIT_SUPPORT
+mng_retcode mng_promote_g16_rgba16 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pPromBuf;
+ mng_uint16p pSrcline = (mng_uint16p)pData->pPromSrc;
+ mng_uint16p pDstline = (mng_uint16p)pData->pPromDst;
+ mng_uint32 iX;
+ mng_uint16 iW;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROMOTE_G16_RGBA16, MNG_LC_START);
+#endif
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iPromWidth; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iPromWidth; iX++)
+#endif
+ {
+ iW = *pSrcline;
+ /* no cheap transparency ? */
+ if ((!pBuf->bHasTRNS) || (iW != pBuf->iTRNSgray))
+ *(pDstline+3) = 0xFFFF;
+
+ *pDstline = iW;
+ *(pDstline+1) = iW;
+ *(pDstline+2) = iW;
+
+ pSrcline++;
+ pDstline += 4;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROMOTE_G16_RGBA16, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_16BIT_SUPPORT
+mng_retcode mng_promote_ga8_ga16 (mng_datap pData)
+{
+ mng_uint8p pSrcline = (mng_uint8p)pData->pPromSrc;
+ mng_uint8p pDstline = (mng_uint8p)pData->pPromDst;
+ mng_uint32 iX;
+ mng_uint16 iW;
+ mng_uint16 iA;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROMOTE_GA8_GA16, MNG_LC_START);
+#endif
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iPromWidth; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iPromWidth; iX++)
+#endif
+ {
+ iW = ((mng_bitdepth_16)pData->fPromBitdepth) (*pSrcline);
+ iA = ((mng_bitdepth_16)pData->fPromBitdepth) (*(pSrcline+1));
+
+ *pDstline = (mng_uint8)(iW >> 8);
+ *(pDstline+1) = (mng_uint8)(iW && 0xFF);
+ *(pDstline+2) = (mng_uint8)(iA >> 8);
+ *(pDstline+3) = (mng_uint8)(iA && 0xFF);
+
+ pSrcline += 2;
+ pDstline += 4;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROMOTE_GA8_GA16, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif
+
+/* ************************************************************************** */
+
+mng_retcode mng_promote_ga8_rgba8 (mng_datap pData)
+{
+ mng_uint8p pSrcline = (mng_uint8p)pData->pPromSrc;
+ mng_uint8p pDstline = (mng_uint8p)pData->pPromDst;
+ mng_uint32 iX;
+ mng_uint8 iB;
+ mng_uint8 iA;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROMOTE_GA8_RGBA8, MNG_LC_START);
+#endif
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iPromWidth; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iPromWidth; iX++)
+#endif
+ {
+ iB = *pSrcline;
+ iA = *(pSrcline+1);
+
+ *pDstline = iB;
+ *(pDstline+1) = iB;
+ *(pDstline+2) = iB;
+ *(pDstline+3) = iA;
+
+ pSrcline += 2;
+ pDstline += 4;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROMOTE_GA8_RGBA8, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_16BIT_SUPPORT
+mng_retcode mng_promote_ga8_rgba16 (mng_datap pData)
+{
+ mng_uint8p pSrcline = (mng_uint8p)pData->pPromSrc;
+ mng_uint8p pDstline = (mng_uint8p)pData->pPromDst;
+ mng_uint32 iX;
+ mng_uint8 iB;
+ mng_uint16 iW;
+ mng_uint16 iA;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROMOTE_GA8_RGBA16, MNG_LC_START);
+#endif
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iPromWidth; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iPromWidth; iX++)
+#endif
+ {
+ iW = ((mng_bitdepth_16)pData->fPromBitdepth) (*pSrcline);
+ iA = ((mng_bitdepth_16)pData->fPromBitdepth) (*(pSrcline+1));
+
+ iB = (mng_uint8)(iW >> 8);
+ *pDstline = iB;
+ *(pDstline+2) = iB;
+ *(pDstline+4) = iB;
+ iB = (mng_uint8)(iW && 0xFF);
+ *(pDstline+1) = iB;
+ *(pDstline+3) = iB;
+ *(pDstline+5) = iB;
+ *(pDstline+6) = (mng_uint8)(iA >> 8);
+ *(pDstline+7) = (mng_uint8)(iA && 0xFF);
+
+ pSrcline += 2;
+ pDstline += 8;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROMOTE_GA8_RGBA16, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_16BIT_SUPPORT
+mng_retcode mng_promote_ga16_rgba16 (mng_datap pData)
+{
+ mng_uint16p pSrcline = (mng_uint16p)pData->pPromSrc;
+ mng_uint16p pDstline = (mng_uint16p)pData->pPromDst;
+ mng_uint32 iX;
+ mng_uint16 iW;
+ mng_uint16 iA;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROMOTE_GA16_RGBA16, MNG_LC_START);
+#endif
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iPromWidth; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iPromWidth; iX++)
+#endif
+ {
+ iW = *pSrcline;
+ iA = *(pSrcline+1);
+
+ *pDstline = iW;
+ *(pDstline+1) = iW;
+ *(pDstline+2) = iW;
+ *(pDstline+3) = iA;
+
+ pSrcline += 2;
+ pDstline += 4;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROMOTE_GA16_RGBA16, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_16BIT_SUPPORT
+mng_retcode mng_promote_rgb8_rgb16 (mng_datap pData)
+{
+ mng_uint8p pSrcline = (mng_uint8p)pData->pPromSrc;
+ mng_uint8p pDstline = (mng_uint8p)pData->pPromDst;
+ mng_uint32 iX;
+ mng_uint16 iR;
+ mng_uint16 iG;
+ mng_uint16 iB;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROMOTE_RGB8_RGB16, MNG_LC_START);
+#endif
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iPromWidth; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iPromWidth; iX++)
+#endif
+ {
+ iR = ((mng_bitdepth_16)pData->fPromBitdepth) (*pSrcline);
+ iG = ((mng_bitdepth_16)pData->fPromBitdepth) (*(pSrcline+1));
+ iB = ((mng_bitdepth_16)pData->fPromBitdepth) (*(pSrcline+2));
+
+ *pDstline = (mng_uint8)(iR >> 8);
+ *(pDstline+1) = (mng_uint8)(iR && 0xFF);
+ *(pDstline+2) = (mng_uint8)(iG >> 8);
+ *(pDstline+3) = (mng_uint8)(iG && 0xFF);
+ *(pDstline+4) = (mng_uint8)(iB >> 8);
+ *(pDstline+5) = (mng_uint8)(iB && 0xFF);
+
+ pSrcline += 3;
+ pDstline += 6;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROMOTE_RGB8_RGB16, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif
+
+/* ************************************************************************** */
+
+mng_retcode mng_promote_rgb8_rgba8 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pPromBuf;
+ mng_uint8p pSrcline = (mng_uint8p)pData->pPromSrc;
+ mng_uint8p pDstline = (mng_uint8p)pData->pPromDst;
+ mng_uint32 iX;
+ mng_uint8 iR;
+ mng_uint8 iG;
+ mng_uint8 iB;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROMOTE_RGB8_RGBA8, MNG_LC_START);
+#endif
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iPromWidth; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iPromWidth; iX++)
+#endif
+ {
+ iR = *pSrcline;
+ iG = *(pSrcline+1);
+ iB = *(pSrcline+2);
+ /* no cheap transparency ? */
+ if ((!pBuf->bHasTRNS) || ((mng_uint16)iR != pBuf->iTRNSred) ||
+ ((mng_uint16)iG != pBuf->iTRNSgreen) || ((mng_uint16)iB != pBuf->iTRNSblue))
+ *(pDstline+3) = 0xFF;
+
+ *pDstline = iR;
+ *(pDstline+1) = iG;
+ *(pDstline+2) = iB;
+
+ pSrcline += 3;
+ pDstline += 4;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROMOTE_RGB8_RGBA8, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_16BIT_SUPPORT
+mng_retcode mng_promote_rgb8_rgba16 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pPromBuf;
+ mng_uint8p pSrcline = (mng_uint8p)pData->pPromSrc;
+ mng_uint8p pDstline = (mng_uint8p)pData->pPromDst;
+ mng_uint32 iX;
+ mng_uint8 iR;
+ mng_uint8 iG;
+ mng_uint8 iB;
+ mng_uint16 iRw;
+ mng_uint16 iGw;
+ mng_uint16 iBw;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROMOTE_RGB8_RGBA16, MNG_LC_START);
+#endif
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iPromWidth; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iPromWidth; iX++)
+#endif
+ {
+ iR = *pSrcline;
+ iG = *(pSrcline+1);
+ iB = *(pSrcline+2);
+ /* no cheap transparency ? */
+ if ((!pBuf->bHasTRNS) || ((mng_uint16)iR != pBuf->iTRNSred) ||
+ ((mng_uint16)iG != pBuf->iTRNSgreen) || ((mng_uint16)iB != pBuf->iTRNSblue))
+ {
+ *(pDstline+6) = 0xFF;
+ *(pDstline+7) = 0xFF;
+ }
+
+ iRw = ((mng_bitdepth_16)pData->fPromBitdepth) (iR);
+ iGw = ((mng_bitdepth_16)pData->fPromBitdepth) (iG);
+ iBw = ((mng_bitdepth_16)pData->fPromBitdepth) (iB);
+
+ *pDstline = (mng_uint8)(iRw >> 8);
+ *(pDstline+1) = (mng_uint8)(iRw && 0xFF);
+ *(pDstline+2) = (mng_uint8)(iGw >> 8);
+ *(pDstline+3) = (mng_uint8)(iGw && 0xFF);
+ *(pDstline+4) = (mng_uint8)(iBw >> 8);
+ *(pDstline+5) = (mng_uint8)(iBw && 0xFF);
+
+ pSrcline += 3;
+ pDstline += 8;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROMOTE_RGB8_RGBA16, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_16BIT_SUPPORT
+mng_retcode mng_promote_rgb16_rgba16 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pPromBuf;
+ mng_uint16p pSrcline = (mng_uint16p)pData->pPromSrc;
+ mng_uint16p pDstline = (mng_uint16p)pData->pPromDst;
+ mng_uint32 iX;
+ mng_uint16 iR;
+ mng_uint16 iG;
+ mng_uint16 iB;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROMOTE_RGB16_RGBA16, MNG_LC_START);
+#endif
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iPromWidth; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iPromWidth; iX++)
+#endif
+ {
+ iR = *pSrcline;
+ iG = *(pSrcline+1);
+ iB = *(pSrcline+2);
+ /* no cheap transparency ? */
+ if ((!pBuf->bHasTRNS) || (iR != pBuf->iTRNSred) ||
+ (iG != pBuf->iTRNSgreen) || (iB != pBuf->iTRNSblue))
+ *(pDstline+3) = 0xFFFF;
+
+ *pDstline = iR;
+ *(pDstline+1) = iG;
+ *(pDstline+2) = iB;
+
+ pSrcline += 3;
+ pDstline += 4;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROMOTE_RGB16_RGBA16, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif
+
+/* ************************************************************************** */
+
+mng_retcode mng_promote_idx8_rgb8 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pPromBuf;
+ mng_uint8p pSrcline = (mng_uint8p)pData->pPromSrc;
+ mng_uint8p pDstline = (mng_uint8p)pData->pPromDst;
+ mng_uint32 iX;
+ mng_uint8 iB;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROMOTE_IDX8_RGB8, MNG_LC_START);
+#endif
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iPromWidth; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iPromWidth; iX++)
+#endif
+ {
+ iB = *pSrcline;
+
+ if ((mng_uint32)iB < pBuf->iPLTEcount)
+ {
+ *pDstline = pBuf->aPLTEentries [iB].iRed;
+ *(pDstline+1) = pBuf->aPLTEentries [iB].iGreen;
+ *(pDstline+2) = pBuf->aPLTEentries [iB].iBlue;
+ }
+
+ pSrcline++;
+ pDstline += 3;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROMOTE_IDX8_RGB8, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_16BIT_SUPPORT
+mng_retcode mng_promote_idx8_rgb16 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pPromBuf;
+ mng_uint8p pSrcline = (mng_uint8p)pData->pPromSrc;
+ mng_uint8p pDstline = (mng_uint8p)pData->pPromDst;
+ mng_uint32 iX;
+ mng_uint8 iN;
+ mng_uint16 iR;
+ mng_uint16 iG;
+ mng_uint16 iB;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROMOTE_IDX8_RGB16, MNG_LC_START);
+#endif
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iPromWidth; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iPromWidth; iX++)
+#endif
+ {
+ iN = *pSrcline;
+
+ if ((mng_uint32)iN < pBuf->iPLTEcount)
+ {
+ iR = ((mng_bitdepth_16)pData->fPromBitdepth) (pBuf->aPLTEentries [iN].iRed);
+ iG = ((mng_bitdepth_16)pData->fPromBitdepth) (pBuf->aPLTEentries [iN].iGreen);
+ iB = ((mng_bitdepth_16)pData->fPromBitdepth) (pBuf->aPLTEentries [iN].iBlue);
+ *pDstline = (mng_uint8)(iR >> 8);
+ *(pDstline+1) = (mng_uint8)(iR && 0xFF);
+ *(pDstline+2) = (mng_uint8)(iG >> 8);
+ *(pDstline+3) = (mng_uint8)(iG && 0xFF);
+ *(pDstline+4) = (mng_uint8)(iB >> 8);
+ *(pDstline+5) = (mng_uint8)(iB && 0xFF);
+ }
+
+ pSrcline++;
+ pDstline += 6;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROMOTE_IDX8_RGB16, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif
+
+/* ************************************************************************** */
+
+mng_retcode mng_promote_idx8_rgba8 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pPromBuf;
+ mng_uint8p pSrcline = (mng_uint8p)pData->pPromSrc;
+ mng_uint8p pDstline = (mng_uint8p)pData->pPromDst;
+ mng_uint32 iX;
+ mng_uint8 iB;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROMOTE_IDX8_RGBA8, MNG_LC_START);
+#endif
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iPromWidth; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iPromWidth; iX++)
+#endif
+ {
+ iB = *pSrcline;
+
+ if ((mng_uint32)iB < pBuf->iPLTEcount)
+ {
+ *pDstline = pBuf->aPLTEentries [iB].iRed;
+ *(pDstline+1) = pBuf->aPLTEentries [iB].iGreen;
+ *(pDstline+2) = pBuf->aPLTEentries [iB].iBlue;
+
+ if ((pBuf->bHasTRNS) && ((mng_uint32)iB < pBuf->iTRNScount))
+ *(pDstline+3) = pBuf->aTRNSentries [iB];
+ else
+ *(pDstline+3) = 0xFF;
+ }
+
+ pSrcline++;
+ pDstline += 4;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROMOTE_IDX8_RGBA8, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_16BIT_SUPPORT
+mng_retcode mng_promote_idx8_rgba16 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pPromBuf;
+ mng_uint8p pSrcline = (mng_uint8p)pData->pPromSrc;
+ mng_uint8p pDstline = (mng_uint8p)pData->pPromDst;
+ mng_uint32 iX;
+ mng_uint8 iN;
+ mng_uint16 iR;
+ mng_uint16 iG;
+ mng_uint16 iB;
+ mng_uint16 iA;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROMOTE_IDX8_RGBA16, MNG_LC_START);
+#endif
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iPromWidth; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iPromWidth; iX++)
+#endif
+ {
+ iN = *pSrcline;
+
+ if ((mng_uint32)iN < pBuf->iPLTEcount)
+ {
+ iR = ((mng_bitdepth_16)pData->fPromBitdepth) (pBuf->aPLTEentries [iN].iRed);
+ iG = ((mng_bitdepth_16)pData->fPromBitdepth) (pBuf->aPLTEentries [iN].iGreen);
+ iB = ((mng_bitdepth_16)pData->fPromBitdepth) (pBuf->aPLTEentries [iN].iBlue);
+
+ if ((pBuf->bHasTRNS) && ((mng_uint32)iN < pBuf->iTRNScount))
+ iA = ((mng_bitdepth_16)pData->fPromBitdepth) (pBuf->aTRNSentries [iN]);
+ else
+ iA = 0xFFFF;
+
+ *pDstline = (mng_uint8)(iR >> 8);
+ *(pDstline+1) = (mng_uint8)(iR && 0xFF);
+ *(pDstline+2) = (mng_uint8)(iG >> 8);
+ *(pDstline+3) = (mng_uint8)(iG && 0xFF);
+ *(pDstline+4) = (mng_uint8)(iB >> 8);
+ *(pDstline+5) = (mng_uint8)(iB && 0xFF);
+ *(pDstline+6) = (mng_uint8)(iA >> 8);
+ *(pDstline+7) = (mng_uint8)(iA && 0xFF);
+ }
+
+ pSrcline++;
+ pDstline += 8;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROMOTE_IDX8_RGBA16, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode mng_promote_rgba8_rgba16 (mng_datap pData)
+{
+ mng_uint8p pSrcline = (mng_uint8p)pData->pPromSrc;
+ mng_uint8p pDstline = (mng_uint8p)pData->pPromDst;
+ mng_uint32 iX;
+ mng_uint16 iR;
+ mng_uint16 iG;
+ mng_uint16 iB;
+ mng_uint16 iA;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROMOTE_RGBA8_RGBA16, MNG_LC_START);
+#endif
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iPromWidth; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iPromWidth; iX++)
+#endif
+ {
+ iR = ((mng_bitdepth_16)pData->fPromBitdepth) (*pSrcline);
+ iG = ((mng_bitdepth_16)pData->fPromBitdepth) (*(pSrcline+1));
+ iB = ((mng_bitdepth_16)pData->fPromBitdepth) (*(pSrcline+2));
+ iA = ((mng_bitdepth_16)pData->fPromBitdepth) (*(pSrcline+3));
+
+ *pDstline = (mng_uint8)(iR >> 8);
+ *(pDstline+1) = (mng_uint8)(iR && 0xFF);
+ *(pDstline+2) = (mng_uint8)(iG >> 8);
+ *(pDstline+3) = (mng_uint8)(iG && 0xFF);
+ *(pDstline+4) = (mng_uint8)(iB >> 8);
+ *(pDstline+5) = (mng_uint8)(iB && 0xFF);
+ *(pDstline+6) = (mng_uint8)(iA >> 8);
+ *(pDstline+7) = (mng_uint8)(iA && 0xFF);
+
+ pSrcline += 4;
+ pDstline += 8;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROMOTE_RGBA8_RGBA16, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif
+#endif /* !defined(MNG_NO_DELTA_PNG) || !defined(MNG_SKIPCHUNK_PAST) || !defined(MNG_SKIPCHUNK_MAGN) */
+
+/* ************************************************************************** */
+/* * * */
+/* * Row processing routines - convert uncompressed data from zlib to * */
+/* * managable row-data which serves as input to the color-management * */
+/* * routines * */
+/* * * */
+/* ************************************************************************** */
+
+#ifndef MNG_NO_1_2_4BIT_SUPPORT
+mng_retcode mng_process_g1 (mng_datap pData)
+{
+ mng_uint8p pWorkrow;
+ mng_uint8p pRGBArow;
+ mng_int32 iX;
+ mng_uint8 iB;
+ mng_uint8 iM;
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_G1, MNG_LC_START);
+#endif
+
+ if (!pBuf) /* no object? then use obj 0 */
+ pBuf = ((mng_imagep)pData->pObjzero)->pImgbuf;
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pRGBArow = pData->pRGBArow;
+ iM = 0; /* start at pixel 0 */
+ iB = 0;
+
+ if (pBuf->bHasTRNS) /* tRNS encountered ? */
+ {
+ if (pBuf->iTRNSgray) /* white transparent ? */
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ if (!iM) /* mask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0x80;
+ }
+
+ if (iB & iM) /* is it white ? */
+ /* transparent ! */
+ mng_put_uint32 (pRGBArow, 0x00000000);
+ else /* opaque black */
+ mng_put_uint32 (pRGBArow, 0x000000FF);
+
+ pRGBArow += 4; /* next pixel */
+ iM >>= 1;
+ }
+ }
+ else /* black transparent */
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ if (!iM) /* mask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0x80;
+ }
+
+ if (iB & iM) /* is it white ? */
+ /* opaque white */
+ mng_put_uint32 (pRGBArow, 0xFFFFFFFF);
+ else /* transparent */
+ mng_put_uint32 (pRGBArow, 0x00000000);
+
+ pRGBArow += 4; /* next pixel */
+ iM >>= 1;
+ }
+ }
+
+ pData->bIsOpaque = MNG_FALSE; /* it's not fully opaque */
+ }
+ else /* no transparency */
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ if (!iM) /* mask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0x80;
+ }
+
+ if (iB & iM) /* is it white ? */
+ /* opaque white */
+ mng_put_uint32 (pRGBArow, 0xFFFFFFFF);
+ else /* opaque black */
+ mng_put_uint32 (pRGBArow, 0x000000FF);
+
+ pRGBArow += 4; /* next pixel */
+ iM >>= 1;
+ }
+
+ pData->bIsOpaque = MNG_TRUE; /* it's fully opaque */
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_G1, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode mng_process_g2 (mng_datap pData)
+{
+ mng_uint8p pWorkrow;
+ mng_uint8p pRGBArow;
+ mng_int32 iX;
+ mng_uint8 iB;
+ mng_uint8 iM;
+ mng_uint32 iS;
+ mng_uint8 iQ;
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+#ifdef MNG_OPTIMIZE_FOOTPRINT_SWITCH
+ const mng_uint32 level[4] = { 0x000000FF, 0x555555FF,
+ 0xAAAAAAFF, 0xFFFFFFFF};
+#endif
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_G2, MNG_LC_START);
+#endif
+
+ if (!pBuf) /* no object? then use obj 0 */
+ pBuf = ((mng_imagep)pData->pObjzero)->pImgbuf;
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pRGBArow = pData->pRGBArow;
+ iM = 0; /* start at pixel 0 */
+ iB = 0;
+ iS = 0;
+
+ if (pBuf->bHasTRNS) /* tRNS encountered ? */
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ if (!iM) /* mask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0xC0;
+ iS = 6;
+ }
+ /* determine gray level */
+ iQ = (mng_uint8)((iB & iM) >> iS);
+
+ if (iQ == pBuf->iTRNSgray) /* transparent ? */
+ mng_put_uint32 (pRGBArow, 0x00000000);
+ else
+ {
+#ifdef MNG_OPTIMIZE_FOOTPRINT_SWITCH
+ mng_put_uint32 (pRGBArow, level[iQ]);
+#else
+ switch (iQ) /* determine the gray level */
+ {
+ case 0x03 : { mng_put_uint32 (pRGBArow, 0xFFFFFFFF); break; }
+ case 0x02 : { mng_put_uint32 (pRGBArow, 0xAAAAAAFF); break; }
+ case 0x01 : { mng_put_uint32 (pRGBArow, 0x555555FF); break; }
+ default : { mng_put_uint32 (pRGBArow, 0x000000FF); }
+ }
+#endif
+ }
+
+ pRGBArow += 4; /* next pixel */
+ iM >>= 2;
+ iS -= 2;
+ }
+
+ pData->bIsOpaque = MNG_FALSE; /* it's not fully opaque */
+ }
+ else
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ if (!iM) /* mask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0xC0;
+ iS = 6;
+ }
+
+#ifdef MNG_OPTIMIZE_FOOTPRINT_SWITCH
+ mng_put_uint32 (pRGBArow, level[((iB & iM) >> iS)] );
+#else
+ switch ((iB & iM) >> iS) /* determine the gray level */
+ {
+ case 0x03 : { mng_put_uint32 (pRGBArow, 0xFFFFFFFF); break; }
+ case 0x02 : { mng_put_uint32 (pRGBArow, 0xAAAAAAFF); break; }
+ case 0x01 : { mng_put_uint32 (pRGBArow, 0x555555FF); break; }
+ default : { mng_put_uint32 (pRGBArow, 0x000000FF); }
+ }
+#endif
+
+ pRGBArow += 4; /* next pixel */
+ iM >>= 2;
+ iS -= 2;
+ }
+
+ pData->bIsOpaque = MNG_TRUE; /* it's fully opaque */
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_G2, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode mng_process_g4 (mng_datap pData)
+{
+ mng_uint8p pWorkrow;
+ mng_uint8p pRGBArow;
+ mng_int32 iX;
+ mng_uint8 iB;
+ mng_uint8 iM;
+ mng_uint32 iS;
+ mng_uint8 iQ;
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_G4, MNG_LC_START);
+#endif
+
+ if (!pBuf) /* no object? then use obj 0 */
+ pBuf = ((mng_imagep)pData->pObjzero)->pImgbuf;
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pRGBArow = pData->pRGBArow;
+ iM = 0; /* start at pixel 0 */
+ iB = 0;
+ iS = 0;
+
+ if (pBuf->bHasTRNS) /* tRNS encountered ? */
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ if (!iM) /* mask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0xF0;
+ iS = 4;
+ }
+ /* get the gray level */
+ iQ = (mng_uint8)((iB & iM) >> iS);
+
+ if (iQ == pBuf->iTRNSgray) /* transparent ? */
+ {
+ *pRGBArow = 0; /* put in intermediate row */
+ *(pRGBArow+1) = 0;
+ *(pRGBArow+2) = 0;
+ *(pRGBArow+3) = 0;
+ }
+ else
+ { /* expand to 8-bit by replication */
+ iQ = (mng_uint8)(iQ + (iQ << 4));
+
+ *pRGBArow = iQ; /* put in intermediate row */
+ *(pRGBArow+1) = iQ;
+ *(pRGBArow+2) = iQ;
+ *(pRGBArow+3) = 0xFF;
+ }
+
+ pRGBArow += 4; /* next pixel */
+ iM >>= 4;
+ iS -= 4;
+ }
+
+ pData->bIsOpaque = MNG_FALSE; /* it's not fully opaque */
+ }
+ else
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ if (!iM) /* mask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0xF0;
+ iS = 4;
+ }
+ /* get the gray level */
+ iQ = (mng_uint8)((iB & iM) >> iS);
+ iQ = (mng_uint8)(iQ + (iQ << 4));/* expand to 8-bit by replication */
+
+ *pRGBArow = iQ; /* put in intermediate row */
+ *(pRGBArow+1) = iQ;
+ *(pRGBArow+2) = iQ;
+ *(pRGBArow+3) = 0xFF;
+
+ pRGBArow += 4; /* next pixel */
+ iM >>= 4;
+ iS -= 4;
+ }
+
+ pData->bIsOpaque = MNG_TRUE; /* it's fully opaque */
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_G4, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_NO_1_2_4BIT_SUPPORT */
+
+/* ************************************************************************** */
+
+mng_retcode mng_process_g8 (mng_datap pData)
+{
+ mng_uint8p pWorkrow;
+ mng_uint8p pRGBArow;
+ mng_int32 iX;
+ mng_uint8 iB;
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_G8, MNG_LC_START);
+#endif
+
+ if (!pBuf) /* no object? then use obj 0 */
+ pBuf = ((mng_imagep)pData->pObjzero)->pImgbuf;
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pRGBArow = pData->pRGBArow;
+
+ if (pBuf->bHasTRNS) /* tRNS encountered ? */
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ iB = *pWorkrow; /* get next input-byte */
+
+ if (iB == pBuf->iTRNSgray) /* transparent ? */
+ {
+ *pRGBArow = 0; /* put in intermediate row */
+ *(pRGBArow+1) = 0;
+ *(pRGBArow+2) = 0;
+ *(pRGBArow+3) = 0;
+ }
+ else
+ {
+ *pRGBArow = iB; /* put in intermediate row */
+ *(pRGBArow+1) = iB;
+ *(pRGBArow+2) = iB;
+ *(pRGBArow+3) = 0xFF;
+ }
+
+ pRGBArow += 4; /* next pixel */
+ pWorkrow++;
+ }
+
+ pData->bIsOpaque = MNG_FALSE; /* it's not fully opaque */
+ }
+ else
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ iB = *pWorkrow; /* get next input-byte */
+
+ *pRGBArow = iB; /* put in intermediate row */
+ *(pRGBArow+1) = iB;
+ *(pRGBArow+2) = iB;
+ *(pRGBArow+3) = 0xFF;
+
+ pRGBArow += 4; /* next pixel */
+ pWorkrow++;
+ }
+
+ pData->bIsOpaque = MNG_TRUE; /* it's fully opaque */
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_G8, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_16BIT_SUPPORT
+mng_retcode mng_process_g16 (mng_datap pData)
+{
+ mng_uint8p pWorkrow;
+ mng_uint8p pRGBArow;
+ mng_int32 iX;
+ mng_uint16 iW;
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_G16, MNG_LC_START);
+#endif
+
+ if (!pBuf) /* no object? then use obj 0 */
+ pBuf = ((mng_imagep)pData->pObjzero)->pImgbuf;
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pRGBArow = pData->pRGBArow;
+
+ if (pBuf->bHasTRNS) /* tRNS encountered ? */
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ iW = mng_get_uint16 (pWorkrow); /* get input */
+
+ if (iW == pBuf->iTRNSgray) /* transparent ? */
+ { /* put in intermediate row */
+ mng_put_uint16 (pRGBArow, 0);
+ mng_put_uint16 (pRGBArow+2, 0);
+ mng_put_uint16 (pRGBArow+4, 0);
+ mng_put_uint16 (pRGBArow+6, 0);
+ }
+ else
+ { /* put in intermediate row */
+ mng_put_uint16 (pRGBArow, iW);
+ mng_put_uint16 (pRGBArow+2, iW);
+ mng_put_uint16 (pRGBArow+4, iW);
+ mng_put_uint16 (pRGBArow+6, 0xFFFF);
+ }
+
+ pRGBArow += 8; /* next pixel */
+ pWorkrow += 2;
+ }
+
+ pData->bIsOpaque = MNG_FALSE; /* it's not fully opaque */
+ }
+ else
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ iW = mng_get_uint16 (pWorkrow); /* get input */
+
+ mng_put_uint16 (pRGBArow, iW); /* and put in intermediate row */
+ mng_put_uint16 (pRGBArow+2, iW);
+ mng_put_uint16 (pRGBArow+4, iW);
+ mng_put_uint16 (pRGBArow+6, 0xFFFF);
+
+ pRGBArow += 8; /* next pixel */
+ pWorkrow += 2;
+ }
+
+ pData->bIsOpaque = MNG_TRUE; /* it's fully opaque */
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_G16, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif
+
+/* ************************************************************************** */
+
+mng_retcode mng_process_rgb8 (mng_datap pData)
+{
+ mng_uint8p pWorkrow;
+ mng_uint8p pRGBArow;
+ mng_int32 iX;
+ mng_uint8 iR, iG, iB;
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_RGB8, MNG_LC_START);
+#endif
+
+ if (!pBuf) /* no object? then use obj 0 */
+ pBuf = ((mng_imagep)pData->pObjzero)->pImgbuf;
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pRGBArow = pData->pRGBArow;
+
+ if (pBuf->bHasTRNS) /* tRNS encountered ? */
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ iR = *pWorkrow; /* get the RGB values */
+ iG = *(pWorkrow+1);
+ iB = *(pWorkrow+2);
+ /* transparent ? */
+ if ((iR == pBuf->iTRNSred) && (iG == pBuf->iTRNSgreen) &&
+ (iB == pBuf->iTRNSblue))
+ {
+ *pRGBArow = 0; /* this pixel is transparent ! */
+ *(pRGBArow+1) = 0;
+ *(pRGBArow+2) = 0;
+ *(pRGBArow+3) = 0;
+ }
+ else
+ {
+ *pRGBArow = iR; /* copy the RGB values */
+ *(pRGBArow+1) = iG;
+ *(pRGBArow+2) = iB;
+ *(pRGBArow+3) = 0xFF; /* this one isn't transparent */
+ }
+
+ pWorkrow += 3; /* next pixel */
+ pRGBArow += 4;
+ }
+
+ pData->bIsOpaque = MNG_FALSE; /* it's not fully opaque */
+ }
+ else
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ *pRGBArow = *pWorkrow; /* copy the RGB bytes */
+ *(pRGBArow+1) = *(pWorkrow+1);
+ *(pRGBArow+2) = *(pWorkrow+2);
+ *(pRGBArow+3) = 0xFF; /* no alpha; so always fully opaque */
+
+ pWorkrow += 3; /* next pixel */
+ pRGBArow += 4;
+ }
+
+ pData->bIsOpaque = MNG_TRUE; /* it's fully opaque */
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_RGB8, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_16BIT_SUPPORT
+mng_retcode mng_process_rgb16 (mng_datap pData)
+{
+ mng_uint8p pWorkrow;
+ mng_uint8p pRGBArow;
+ mng_int32 iX;
+ mng_uint16 iR, iG, iB;
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_RGB16, MNG_LC_START);
+#endif
+
+ if (!pBuf) /* no object? then use obj 0 */
+ pBuf = ((mng_imagep)pData->pObjzero)->pImgbuf;
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pRGBArow = pData->pRGBArow;
+
+ if (pBuf->bHasTRNS) /* tRNS encountered ? */
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ iR = mng_get_uint16 (pWorkrow); /* get the RGB values */
+ iG = mng_get_uint16 (pWorkrow+2);
+ iB = mng_get_uint16 (pWorkrow+4);
+ /* transparent ? */
+ if ((iR == pBuf->iTRNSred) && (iG == pBuf->iTRNSgreen) &&
+ (iB == pBuf->iTRNSblue))
+ { /* transparent then */
+ mng_put_uint16 (pRGBArow, 0);
+ mng_put_uint16 (pRGBArow+2, 0);
+ mng_put_uint16 (pRGBArow+4, 0);
+ mng_put_uint16 (pRGBArow+6, 0);
+ }
+ else
+ { /* put in intermediate row */
+ mng_put_uint16 (pRGBArow, iR);
+ mng_put_uint16 (pRGBArow+2, iG);
+ mng_put_uint16 (pRGBArow+4, iB);
+ mng_put_uint16 (pRGBArow+6, 0xFFFF);
+ }
+
+ pWorkrow += 6; /* next pixel */
+ pRGBArow += 8;
+ }
+
+ pData->bIsOpaque = MNG_FALSE; /* it's not fully opaque */
+ }
+ else
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ { /* copy the RGB values */
+ mng_put_uint16 (pRGBArow, mng_get_uint16 (pWorkrow ));
+ mng_put_uint16 (pRGBArow+2, mng_get_uint16 (pWorkrow+2));
+ mng_put_uint16 (pRGBArow+4, mng_get_uint16 (pWorkrow+4));
+ mng_put_uint16 (pRGBArow+6, 0xFFFF);
+
+ pWorkrow += 6; /* next pixel */
+ pRGBArow += 8;
+ }
+
+ pData->bIsOpaque = MNG_TRUE; /* it's fully opaque */
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_RGB16, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_1_2_4BIT_SUPPORT
+mng_retcode mng_process_idx1 (mng_datap pData)
+{
+ mng_uint8p pWorkrow;
+ mng_uint8p pRGBArow;
+ mng_int32 iX;
+ mng_uint8 iB;
+ mng_uint8 iM;
+ mng_uint32 iS;
+ mng_uint8 iQ;
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_IDX1, MNG_LC_START);
+#endif
+
+ if (!pBuf) /* no object? then use obj 0 */
+ pBuf = ((mng_imagep)pData->pObjzero)->pImgbuf;
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pRGBArow = pData->pRGBArow;
+ iM = 0; /* start at pixel 0 */
+ iB = 0;
+ iS = 0;
+
+ if (pBuf->bHasTRNS) /* tRNS encountered ? */
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ if (!iM) /* mask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0x80;
+ iS = 7;
+ }
+ /* get the index */
+ iQ = (mng_uint8)((iB & iM) >> iS);
+ /* index valid ? */
+ if ((mng_uint32)iQ < pBuf->iPLTEcount)
+ { /* put in intermediate row */
+ *pRGBArow = pBuf->aPLTEentries [iQ].iRed;
+ *(pRGBArow+1) = pBuf->aPLTEentries [iQ].iGreen;
+ *(pRGBArow+2) = pBuf->aPLTEentries [iQ].iBlue;
+ /* transparency for this index ? */
+ if ((mng_uint32)iQ < pBuf->iTRNScount)
+ *(pRGBArow+3) = pBuf->aTRNSentries [iQ];
+ else
+ *(pRGBArow+3) = 0xFF;
+ }
+ else
+ MNG_ERROR (pData, MNG_PLTEINDEXERROR);
+
+ pRGBArow += 4; /* next pixel */
+ iM >>= 1;
+ iS -= 1;
+ }
+
+ pData->bIsOpaque = MNG_FALSE; /* it's not fully opaque */
+ }
+ else
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ if (!iM) /* mask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0x80;
+ iS = 7;
+ }
+ /* get the index */
+ iQ = (mng_uint8)((iB & iM) >> iS);
+ /* index valid ? */
+ if ((mng_uint32)iQ < pBuf->iPLTEcount)
+ { /* put in intermediate row */
+ *pRGBArow = pBuf->aPLTEentries [iQ].iRed;
+ *(pRGBArow+1) = pBuf->aPLTEentries [iQ].iGreen;
+ *(pRGBArow+2) = pBuf->aPLTEentries [iQ].iBlue;
+ *(pRGBArow+3) = 0xFF;
+ }
+ else
+ MNG_ERROR (pData, MNG_PLTEINDEXERROR);
+
+ pRGBArow += 4; /* next pixel */
+ iM >>= 1;
+ iS -= 1;
+ }
+
+ pData->bIsOpaque = MNG_TRUE; /* it's fully opaque */
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_IDX1, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode mng_process_idx2 (mng_datap pData)
+{
+ mng_uint8p pWorkrow;
+ mng_uint8p pRGBArow;
+ mng_int32 iX;
+ mng_uint8 iB;
+ mng_uint8 iM;
+ mng_uint32 iS;
+ mng_uint8 iQ;
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_IDX2, MNG_LC_START);
+#endif
+
+ if (!pBuf) /* no object? then use obj 0 */
+ pBuf = ((mng_imagep)pData->pObjzero)->pImgbuf;
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pRGBArow = pData->pRGBArow;
+ iM = 0; /* start at pixel 0 */
+ iB = 0;
+ iS = 0;
+
+ if (pBuf->bHasTRNS) /* tRNS encountered ? */
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ if (!iM) /* mask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0xC0;
+ iS = 6;
+ }
+ /* get the index */
+ iQ = (mng_uint8)((iB & iM) >> iS);
+ /* index valid ? */
+ if ((mng_uint32)iQ < pBuf->iPLTEcount)
+ { /* put in intermediate row */
+ *pRGBArow = pBuf->aPLTEentries [iQ].iRed;
+ *(pRGBArow+1) = pBuf->aPLTEentries [iQ].iGreen;
+ *(pRGBArow+2) = pBuf->aPLTEentries [iQ].iBlue;
+ /* transparency for this index ? */
+ if ((mng_uint32)iQ < pBuf->iTRNScount)
+ *(pRGBArow+3) = pBuf->aTRNSentries [iQ];
+ else
+ *(pRGBArow+3) = 0xFF;
+ }
+ else
+ MNG_ERROR (pData, MNG_PLTEINDEXERROR);
+
+ pRGBArow += 4; /* next pixel */
+ iM >>= 2;
+ iS -= 2;
+ }
+
+ pData->bIsOpaque = MNG_FALSE; /* it's not fully opaque */
+ }
+ else
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ if (!iM) /* mask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0xC0;
+ iS = 6;
+ }
+ /* get the index */
+ iQ = (mng_uint8)((iB & iM) >> iS);
+ /* index valid ? */
+ if ((mng_uint32)iQ < pBuf->iPLTEcount)
+ { /* put in intermediate row */
+ *pRGBArow = pBuf->aPLTEentries [iQ].iRed;
+ *(pRGBArow+1) = pBuf->aPLTEentries [iQ].iGreen;
+ *(pRGBArow+2) = pBuf->aPLTEentries [iQ].iBlue;
+ *(pRGBArow+3) = 0xFF;
+ }
+ else
+ MNG_ERROR (pData, MNG_PLTEINDEXERROR);
+
+ pRGBArow += 4; /* next pixel */
+ iM >>= 2;
+ iS -= 2;
+ }
+
+ pData->bIsOpaque = MNG_TRUE; /* it's fully opaque */
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_IDX2, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode mng_process_idx4 (mng_datap pData)
+{
+ mng_uint8p pWorkrow;
+ mng_uint8p pRGBArow;
+ mng_int32 iX;
+ mng_uint8 iB;
+ mng_uint8 iM;
+ mng_uint32 iS;
+ mng_uint8 iQ;
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_IDX4, MNG_LC_START);
+#endif
+
+ if (!pBuf) /* no object? then use obj 0 */
+ pBuf = ((mng_imagep)pData->pObjzero)->pImgbuf;
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pRGBArow = pData->pRGBArow;
+ iM = 0; /* start at pixel 0 */
+ iB = 0;
+ iS = 0;
+
+ if (pBuf->bHasTRNS) /* tRNS encountered ? */
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ if (!iM) /* mask underflow ? */
+ {
+ iB = pWorkrow [0]; /* get next input-byte */
+ pWorkrow++;
+ iM = 0xF0;
+ iS = 4;
+ }
+ /* get the index */
+ iQ = (mng_uint8)((iB & iM) >> iS);
+ /* index valid ? */
+ if ((mng_uint32)iQ < pBuf->iPLTEcount)
+ { /* put in intermediate row */
+ pRGBArow [0] = pBuf->aPLTEentries [iQ].iRed;
+ pRGBArow [1] = pBuf->aPLTEentries [iQ].iGreen;
+ pRGBArow [2] = pBuf->aPLTEentries [iQ].iBlue;
+ /* transparency for this index ? */
+ if ((mng_uint32)iQ < pBuf->iTRNScount)
+ pRGBArow [3] = pBuf->aTRNSentries [iQ];
+ else
+ pRGBArow [3] = 0xFF;
+ }
+ else
+ MNG_ERROR (pData, MNG_PLTEINDEXERROR);
+
+ pRGBArow += 4; /* next pixel */
+ iM >>= 4;
+ iS -= 4;
+ }
+
+ pData->bIsOpaque = MNG_FALSE; /* it's not fully opaque */
+ }
+ else
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ if (!iM) /* mask underflow ? */
+ {
+ iB = pWorkrow [0]; /* get next input-byte */
+ pWorkrow++;
+ iM = 0xF0;
+ iS = 4;
+ }
+ /* get the index */
+ iQ = (mng_uint8)((iB & iM) >> iS);
+ /* index valid ? */
+ if ((mng_uint32)iQ < pBuf->iPLTEcount)
+ { /* put in intermediate row */
+ pRGBArow [0] = pBuf->aPLTEentries [iQ].iRed;
+ pRGBArow [1] = pBuf->aPLTEentries [iQ].iGreen;
+ pRGBArow [2] = pBuf->aPLTEentries [iQ].iBlue;
+ pRGBArow [3] = 0xFF;
+ }
+ else
+ MNG_ERROR (pData, MNG_PLTEINDEXERROR);
+
+ pRGBArow += 4; /* next pixel */
+ iM >>= 4;
+ iS -= 4;
+ }
+
+ pData->bIsOpaque = MNG_TRUE; /* it's fully opaque */
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_IDX4, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_NO_1_2_4BIT_SUPPORT */
+
+/* ************************************************************************** */
+
+mng_retcode mng_process_idx8 (mng_datap pData)
+{
+ mng_uint8p pWorkrow;
+ mng_uint8p pRGBArow;
+ mng_int32 iX;
+ mng_uint8 iQ;
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_IDX8, MNG_LC_START);
+#endif
+
+ if (!pBuf) /* no object? then use obj 0 */
+ pBuf = ((mng_imagep)pData->pObjzero)->pImgbuf;
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pRGBArow = pData->pRGBArow;
+
+ if (pBuf->bHasTRNS) /* tRNS encountered ? */
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ iQ = *pWorkrow; /* get input byte */
+ /* index valid ? */
+ if ((mng_uint32)iQ < pBuf->iPLTEcount)
+ { /* put in intermediate row */
+ pRGBArow [0] = pBuf->aPLTEentries [iQ].iRed;
+ pRGBArow [1] = pBuf->aPLTEentries [iQ].iGreen;
+ pRGBArow [2] = pBuf->aPLTEentries [iQ].iBlue;
+ /* transparency for this index ? */
+ if ((mng_uint32)iQ < pBuf->iTRNScount)
+ pRGBArow [3] = pBuf->aTRNSentries [iQ];
+ else
+ pRGBArow [3] = 0xFF;
+ }
+ else
+ MNG_ERROR (pData, MNG_PLTEINDEXERROR);
+
+ pRGBArow += 4; /* next pixel */
+ pWorkrow++;
+ }
+
+ pData->bIsOpaque = MNG_FALSE; /* it's not fully opaque */
+ }
+ else
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ iQ = *pWorkrow; /* get input byte */
+ /* index valid ? */
+ if ((mng_uint32)iQ < pBuf->iPLTEcount)
+ { /* put in intermediate row */
+ pRGBArow [0] = pBuf->aPLTEentries [iQ].iRed;
+ pRGBArow [1] = pBuf->aPLTEentries [iQ].iGreen;
+ pRGBArow [2] = pBuf->aPLTEentries [iQ].iBlue;
+ pRGBArow [3] = 0xFF;
+ }
+ else
+ MNG_ERROR (pData, MNG_PLTEINDEXERROR);
+
+ pRGBArow += 4; /* next pixel */
+ pWorkrow++;
+ }
+
+ pData->bIsOpaque = MNG_TRUE; /* it's fully opaque */
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_IDX8, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode mng_process_ga8 (mng_datap pData)
+{
+ mng_uint8p pWorkrow;
+ mng_uint8p pRGBArow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_GA8, MNG_LC_START);
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pRGBArow = pData->pRGBArow;
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ *pRGBArow = *pWorkrow; /* copy the gray value */
+ *(pRGBArow+1) = *pWorkrow;
+ *(pRGBArow+2) = *pWorkrow;
+ *(pRGBArow+3) = *(pWorkrow+1); /* copy the alpha value */
+
+ pWorkrow += 2; /* next pixel */
+ pRGBArow += 4;
+ }
+
+ pData->bIsOpaque = MNG_FALSE; /* it's definitely not fully opaque */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_GA8, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_16BIT_SUPPORT
+mng_retcode mng_process_ga16 (mng_datap pData)
+{
+ mng_uint8p pWorkrow;
+ mng_uint8p pRGBArow;
+ mng_int32 iX;
+ mng_uint16 iW;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_GA16, MNG_LC_START);
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pRGBArow = pData->pRGBArow;
+
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iRowsamples; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+#endif
+ {
+ iW = mng_get_uint16 (pWorkrow); /* copy the gray value */
+ mng_put_uint16 (pRGBArow, iW);
+ mng_put_uint16 (pRGBArow+2, iW);
+ mng_put_uint16 (pRGBArow+4, iW);
+ /* copy the alpha value */
+ mng_put_uint16 (pRGBArow+6, mng_get_uint16 (pWorkrow+2));
+
+ pWorkrow += 4; /* next pixel */
+ pRGBArow += 8;
+ }
+
+ pData->bIsOpaque = MNG_FALSE; /* it's definitely not fully opaque */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_GA16, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif
+
+/* ************************************************************************** */
+
+mng_retcode mng_process_rgba8 (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_RGBA8, MNG_LC_START);
+#endif
+ /* this is the easiest transform */
+ MNG_COPY (pData->pRGBArow, pData->pWorkrow + pData->iPixelofs, pData->iRowsize);
+
+ pData->bIsOpaque = MNG_FALSE; /* it's definitely not fully opaque */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_RGBA8, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_16BIT_SUPPORT
+mng_retcode mng_process_rgba16 (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_RGBA16, MNG_LC_START);
+#endif
+ /* this is the easiest transform */
+ MNG_COPY (pData->pRGBArow, pData->pWorkrow + pData->iPixelofs, pData->iRowsize);
+
+ pData->bIsOpaque = MNG_FALSE; /* it's definitely not fully opaque */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_RGBA16, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif
+
+/* ************************************************************************** */
+/* * * */
+/* * Row processing initialization routines - set up the variables needed * */
+/* * to process uncompressed row-data * */
+/* * * */
+/* ************************************************************************** */
+
+#ifndef MNG_OPTIMIZE_FOOTPRINT_INIT
+#ifndef MNG_NO_1_2_4BIT_SUPPORT
+mng_retcode mng_init_g1_ni (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_G1_NI, MNG_LC_START);
+#endif
+
+ if (pData->fDisplayrow)
+ pData->fProcessrow = (mng_fptr)mng_process_g1;
+
+ if (pData->pStoreobj) /* store in object too ? */
+ { /* immediate delta ? */
+#ifndef MNG_NO_DELTA_PNG
+ if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
+ pData->fStorerow = (mng_fptr)mng_delta_g1;
+ else
+#endif
+ pData->fStorerow = (mng_fptr)mng_store_g1;
+ }
+
+#ifdef FILTER192 /* leveling & differing ? */
+ if (pData->iFilter == MNG_FILTER_DIFFERING)
+ pData->fDifferrow = (mng_fptr)mng_differ_g1;
+#endif
+
+ pData->iPass = -1;
+ pData->iRow = 0;
+ pData->iRowinc = 1;
+ pData->iCol = 0;
+ pData->iColinc = 1;
+ pData->iRowsamples = pData->iDatawidth;
+ pData->iSamplemul = 1;
+ pData->iSampleofs = 7;
+ pData->iSamplediv = 3;
+ pData->iRowsize = (pData->iRowsamples + 7) >> 3;
+ pData->iRowmax = pData->iRowsize + pData->iPixelofs;
+ pData->iFilterbpp = 1;
+ pData->bIsRGBA16 = MNG_FALSE; /* intermediate row is 8-bit deep */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_G1_NI, MNG_LC_END);
+#endif
+
+ return mng_init_rowproc (pData);
+}
+
+/* ************************************************************************** */
+
+mng_retcode mng_init_g1_i (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_G1_I, MNG_LC_START);
+#endif
+
+ if (pData->fDisplayrow)
+ pData->fProcessrow = (mng_fptr)mng_process_g1;
+
+ if (pData->pStoreobj) /* store in object too ? */
+ { /* immediate delta ? */
+#ifndef MNG_NO_DELTA_PNG
+ if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
+ pData->fStorerow = (mng_fptr)mng_delta_g1;
+ else
+#endif
+ pData->fStorerow = (mng_fptr)mng_store_g1;
+ }
+
+#ifdef FILTER192 /* leveling & differing ? */
+ if (pData->iFilter == MNG_FILTER_DIFFERING)
+ pData->fDifferrow = (mng_fptr)mng_differ_g1;
+#endif
+
+ pData->iPass = 0; /* from 0..6; is 1..7 in specifications */
+ pData->iRow = interlace_row [0];
+ pData->iRowinc = interlace_rowskip [0];
+ pData->iCol = interlace_col [0];
+ pData->iColinc = interlace_colskip [0];
+ pData->iRowsamples = (pData->iDatawidth + interlace_roundoff [0]) >> interlace_divider [0];
+ pData->iSamplemul = 1;
+ pData->iSampleofs = 7;
+ pData->iSamplediv = 3;
+ pData->iRowsize = ((pData->iRowsamples + 7) >> 3);
+ pData->iRowmax = ((pData->iDatawidth + 7) >> 3) + pData->iPixelofs;
+ pData->iFilterbpp = 1;
+ pData->bIsRGBA16 = MNG_FALSE; /* intermediate row is 8-bit deep */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_G1_I, MNG_LC_END);
+#endif
+
+ return mng_init_rowproc (pData);
+}
+
+/* ************************************************************************** */
+
+mng_retcode mng_init_g2_ni (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_G2_NI, MNG_LC_START);
+#endif
+
+ if (pData->fDisplayrow)
+ pData->fProcessrow = (mng_fptr)mng_process_g2;
+
+ if (pData->pStoreobj) /* store in object too ? */
+ { /* immediate delta ? */
+#ifndef MNG_NO_DELTA_PNG
+ if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
+ pData->fStorerow = (mng_fptr)mng_delta_g2;
+ else
+#endif
+ pData->fStorerow = (mng_fptr)mng_store_g2;
+ }
+
+#ifdef FILTER192 /* leveling & differing ? */
+ if (pData->iFilter == MNG_FILTER_DIFFERING)
+ pData->fDifferrow = (mng_fptr)mng_differ_g2;
+#endif
+
+ pData->iPass = -1;
+ pData->iRow = 0;
+ pData->iRowinc = 1;
+ pData->iCol = 0;
+ pData->iColinc = 1;
+ pData->iRowsamples = pData->iDatawidth;
+ pData->iSamplemul = 1;
+ pData->iSampleofs = 3;
+ pData->iSamplediv = 2;
+ pData->iRowsize = (pData->iRowsamples + 3) >> 2;
+ pData->iRowmax = pData->iRowsize + pData->iPixelofs;
+ pData->iFilterbpp = 1;
+ pData->bIsRGBA16 = MNG_FALSE; /* intermediate row is 8-bit deep */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_G2_NI, MNG_LC_END);
+#endif
+
+ return mng_init_rowproc (pData);
+}
+
+/* ************************************************************************** */
+
+mng_retcode mng_init_g2_i (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_G2_I, MNG_LC_START);
+#endif
+
+ if (pData->fDisplayrow)
+ pData->fProcessrow = (mng_fptr)mng_process_g2;
+
+ if (pData->pStoreobj) /* store in object too ? */
+ { /* immediate delta ? */
+#ifndef MNG_NO_DELTA_PNG
+ if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
+ pData->fStorerow = (mng_fptr)mng_delta_g2;
+ else
+#endif
+ pData->fStorerow = (mng_fptr)mng_store_g2;
+ }
+
+#ifdef FILTER192 /* leveling & differing ? */
+ if (pData->iFilter == MNG_FILTER_DIFFERING)
+ pData->fDifferrow = (mng_fptr)mng_differ_g2;
+#endif
+
+ pData->iPass = 0; /* from 0..6; is 1..7 in specifications */
+ pData->iRow = interlace_row [0];
+ pData->iRowinc = interlace_rowskip [0];
+ pData->iCol = interlace_col [0];
+ pData->iColinc = interlace_colskip [0];
+ pData->iRowsamples = (pData->iDatawidth + interlace_roundoff [0]) >> interlace_divider [0];
+ pData->iSamplemul = 1;
+ pData->iSampleofs = 3;
+ pData->iSamplediv = 2;
+ pData->iRowsize = ((pData->iRowsamples + 3) >> 2);
+ pData->iRowmax = ((pData->iDatawidth + 3) >> 2) + pData->iPixelofs;
+ pData->iFilterbpp = 1;
+ pData->bIsRGBA16 = MNG_FALSE; /* intermediate row is 8-bit deep */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_G2_I, MNG_LC_END);
+#endif
+
+ return mng_init_rowproc (pData);
+}
+
+/* ************************************************************************** */
+
+mng_retcode mng_init_g4_ni (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_G4_NI, MNG_LC_START);
+#endif
+
+ if (pData->fDisplayrow)
+ pData->fProcessrow = (mng_fptr)mng_process_g4;
+
+ if (pData->pStoreobj) /* store in object too ? */
+ { /* immediate delta ? */
+#ifndef MNG_NO_DELTA_PNG
+ if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
+ pData->fStorerow = (mng_fptr)mng_delta_g4;
+ else
+#endif
+ pData->fStorerow = (mng_fptr)mng_store_g4;
+ }
+
+#ifdef FILTER192 /* leveling & differing ? */
+ if (pData->iFilter == MNG_FILTER_DIFFERING)
+ pData->fDifferrow = (mng_fptr)mng_differ_g4;
+#endif
+
+ pData->iPass = -1;
+ pData->iRow = 0;
+ pData->iRowinc = 1;
+ pData->iCol = 0;
+ pData->iColinc = 1;
+ pData->iRowsamples = pData->iDatawidth;
+ pData->iSamplemul = 1;
+ pData->iSampleofs = 1;
+ pData->iSamplediv = 1;
+ pData->iRowsize = (pData->iRowsamples + 1) >> 1;
+ pData->iRowmax = pData->iRowsize + pData->iPixelofs;
+ pData->iFilterbpp = 1;
+ pData->bIsRGBA16 = MNG_FALSE; /* intermediate row is 8-bit deep */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_G4_NI, MNG_LC_END);
+#endif
+
+ return mng_init_rowproc (pData);
+}
+
+/* ************************************************************************** */
+
+mng_retcode mng_init_g4_i (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_G4_I, MNG_LC_START);
+#endif
+
+ if (pData->fDisplayrow)
+ pData->fProcessrow = (mng_fptr)mng_process_g4;
+
+ if (pData->pStoreobj) /* store in object too ? */
+ { /* immediate delta ? */
+#ifndef MNG_NO_DELTA_PNG
+ if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
+ pData->fStorerow = (mng_fptr)mng_delta_g4;
+ else
+#endif
+ pData->fStorerow = (mng_fptr)mng_store_g4;
+ }
+
+#ifdef FILTER192 /* leveling & differing ? */
+ if (pData->iFilter == MNG_FILTER_DIFFERING)
+ pData->fDifferrow = (mng_fptr)mng_differ_g4;
+#endif
+
+ pData->iPass = 0; /* from 0..6; is 1..7 in specifications */
+ pData->iRow = interlace_row [0];
+ pData->iRowinc = interlace_rowskip [0];
+ pData->iCol = interlace_col [0];
+ pData->iColinc = interlace_colskip [0];
+ pData->iRowsamples = (pData->iDatawidth + interlace_roundoff [0]) >> interlace_divider [0];
+ pData->iSamplemul = 1;
+ pData->iSampleofs = 1;
+ pData->iSamplediv = 1;
+ pData->iRowsize = ((pData->iRowsamples + 1) >> 1);
+ pData->iRowmax = ((pData->iDatawidth + 1) >> 1) + pData->iPixelofs;
+ pData->iFilterbpp = 1;
+ pData->bIsRGBA16 = MNG_FALSE; /* intermediate row is 8-bit deep */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_G4_I, MNG_LC_END);
+#endif
+
+ return mng_init_rowproc (pData);
+}
+#endif /* MNG_NO_1_2_4BIT_SUPPORT */
+
+/* ************************************************************************** */
+
+mng_retcode mng_init_g8_ni (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_G8_NI, MNG_LC_START);
+#endif
+
+ if (pData->fDisplayrow)
+ pData->fProcessrow = (mng_fptr)mng_process_g8;
+
+ if (pData->pStoreobj) /* store in object too ? */
+ { /* immediate delta ? */
+#ifndef MNG_NO_DELTA_PNG
+ if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
+ pData->fStorerow = (mng_fptr)mng_delta_g8;
+ else
+#endif
+ pData->fStorerow = (mng_fptr)mng_store_g8;
+ }
+
+#ifdef FILTER192 /* leveling & differing ? */
+ if (pData->iFilter == MNG_FILTER_DIFFERING)
+ pData->fDifferrow = (mng_fptr)mng_differ_g8;
+#endif
+
+ pData->iPass = -1;
+ pData->iRow = 0;
+ pData->iRowinc = 1;
+ pData->iCol = 0;
+ pData->iColinc = 1;
+ pData->iRowsamples = pData->iDatawidth;
+ pData->iSamplemul = 1;
+ pData->iSampleofs = 0;
+ pData->iSamplediv = 0;
+ pData->iRowsize = pData->iRowsamples;
+ pData->iRowmax = pData->iRowsize + pData->iPixelofs;
+ pData->iFilterbpp = 1;
+ pData->bIsRGBA16 = MNG_FALSE; /* intermediate row is 8-bit deep */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_G8_NI, MNG_LC_END);
+#endif
+
+ return mng_init_rowproc (pData);
+}
+
+/* ************************************************************************** */
+
+mng_retcode mng_init_g8_i (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_G8_I, MNG_LC_START);
+#endif
+
+ if (pData->fDisplayrow)
+ pData->fProcessrow = (mng_fptr)mng_process_g8;
+
+ if (pData->pStoreobj) /* store in object too ? */
+ { /* immediate delta ? */
+#ifndef MNG_NO_DELTA_PNG
+ if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
+ pData->fStorerow = (mng_fptr)mng_delta_g8;
+ else
+#endif
+ pData->fStorerow = (mng_fptr)mng_store_g8;
+ }
+
+#ifdef FILTER192 /* leveling & differing ? */
+ if (pData->iFilter == MNG_FILTER_DIFFERING)
+ pData->fDifferrow = (mng_fptr)mng_differ_g8;
+#endif
+
+ pData->iPass = 0; /* from 0..6; is 1..7 in specifications */
+ pData->iRow = interlace_row [0];
+ pData->iRowinc = interlace_rowskip [0];
+ pData->iCol = interlace_col [0];
+ pData->iColinc = interlace_colskip [0];
+ pData->iRowsamples = (pData->iDatawidth + interlace_roundoff [0]) >> interlace_divider [0];
+ pData->iSamplemul = 1;
+ pData->iSampleofs = 0;
+ pData->iSamplediv = 0;
+ pData->iRowsize = pData->iRowsamples;
+ pData->iRowmax = pData->iDatawidth + pData->iPixelofs;
+ pData->iFilterbpp = 1;
+ pData->bIsRGBA16 = MNG_FALSE; /* intermediate row is 8-bit deep */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_G8_I, MNG_LC_END);
+#endif
+
+ return mng_init_rowproc (pData);
+}
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_16BIT_SUPPORT
+mng_retcode mng_init_g16_ni (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_G16_NI, MNG_LC_START);
+#endif
+
+ if (pData->fDisplayrow)
+ pData->fProcessrow = (mng_fptr)mng_process_g16;
+
+ if (pData->pStoreobj) /* store in object too ? */
+ { /* immediate delta ? */
+#ifndef MNG_NO_DELTA_PNG
+ if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
+ pData->fStorerow = (mng_fptr)mng_delta_g16;
+ else
+#endif
+ pData->fStorerow = (mng_fptr)mng_store_g16;
+ }
+
+#ifdef FILTER192 /* leveling & differing ? */
+ if (pData->iFilter == MNG_FILTER_DIFFERING)
+ pData->fDifferrow = (mng_fptr)mng_differ_g16;
+#endif
+
+ pData->iPass = -1;
+ pData->iRow = 0;
+ pData->iRowinc = 1;
+ pData->iCol = 0;
+ pData->iColinc = 1;
+ pData->iRowsamples = pData->iDatawidth;
+ pData->iSamplemul = 2;
+ pData->iSampleofs = 0;
+ pData->iSamplediv = 0;
+ pData->iRowsize = pData->iRowsamples << 1;
+ pData->iRowmax = pData->iRowsize + pData->iPixelofs;
+ pData->iFilterbpp = 2;
+ pData->bIsRGBA16 = MNG_TRUE; /* intermediate row is 16-bit deep */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_G16_NI, MNG_LC_END);
+#endif
+
+ return mng_init_rowproc (pData);
+}
+#endif
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_16BIT_SUPPORT
+mng_retcode mng_init_g16_i (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_G16_I, MNG_LC_START);
+#endif
+
+ if (pData->fDisplayrow)
+ pData->fProcessrow = (mng_fptr)mng_process_g16;
+
+ if (pData->pStoreobj) /* store in object too ? */
+ { /* immediate delta ? */
+#ifndef MNG_NO_DELTA_PNG
+ if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
+ pData->fStorerow = (mng_fptr)mng_delta_g16;
+ else
+#endif
+ pData->fStorerow = (mng_fptr)mng_store_g16;
+ }
+
+#ifdef FILTER192 /* leveling & differing ? */
+ if (pData->iFilter == MNG_FILTER_DIFFERING)
+ pData->fDifferrow = (mng_fptr)mng_differ_g16;
+#endif
+
+ pData->iPass = 0; /* from 0..6; is 1..7 in specifications */
+ pData->iRow = interlace_row [0];
+ pData->iRowinc = interlace_rowskip [0];
+ pData->iCol = interlace_col [0];
+ pData->iColinc = interlace_colskip [0];
+ pData->iRowsamples = (pData->iDatawidth + interlace_roundoff [0]) >> interlace_divider [0];
+ pData->iSamplemul = 2;
+ pData->iSampleofs = 0;
+ pData->iSamplediv = 0;
+ pData->iRowsize = pData->iRowsamples << 1;
+ pData->iRowmax = (pData->iDatawidth << 1) + pData->iPixelofs;
+ pData->iFilterbpp = 2;
+ pData->bIsRGBA16 = MNG_TRUE; /* intermediate row is 16-bit deep */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_G16_I, MNG_LC_END);
+#endif
+
+ return mng_init_rowproc (pData);
+}
+#endif
+
+/* ************************************************************************** */
+
+mng_retcode mng_init_rgb8_ni (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_RGB8_NI, MNG_LC_START);
+#endif
+
+ if (pData->fDisplayrow)
+ pData->fProcessrow = (mng_fptr)mng_process_rgb8;
+
+ if (pData->pStoreobj) /* store in object too ? */
+ { /* immediate delta ? */
+#ifndef MNG_NO_DELTA_PNG
+ if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
+ pData->fStorerow = (mng_fptr)mng_delta_rgb8;
+ else
+#endif
+ pData->fStorerow = (mng_fptr)mng_store_rgb8;
+ }
+
+#ifdef FILTER192 /* leveling & differing ? */
+ if (pData->iFilter == MNG_FILTER_DIFFERING)
+ pData->fDifferrow = (mng_fptr)mng_differ_rgb8;
+#endif
+
+ pData->iPass = -1;
+ pData->iRow = 0;
+ pData->iRowinc = 1;
+ pData->iCol = 0;
+ pData->iColinc = 1;
+ pData->iRowsamples = pData->iDatawidth;
+ pData->iSamplemul = 3;
+ pData->iSampleofs = 0;
+ pData->iSamplediv = 0;
+ pData->iRowsize = pData->iRowsamples * 3;
+ pData->iRowmax = pData->iRowsize + pData->iPixelofs;
+ pData->iFilterbpp = 3;
+ pData->bIsRGBA16 = MNG_FALSE; /* intermediate row is 8-bit deep */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_RGB8_NI, MNG_LC_END);
+#endif
+
+ return mng_init_rowproc (pData);
+}
+
+/* ************************************************************************** */
+
+mng_retcode mng_init_rgb8_i (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_RGB8_I, MNG_LC_START);
+#endif
+
+ if (pData->fDisplayrow)
+ pData->fProcessrow = (mng_fptr)mng_process_rgb8;
+
+ if (pData->pStoreobj) /* store in object too ? */
+ { /* immediate delta ? */
+#ifndef MNG_NO_DELTA_PNG
+ if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
+ pData->fStorerow = (mng_fptr)mng_delta_rgb8;
+ else
+#endif
+ pData->fStorerow = (mng_fptr)mng_store_rgb8;
+ }
+
+#ifdef FILTER192 /* leveling & differing ? */
+ if (pData->iFilter == MNG_FILTER_DIFFERING)
+ pData->fDifferrow = (mng_fptr)mng_differ_rgb8;
+#endif
+
+ pData->iPass = 0; /* from 0..6; is 1..7 in specifications */
+ pData->iRow = interlace_row [0];
+ pData->iRowinc = interlace_rowskip [0];
+ pData->iCol = interlace_col [0];
+ pData->iColinc = interlace_colskip [0];
+ pData->iRowsamples = (pData->iDatawidth + interlace_roundoff [0]) >> interlace_divider [0];
+ pData->iSamplemul = 3;
+ pData->iSampleofs = 0;
+ pData->iSamplediv = 0;
+ pData->iRowsize = pData->iRowsamples * 3;
+ pData->iRowmax = (pData->iDatawidth * 3) + pData->iPixelofs;
+ pData->iFilterbpp = 3;
+ pData->bIsRGBA16 = MNG_FALSE; /* intermediate row is 8-bit deep */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_RGB8_I, MNG_LC_END);
+#endif
+
+ return mng_init_rowproc (pData);
+}
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_16BIT_SUPPORT
+mng_retcode mng_init_rgb16_ni (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_RGB16_NI, MNG_LC_START);
+#endif
+
+ if (pData->fDisplayrow)
+ pData->fProcessrow = (mng_fptr)mng_process_rgb16;
+
+ if (pData->pStoreobj) /* store in object too ? */
+ { /* immediate delta ? */
+#ifndef MNG_NO_DELTA_PNG
+ if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
+ pData->fStorerow = (mng_fptr)mng_delta_rgb16;
+ else
+#endif
+ pData->fStorerow = (mng_fptr)mng_store_rgb16;
+ }
+
+#ifdef FILTER192 /* leveling & differing ? */
+ if (pData->iFilter == MNG_FILTER_DIFFERING)
+ pData->fDifferrow = (mng_fptr)mng_differ_rgb16;
+#endif
+
+ pData->iPass = -1;
+ pData->iRow = 0;
+ pData->iRowinc = 1;
+ pData->iCol = 0;
+ pData->iColinc = 1;
+ pData->iRowsamples = pData->iDatawidth;
+ pData->iSamplemul = 6;
+ pData->iSampleofs = 0;
+ pData->iSamplediv = 0;
+ pData->iRowsize = pData->iRowsamples * 6;
+ pData->iRowmax = pData->iRowsize + pData->iPixelofs;
+ pData->iFilterbpp = 6;
+ pData->bIsRGBA16 = MNG_TRUE; /* intermediate row is 16-bit deep */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_RGB16_NI, MNG_LC_END);
+#endif
+
+ return mng_init_rowproc (pData);
+}
+#endif
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_16BIT_SUPPORT
+mng_retcode mng_init_rgb16_i (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_RGB16_I, MNG_LC_START);
+#endif
+
+ if (pData->fDisplayrow)
+ pData->fProcessrow = (mng_fptr)mng_process_rgb16;
+
+ if (pData->pStoreobj) /* store in object too ? */
+ { /* immediate delta ? */
+#ifndef MNG_NO_DELTA_PNG
+ if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
+ pData->fStorerow = (mng_fptr)mng_delta_rgb16;
+ else
+#endif
+ pData->fStorerow = (mng_fptr)mng_store_rgb16;
+ }
+
+#ifdef FILTER192 /* leveling & differing ? */
+ if (pData->iFilter == MNG_FILTER_DIFFERING)
+ pData->fDifferrow = (mng_fptr)mng_differ_rgb16;
+#endif
+
+ pData->iPass = 0; /* from 0..6; is 1..7 in specifications */
+ pData->iRow = interlace_row [0];
+ pData->iRowinc = interlace_rowskip [0];
+ pData->iCol = interlace_col [0];
+ pData->iColinc = interlace_colskip [0];
+ pData->iRowsamples = (pData->iDatawidth + interlace_roundoff [0]) >> interlace_divider [0];
+ pData->iSamplemul = 6;
+ pData->iSampleofs = 0;
+ pData->iSamplediv = 0;
+ pData->iRowsize = pData->iRowsamples * 6;
+ pData->iRowmax = (pData->iDatawidth * 6) + pData->iPixelofs;
+ pData->iFilterbpp = 6;
+ pData->bIsRGBA16 = MNG_TRUE; /* intermediate row is 16-bit deep */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_RGB16_I, MNG_LC_END);
+#endif
+
+ return mng_init_rowproc (pData);
+}
+#endif
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_1_2_4BIT_SUPPORT
+mng_retcode mng_init_idx1_ni (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_IDX1_NI, MNG_LC_START);
+#endif
+
+ if (pData->fDisplayrow)
+ pData->fProcessrow = (mng_fptr)mng_process_idx1;
+
+ if (pData->pStoreobj) /* store in object too ? */
+ { /* immediate delta ? */
+#ifndef MNG_NO_DELTA_PNG
+ if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
+ pData->fStorerow = (mng_fptr)mng_delta_idx1;
+ else
+#endif
+ pData->fStorerow = (mng_fptr)mng_store_idx1;
+ }
+
+#ifdef FILTER192 /* leveling & differing ? */
+ if (pData->iFilter == MNG_FILTER_DIFFERING)
+ pData->fDifferrow = (mng_fptr)mng_differ_idx1;
+#endif
+
+ pData->iPass = -1;
+ pData->iRow = 0;
+ pData->iRowinc = 1;
+ pData->iCol = 0;
+ pData->iColinc = 1;
+ pData->iRowsamples = pData->iDatawidth;
+ pData->iSamplemul = 1;
+ pData->iSampleofs = 7;
+ pData->iSamplediv = 3;
+ pData->iRowsize = (pData->iRowsamples + 7) >> 3;
+ pData->iRowmax = pData->iRowsize + pData->iPixelofs;
+ pData->iFilterbpp = 1;
+ pData->bIsRGBA16 = MNG_FALSE; /* intermediate row is 8-bit deep */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_IDX1_NI, MNG_LC_END);
+#endif
+
+ return mng_init_rowproc (pData);
+}
+
+/* ************************************************************************** */
+
+mng_retcode mng_init_idx1_i (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_IDX1_I, MNG_LC_START);
+#endif
+
+ if (pData->fDisplayrow)
+ pData->fProcessrow = (mng_fptr)mng_process_idx1;
+
+ if (pData->pStoreobj) /* store in object too ? */
+ { /* immediate delta ? */
+#ifndef MNG_NO_DELTA_PNG
+ if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
+ pData->fStorerow = (mng_fptr)mng_delta_idx1;
+ else
+#endif
+ pData->fStorerow = (mng_fptr)mng_store_idx1;
+ }
+
+#ifdef FILTER192 /* leveling & differing ? */
+ if (pData->iFilter == MNG_FILTER_DIFFERING)
+ pData->fDifferrow = (mng_fptr)mng_differ_idx1;
+#endif
+
+ pData->iPass = 0; /* from 0..6; is 1..7 in specifications */
+ pData->iRow = interlace_row [0];
+ pData->iRowinc = interlace_rowskip [0];
+ pData->iCol = interlace_col [0];
+ pData->iColinc = interlace_colskip [0];
+ pData->iRowsamples = (pData->iDatawidth + interlace_roundoff [0]) >> interlace_divider [0];
+ pData->iSamplemul = 1;
+ pData->iSampleofs = 7;
+ pData->iSamplediv = 3;
+ pData->iRowsize = (pData->iRowsamples + 7) >> 3;
+ pData->iRowmax = ((pData->iDatawidth + 7) >> 3) + pData->iPixelofs;
+ pData->iFilterbpp = 1;
+ pData->bIsRGBA16 = MNG_FALSE; /* intermediate row is 8-bit deep */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_IDX1_I, MNG_LC_END);
+#endif
+
+ return mng_init_rowproc (pData);
+}
+
+/* ************************************************************************** */
+
+mng_retcode mng_init_idx2_ni (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_IDX2_NI, MNG_LC_START);
+#endif
+
+ if (pData->fDisplayrow)
+ pData->fProcessrow = (mng_fptr)mng_process_idx2;
+
+ if (pData->pStoreobj) /* store in object too ? */
+ { /* immediate delta ? */
+#ifndef MNG_NO_DELTA_PNG
+ if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
+ pData->fStorerow = (mng_fptr)mng_delta_idx2;
+ else
+#endif
+ pData->fStorerow = (mng_fptr)mng_store_idx2;
+ }
+
+#ifdef FILTER192 /* leveling & differing ? */
+ if (pData->iFilter == MNG_FILTER_DIFFERING)
+ pData->fDifferrow = (mng_fptr)mng_differ_idx2;
+#endif
+
+ pData->iPass = -1;
+ pData->iRow = 0;
+ pData->iRowinc = 1;
+ pData->iCol = 0;
+ pData->iColinc = 1;
+ pData->iRowsamples = pData->iDatawidth;
+ pData->iSamplemul = 1;
+ pData->iSampleofs = 3;
+ pData->iSamplediv = 2;
+ pData->iRowsize = (pData->iRowsamples + 3) >> 2;
+ pData->iRowmax = pData->iRowsize + pData->iPixelofs;
+ pData->iFilterbpp = 1;
+ pData->bIsRGBA16 = MNG_FALSE; /* intermediate row is 8-bit deep */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_IDX2_NI, MNG_LC_END);
+#endif
+
+ return mng_init_rowproc (pData);
+}
+
+/* ************************************************************************** */
+
+mng_retcode mng_init_idx2_i (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_IDX2_I, MNG_LC_START);
+#endif
+
+ if (pData->fDisplayrow)
+ pData->fProcessrow = (mng_fptr)mng_process_idx2;
+
+ if (pData->pStoreobj) /* store in object too ? */
+ { /* immediate delta ? */
+#ifndef MNG_NO_DELTA_PNG
+ if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
+ pData->fStorerow = (mng_fptr)mng_delta_idx2;
+ else
+#endif
+ pData->fStorerow = (mng_fptr)mng_store_idx2;
+ }
+
+#ifdef FILTER192 /* leveling & differing ? */
+ if (pData->iFilter == MNG_FILTER_DIFFERING)
+ pData->fDifferrow = (mng_fptr)mng_differ_idx2;
+#endif
+
+ pData->iPass = 0; /* from 0..6; is 1..7 in specifications */
+ pData->iRow = interlace_row [0];
+ pData->iRowinc = interlace_rowskip [0];
+ pData->iCol = interlace_col [0];
+ pData->iColinc = interlace_colskip [0];
+ pData->iRowsamples = (pData->iDatawidth + interlace_roundoff [0]) >> interlace_divider [0];
+ pData->iSamplemul = 1;
+ pData->iSampleofs = 3;