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

📄 sdl_blit_n.c

📁 MPEG-4编解码的实现(包括MPEG4视音频编解码)
💻 C
📖 第 1 页 / 共 4 页
字号:
		{
		        Uint32 pixel;
			unsigned sR;
			unsigned sG;
			unsigned sB;
			DISEMBLE_RGB(src, srcbpp, srcfmt, pixel, sR, sG, sB);
			ASSEMBLE_RGBA(dst, dstbpp, dstfmt, sR, sG, sB, alpha);
			dst += dstbpp;
			src += srcbpp;
		},
		width);
		src += srcskip;
		dst += dstskip;
	}
}

static void BlitNtoNCopyAlpha(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;
	SDL_PixelFormat *srcfmt = info->src;
	int srcbpp = srcfmt->BytesPerPixel;
	SDL_PixelFormat *dstfmt = info->dst;
	int dstbpp = dstfmt->BytesPerPixel;
	int c;

	/* FIXME: should map alpha to [0..255] correctly! */
	while ( height-- ) {
		for ( c=width; c; --c ) {
		        Uint32 pixel;
			unsigned sR, sG, sB, sA;
			DISEMBLE_RGBA(src, srcbpp, srcfmt, pixel,
				      sR, sG, sB, sA);
			ASSEMBLE_RGBA(dst, dstbpp, dstfmt,
				      sR, sG, sB, sA);
			dst += dstbpp;
			src += srcbpp;
		}
		src += srcskip;
		dst += dstskip;
	}
}

static void BlitNto1Key(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;
	SDL_PixelFormat *srcfmt = info->src;
	const Uint8 *palmap = info->table;
	Uint32 ckey = srcfmt->colorkey;
	Uint32 rgbmask = ~srcfmt->Amask;
	int srcbpp;
	Uint32 pixel;
	Uint8  sR, sG, sB;

	/* Set up some basic variables */
	srcbpp = srcfmt->BytesPerPixel;
	ckey &= rgbmask;

	if ( palmap == NULL ) {
		while ( height-- ) {
			DUFFS_LOOP(
			{
				DISEMBLE_RGB(src, srcbpp, srcfmt, pixel,
								sR, sG, sB);
				if ( (pixel & rgbmask) != ckey ) {
				  	/* Pack RGB into 8bit pixel */
				  	*dst = ((sR>>5)<<(3+2))|
						((sG>>5)<<(2)) |
						((sB>>6)<<(0)) ;
				}
				dst++;
				src += srcbpp;
			},
			width);
			src += srcskip;
			dst += dstskip;
		}
	} else {
		while ( height-- ) {
			DUFFS_LOOP(
			{
				DISEMBLE_RGB(src, srcbpp, srcfmt, pixel,
								sR, sG, sB);
				if ( (pixel & rgbmask) != ckey ) {
				  	/* Pack RGB into 8bit pixel */
				  	*dst = palmap[((sR>>5)<<(3+2))|
							((sG>>5)<<(2))  |
							((sB>>6)<<(0))  ];
				}
				dst++;
				src += srcbpp;
			},
			width);
			src += srcskip;
			dst += dstskip;
		}
	}
}

static void Blit2to2Key(SDL_BlitInfo *info)
{
	int width = info->d_width;
	int height = info->d_height;
	Uint16 *srcp = (Uint16 *)info->s_pixels;
	int srcskip = info->s_skip;
	Uint16 *dstp = (Uint16 *)info->d_pixels;
	int dstskip = info->d_skip;
	Uint32 ckey = info->src->colorkey;
	Uint32 rgbmask = ~info->src->Amask;

	/* Set up some basic variables */
        srcskip /= 2;
        dstskip /= 2;
	ckey &= rgbmask;

	while ( height-- ) {
		DUFFS_LOOP(
		{
			if ( (*srcp & rgbmask) != ckey ) {
				*dstp = *srcp;
			}
			dstp++;
			srcp++;
		},
		width);
		srcp += srcskip;
		dstp += dstskip;
	}
}

static void BlitNtoNKey(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;
	Uint32 ckey = info->src->colorkey;
	SDL_PixelFormat *srcfmt = info->src;
	SDL_PixelFormat *dstfmt = info->dst;
	int srcbpp = srcfmt->BytesPerPixel;
	int dstbpp = dstfmt->BytesPerPixel;
	unsigned alpha = dstfmt->Amask ? SDL_ALPHA_OPAQUE : 0;

	while ( height-- ) {
		DUFFS_LOOP(
		{
		        Uint32 pixel;
			unsigned sR;
			unsigned sG;
			unsigned sB;
			RETRIEVE_RGB_PIXEL(src, srcbpp, pixel);
			if ( pixel != ckey ) {
			        RGB_FROM_PIXEL(pixel, srcfmt, sR, sG, sB);
				ASSEMBLE_RGBA(dst, dstbpp, dstfmt,
					      sR, sG, sB, alpha);
			}
			dst += dstbpp;
			src += srcbpp;
		},
		width);
		src += srcskip;
		dst += dstskip;
	}
}

static void BlitNtoNKeyCopyAlpha(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;
	Uint32 ckey = info->src->colorkey;
	SDL_PixelFormat *srcfmt = info->src;
	SDL_PixelFormat *dstfmt = info->dst;
	Uint32 rgbmask = ~srcfmt->Amask;

	Uint8 srcbpp;
	Uint8 dstbpp;
	Uint32 pixel;
	Uint8  sR, sG, sB, sA;

	/* Set up some basic variables */
	srcbpp = srcfmt->BytesPerPixel;
	dstbpp = dstfmt->BytesPerPixel;
	ckey &= rgbmask;

	/* FIXME: should map alpha to [0..255] correctly! */
	while ( height-- ) {
		DUFFS_LOOP(
		{
			DISEMBLE_RGBA(src, srcbpp, srcfmt, pixel,
				      sR, sG, sB, sA);
			if ( (pixel & rgbmask) != ckey ) {
				  ASSEMBLE_RGBA(dst, dstbpp, dstfmt,
						sR, sG, sB, sA);
			}
			dst += dstbpp;
			src += srcbpp;
		},
		width);
		src += srcskip;
		dst += dstskip;
	}
}

/* Normal N to N optimized blitters */
struct blit_table {
	Uint32 srcR, srcG, srcB;
	int dstbpp;
	Uint32 dstR, dstG, dstB;
	Uint32 cpu_flags;
	void *aux_data;
	SDL_loblit blitfunc;
        enum { NO_ALPHA, SET_ALPHA, COPY_ALPHA } alpha;
};
static const struct blit_table normal_blit_1[] = {
	/* Default for 8-bit RGB source, an invalid combination */
	{ 0,0,0, 0, 0,0,0, 0, NULL, NULL },
};
static const struct blit_table normal_blit_2[] = {
#ifdef USE_ASMBLIT
    { 0x0000F800,0x000007E0,0x0000001F, 2, 0x0000001F,0x000007E0,0x0000F800,
      0, ConvertX86p16_16BGR565, ConvertX86, NO_ALPHA },
    { 0x0000F800,0x000007E0,0x0000001F, 2, 0x00007C00,0x000003E0,0x0000001F,
      0, ConvertX86p16_16RGB555, ConvertX86, NO_ALPHA },
    { 0x0000F800,0x000007E0,0x0000001F, 2, 0x0000001F,0x000003E0,0x00007C00,
      0, ConvertX86p16_16BGR555, ConvertX86, NO_ALPHA },
#endif
    { 0x0000F800,0x000007E0,0x0000001F, 4, 0x00FF0000,0x0000FF00,0x000000FF,
      0, NULL, Blit_RGB565_ARGB8888, SET_ALPHA },
    { 0x0000F800,0x000007E0,0x0000001F, 4, 0x000000FF,0x0000FF00,0x00FF0000,
      0, NULL, Blit_RGB565_ABGR8888, SET_ALPHA },
    { 0x0000F800,0x000007E0,0x0000001F, 4, 0xFF000000,0x00FF0000,0x0000FF00,
      0, NULL, Blit_RGB565_RGBA8888, SET_ALPHA },
    { 0x0000F800,0x000007E0,0x0000001F, 4, 0x0000FF00,0x00FF0000,0xFF000000,
      0, NULL, Blit_RGB565_BGRA8888, SET_ALPHA },

    /* Default for 16-bit RGB source, used if no other blitter matches */
    { 0,0,0, 0, 0,0,0, 0, NULL, BlitNtoN, 0 }
};
static const struct blit_table normal_blit_3[] = {
	/* Default for 24-bit RGB source, never optimized */
    { 0,0,0, 0, 0,0,0, 0, NULL, BlitNtoN, 0 }
};
static const struct blit_table normal_blit_4[] = {
#ifdef USE_ASMBLIT
    { 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x0000F800,0x000007E0,0x0000001F,
      MMX_CPU, ConvertMMXpII32_16RGB565, ConvertMMX, NO_ALPHA },
    { 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x0000F800,0x000007E0,0x0000001F,
      0, ConvertX86p32_16RGB565, ConvertX86, NO_ALPHA },
    { 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x0000001F,0x000007E0,0x0000F800,
      MMX_CPU, ConvertMMXpII32_16BGR565, ConvertMMX, NO_ALPHA },
    { 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x0000001F,0x000007E0,0x0000F800,
      0, ConvertX86p32_16BGR565, ConvertX86, NO_ALPHA },
    { 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x00007C00,0x000003E0,0x0000001F,
      MMX_CPU, ConvertMMXpII32_16RGB555, ConvertMMX, NO_ALPHA },
    { 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x00007C00,0x000003E0,0x0000001F,
      0, ConvertX86p32_16RGB555, ConvertX86, NO_ALPHA },
    { 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x0000001F,0x000003E0,0x00007C00,
      MMX_CPU, ConvertMMXpII32_16BGR555, ConvertMMX, NO_ALPHA },
    { 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x0000001F,0x000003E0,0x00007C00,
      0, ConvertX86p32_16BGR555, ConvertX86, NO_ALPHA },
    { 0x00FF0000,0x0000FF00,0x000000FF, 3, 0x00FF0000,0x0000FF00,0x000000FF,
      0, ConvertX86p32_24RGB888, ConvertX86, NO_ALPHA },
    { 0x00FF0000,0x0000FF00,0x000000FF, 3, 0x000000FF,0x0000FF00,0x00FF0000,
      0, ConvertX86p32_24BGR888, ConvertX86, NO_ALPHA },
    { 0x00FF0000,0x0000FF00,0x000000FF, 4, 0x000000FF,0x0000FF00,0x00FF0000,
      0, ConvertX86p32_32BGR888, ConvertX86, NO_ALPHA },
    { 0x00FF0000,0x0000FF00,0x000000FF, 4, 0xFF000000,0x00FF0000,0x0000FF00,
      0, ConvertX86p32_32RGBA888, ConvertX86, NO_ALPHA },
    { 0x00FF0000,0x0000FF00,0x000000FF, 4, 0x0000FF00,0x00FF0000,0xFF000000,
      0, ConvertX86p32_32BGRA888, ConvertX86, NO_ALPHA },
#else
    { 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x0000F800,0x000007E0,0x0000001F,
      0, NULL, Blit_RGB888_RGB565, NO_ALPHA },
    { 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x00007C00,0x000003E0,0x0000001F,
      0, NULL, Blit_RGB888_RGB555, NO_ALPHA },
#endif
	/* Default for 32-bit RGB source, used if no other blitter matches */
	{ 0,0,0, 0, 0,0,0, 0, NULL, BlitNtoN, 0 }
};
static const struct blit_table *normal_blit[] = {
	normal_blit_1, normal_blit_2, normal_blit_3, normal_blit_4
};

SDL_loblit SDL_CalculateBlitN(SDL_Surface *surface, int blit_index)
{
	struct private_swaccel *sdata;
	SDL_PixelFormat *srcfmt;
	SDL_PixelFormat *dstfmt;
	const struct blit_table *table;
	int which;
	SDL_loblit blitfun;

	/* Set up data for choosing the blit */
	sdata = surface->map->sw_data;
	srcfmt = surface->format;
	dstfmt = surface->map->dst->format;

	if ( blit_index & 2 ) {
	        /* alpha or alpha+colorkey */
	        return SDL_CalculateAlphaBlit(surface, blit_index);
	}

	/* We don't support destinations less than 8-bits */
	if ( dstfmt->BitsPerPixel < 8 ) {
		return(NULL);
	}
	
	if(blit_index == 1) {
	    /* colorkey blit: Here we don't have too many options, mostly
	       because RLE is the preferred fast way to deal with this.
	       If a particular case turns out to be useful we'll add it. */

	    if(srcfmt->BytesPerPixel == 2
	       && surface->map->identity)
		return Blit2to2Key;
	    else if(dstfmt->BytesPerPixel == 1)
		return BlitNto1Key;
	    else {
		if(srcfmt->Amask && dstfmt->Amask)
		    return BlitNtoNKeyCopyAlpha;
		else
		    return BlitNtoNKey;
	    }
	}

	blitfun = NULL;
	if ( dstfmt->BitsPerPixel == 8 ) {
		/* We assume 8-bit destinations are palettized */
		if ( (srcfmt->BytesPerPixel == 4) &&
		     (srcfmt->Rmask == 0x00FF0000) &&
		     (srcfmt->Gmask == 0x0000FF00) &&
		     (srcfmt->Bmask == 0x000000FF) ) {
			if ( surface->map->table ) {
				blitfun = Blit_RGB888_index8_map;
			} else {
#ifdef USE_ASMBLIT
				sdata->aux_data = ConvertX86p32_8RGB332;
				blitfun = ConvertX86;
#else
				blitfun = Blit_RGB888_index8;
#endif
			}
		} else {
			blitfun = BlitNto1;
		}
	} else {
		/* Now the meat, choose the blitter we want */
	        int a_need = 0;
		if(dstfmt->Amask)
		    a_need = srcfmt->Amask ? COPY_ALPHA : SET_ALPHA;
		table = normal_blit[srcfmt->BytesPerPixel-1];
		for ( which=0; table[which].srcR; ++which ) {
			if ( srcfmt->Rmask == table[which].srcR &&
			     srcfmt->Gmask == table[which].srcG &&
			     srcfmt->Bmask == table[which].srcB &&
			     dstfmt->BytesPerPixel == table[which].dstbpp &&
			     dstfmt->Rmask == table[which].dstR &&
			     dstfmt->Gmask == table[which].dstG &&
			     dstfmt->Bmask == table[which].dstB &&
			     (a_need & table[which].alpha) == a_need &&
			     (CPU_Flags()&table[which].cpu_flags) ==
			     table[which].cpu_flags )
				break;
		}
		sdata->aux_data = table[which].aux_data;
		blitfun = table[which].blitfunc;
		if(a_need == COPY_ALPHA && blitfun == BlitNtoN)
		    blitfun = BlitNtoNCopyAlpha;
	}

#ifdef DEBUG_ASM
#ifdef USE_ASMBLIT
	if ( blitfun == ConvertMMX )
		fprintf(stderr, "Using mmx blit\n");
	else
	if ( blitfun == ConvertX86 )
		fprintf(stderr, "Using asm blit\n");
	else
#endif
	if ( (blitfun == SDL_BlitNtoN) || (blitfun == SDL_BlitNto1) )
		fprintf(stderr, "Using C blit\n");
	else
		fprintf(stderr, "Using optimized C blit\n");
#endif /* DEBUG_ASM */

	return(blitfun);
}

⌨️ 快捷键说明

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