⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sdl_blit_a.c

📁 网络MPEG4IP流媒体开发源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*    SDL - Simple DirectMedia Layer    Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002  Sam Lantinga    This library is free software; you can redistribute it and/or    modify it under the terms of the GNU Library General Public    License as published by the Free Software Foundation; either    version 2 of the License, or (at your option) any later version.    This library is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU    Library General Public License for more details.    You should have received a copy of the GNU Library General Public    License along with this library; if not, write to the Free    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA    Sam Lantinga    slouken@libsdl.org*/#ifdef SAVE_RCSIDstatic char rcsid = "@(#) $Id$";#endif#include <stdio.h>#include "SDL_types.h"#include "SDL_video.h"#include "SDL_blit.h"/* Functions to perform alpha blended blitting *//* N->1 blending with per-surface alpha */static void BlitNto1SurfaceAlpha(SDL_BlitInfo *info){	int width = info->d_width;	int height = info->d_height;	Uint8 *src = info->s_pixels;	int srcskip = info->s_skip;	Uint8 *dst = info->d_pixels;	int dstskip = info->d_skip;	Uint8 *palmap = info->table;	SDL_PixelFormat *srcfmt = info->src;	SDL_PixelFormat *dstfmt = info->dst;	int srcbpp = srcfmt->BytesPerPixel;	const unsigned A = srcfmt->alpha;	while ( height-- ) {	    DUFFS_LOOP4(	    {		Uint32 pixel;		unsigned sR;		unsigned sG;		unsigned sB;		unsigned dR;		unsigned dG;		unsigned dB;		DISEMBLE_RGB(src, srcbpp, srcfmt, pixel, sR, sG, sB);		dR = dstfmt->palette->colors[*dst].r;		dG = dstfmt->palette->colors[*dst].g;		dB = dstfmt->palette->colors[*dst].b;		ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB);		dR &= 0xff;		dG &= 0xff;		dB &= 0xff;		/* Pack RGB into 8bit pixel */		if ( palmap == NULL ) {		    *dst =((dR>>5)<<(3+2))|			  ((dG>>5)<<(2))|			  ((dB>>6)<<(0));		} else {		    *dst = palmap[((dR>>5)<<(3+2))|				  ((dG>>5)<<(2))  |				  ((dB>>6)<<(0))];		}		dst++;		src += srcbpp;	    },	    width);	    src += srcskip;	    dst += dstskip;	}}/* N->1 blending with pixel alpha */static void BlitNto1PixelAlpha(SDL_BlitInfo *info){	int width = info->d_width;	int height = info->d_height;	Uint8 *src = info->s_pixels;	int srcskip = info->s_skip;	Uint8 *dst = info->d_pixels;	int dstskip = info->d_skip;	Uint8 *palmap = info->table;	SDL_PixelFormat *srcfmt = info->src;	SDL_PixelFormat *dstfmt = info->dst;	int srcbpp = srcfmt->BytesPerPixel;	/* FIXME: fix alpha bit field expansion here too? */	while ( height-- ) {	    DUFFS_LOOP4(	    {		Uint32 pixel;		unsigned sR;		unsigned sG;		unsigned sB;		unsigned sA;		unsigned dR;		unsigned dG;		unsigned dB;		DISEMBLE_RGBA(src,srcbpp,srcfmt,pixel,sR,sG,sB,sA);		dR = dstfmt->palette->colors[*dst].r;		dG = dstfmt->palette->colors[*dst].g;		dB = dstfmt->palette->colors[*dst].b;		ALPHA_BLEND(sR, sG, sB, sA, dR, dG, dB);		dR &= 0xff;		dG &= 0xff;		dB &= 0xff;		/* Pack RGB into 8bit pixel */		if ( palmap == NULL ) {		    *dst =((dR>>5)<<(3+2))|			  ((dG>>5)<<(2))|			  ((dB>>6)<<(0));		} else {		    *dst = palmap[((dR>>5)<<(3+2))|				  ((dG>>5)<<(2))  |				  ((dB>>6)<<(0))  ];		}		dst++;		src += srcbpp;	    },	    width);	    src += srcskip;	    dst += dstskip;	}}/* colorkeyed N->1 blending with per-surface alpha */static void BlitNto1SurfaceAlphaKey(SDL_BlitInfo *info){	int width = info->d_width;	int height = info->d_height;	Uint8 *src = info->s_pixels;	int srcskip = info->s_skip;	Uint8 *dst = info->d_pixels;	int dstskip = info->d_skip;	Uint8 *palmap = info->table;	SDL_PixelFormat *srcfmt = info->src;	SDL_PixelFormat *dstfmt = info->dst;	int srcbpp = srcfmt->BytesPerPixel;	Uint32 ckey = srcfmt->colorkey;	const int A = srcfmt->alpha;	while ( height-- ) {	    DUFFS_LOOP(	    {		Uint32 pixel;		unsigned sR;		unsigned sG;		unsigned sB;		unsigned dR;		unsigned dG;		unsigned dB;		DISEMBLE_RGB(src, srcbpp, srcfmt, pixel, sR, sG, sB);		if ( pixel != ckey ) {		    dR = dstfmt->palette->colors[*dst].r;		    dG = dstfmt->palette->colors[*dst].g;		    dB = dstfmt->palette->colors[*dst].b;		    ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB);		    dR &= 0xff;		    dG &= 0xff;		    dB &= 0xff;		    /* Pack RGB into 8bit pixel */		    if ( palmap == NULL ) {			*dst =((dR>>5)<<(3+2))|			      ((dG>>5)<<(2)) |			      ((dB>>6)<<(0));		    } else {			*dst = palmap[((dR>>5)<<(3+2))|				      ((dG>>5)<<(2))  |				      ((dB>>6)<<(0))  ];		    }		}		dst++;		src += srcbpp;	    },	    width);	    src += srcskip;	    dst += dstskip;	}}/* fast RGB888->(A)RGB888 blending with surface alpha=128 special case */static void BlitRGBtoRGBSurfaceAlpha128(SDL_BlitInfo *info){	int width = info->d_width;	int height = info->d_height;	Uint32 *srcp = (Uint32 *)info->s_pixels;	int srcskip = info->s_skip >> 2;	Uint32 *dstp = (Uint32 *)info->d_pixels;	int dstskip = info->d_skip >> 2;	while(height--) {	    DUFFS_LOOP4({		    Uint32 s = *srcp++;		    Uint32 d = *dstp;		    *dstp++ = ((((s & 0x00fefefe) + (d & 0x00fefefe)) >> 1)			       + (s & d & 0x00010101)) | 0xff000000;	    }, width);	    srcp += srcskip;	    dstp += dstskip;	}}/* fast RGB888->(A)RGB888 blending with surface alpha */static void BlitRGBtoRGBSurfaceAlpha(SDL_BlitInfo *info){	unsigned alpha = info->src->alpha;	if(alpha == 128) {		BlitRGBtoRGBSurfaceAlpha128(info);	} else {		int width = info->d_width;		int height = info->d_height;		Uint32 *srcp = (Uint32 *)info->s_pixels;		int srcskip = info->s_skip >> 2;		Uint32 *dstp = (Uint32 *)info->d_pixels;		int dstskip = info->d_skip >> 2;		while(height--) {			DUFFS_LOOP4({				Uint32 s;				Uint32 d;				Uint32 s1;				Uint32 d1;				s = *srcp;				d = *dstp;				s1 = s & 0xff00ff;				d1 = d & 0xff00ff;				d1 = (d1 + ((s1 - d1) * alpha >> 8))				     & 0xff00ff;				s &= 0xff00;				d &= 0xff00;				d = (d + ((s - d) * alpha >> 8)) & 0xff00;				*dstp = d1 | d | 0xff000000;				++srcp;				++dstp;			}, width);			srcp += srcskip;			dstp += dstskip;		}	}}/* fast ARGB888->(A)RGB888 blending with pixel alpha */static void BlitRGBtoRGBPixelAlpha(SDL_BlitInfo *info){	int width = info->d_width;	int height = info->d_height;	Uint32 *srcp = (Uint32 *)info->s_pixels;	int srcskip = info->s_skip >> 2;	Uint32 *dstp = (Uint32 *)info->d_pixels;	int dstskip = info->d_skip >> 2;	while(height--) {	    DUFFS_LOOP4({		Uint32 dalpha;		Uint32 d;		Uint32 s1;		Uint32 d1;		Uint32 s = *srcp;		Uint32 alpha = s >> 24;		/* FIXME: Here we special-case opaque alpha since the		   compositioning used (>>8 instead of /255) doesn't handle		   it correctly. Also special-case alpha=0 for speed?		   Benchmark this! */		if(alpha == SDL_ALPHA_OPAQUE) {		    *dstp = (s & 0x00ffffff) | (*dstp & 0xff000000);		} else {		    /*		     * take out the middle component (green), and process		     * the other two in parallel. One multiply less.		     */		    d = *dstp;		    dalpha = d & 0xff000000;		    s1 = s & 0xff00ff;		    d1 = d & 0xff00ff;		    d1 = (d1 + ((s1 - d1) * alpha >> 8)) & 0xff00ff;		    s &= 0xff00;		    d &= 0xff00;		    d = (d + ((s - d) * alpha >> 8)) & 0xff00;		    *dstp = d1 | d | dalpha;		}		++srcp;		++dstp;	    }, width);	    srcp += srcskip;	    dstp += dstskip;	}}/* 16bpp special case for per-surface alpha=50%: blend 2 pixels in parallel *//* blend a single 16 bit pixel at 50% */#define BLEND16_50(d, s, mask)						\	((((s & mask) + (d & mask)) >> 1) + (s & d & (~mask & 0xffff)))/* blend two 16 bit pixels at 50% */#define BLEND2x16_50(d, s, mask)					     \	(((s & (mask | mask << 16)) >> 1) + ((d & (mask | mask << 16)) >> 1) \	 + (s & d & (~(mask | mask << 16))))static void Blit16to16SurfaceAlpha128(SDL_BlitInfo *info, Uint16 mask){	int width = info->d_width;	int height = info->d_height;	Uint16 *srcp = (Uint16 *)info->s_pixels;	int srcskip = info->s_skip >> 1;	Uint16 *dstp = (Uint16 *)info->d_pixels;	int dstskip = info->d_skip >> 1;	while(height--) {		if(((unsigned long)srcp ^ (unsigned long)dstp) & 2) {			/*			 * Source and destination not aligned, pipeline it.			 * This is mostly a win for big blits but no loss for			 * small ones			 */			Uint32 prev_sw;			int w = width;			/* handle odd destination */			if((unsigned long)dstp & 2) {				Uint16 d = *dstp, s = *srcp;				*dstp = BLEND16_50(d, s, mask);				dstp++;				srcp++;				w--;			}			srcp++;	/* srcp is now 32-bit aligned */			/* bootstrap pipeline with first halfword */			prev_sw = ((Uint32 *)srcp)[-1];			while(w > 1) {				Uint32 sw, dw, s;				sw = *(Uint32 *)srcp;				dw = *(Uint32 *)dstp;				if(SDL_BYTEORDER == SDL_BIG_ENDIAN)					s = (prev_sw << 16) + (sw >> 16);				else					s = (prev_sw >> 16) + (sw << 16);				prev_sw = sw;				*(Uint32 *)dstp = BLEND2x16_50(dw, s, mask);				dstp += 2;				srcp += 2;				w -= 2;			}			/* final pixel if any */			if(w) {				Uint16 d = *dstp, s;				if(SDL_BYTEORDER == SDL_BIG_ENDIAN)					s = prev_sw;				else					s = prev_sw >> 16;				*dstp = BLEND16_50(d, s, mask);				srcp++;				dstp++;			}			srcp += srcskip - 1;			dstp += dstskip;		} else {			/* source and destination are aligned */			int w = width;			/* first odd pixel? */			if((unsigned long)srcp & 2) {				Uint16 d = *dstp, s = *srcp;				*dstp = BLEND16_50(d, s, mask);				srcp++;				dstp++;				w--;			}			/* srcp and dstp are now 32-bit aligned */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -