📄 libmng_pixels.c
字号:
/* ************************************************************************** *//* * For conditions of distribution and use, * *//* * see copyright notice in libmng.h * *//* ************************************************************************** *//* * * *//* * project : libmng * *//* * file : libmng_pixels.c copyright (c) 2000 G.Juyn * *//* * version : 1.0.4 * *//* * * *//* * purpose : Pixel-row management routines (implementation) * *//* * * *//* * author : G.Juyn * *//* * web : http://www.3-t.com * *//* * email : mailto:info@3-t.com * *//* * * *//* * 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 * *//* * * *//* ************************************************************************** */#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_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_uint32 const interlace_row [7] = { 0, 0, 4, 0, 2, 0, 1 };mng_uint32 const interlace_rowskip [7] = { 8, 8, 8, 4, 4, 2, 2 };mng_uint32 const interlace_col [7] = { 0, 4, 0, 2, 0, 1, 0 };mng_uint32 const interlace_colskip [7] = { 8, 8, 4, 4, 2, 2, 1 };mng_uint32 const interlace_roundoff [7] = { 7, 7, 3, 3, 1, 1, 0 };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)65525 - \ ((((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 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 * *//* * * *//* ************************************************************************** */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;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -