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

📄 gdip_texture.cpp

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 CPP
字号:
/* *			GPAC - Multimedia Framework C SDK * *			Copyright (c) Jean Le Feuvre 2000-2005 *					All rights reserved * *  This file is part of GPAC / GDIplus rasterizer module * *  GPAC is free software; you can redistribute it and/or modify *  it under the terms of the GNU Lesser General Public License as published by *  the Free Software Foundation; either version 2, or (at your option) *  any later version. *    *  GPAC 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 Lesser General Public License for more details. *    *  You should have received a copy of the GNU Lesser General Public *  License along with this library; see the file COPYING.  If not, write to *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  * */#include "gdip_priv.h"#define COL_565(c) ( ( ( (c>>16) & 248) << 8) + ( ( (c>>8) & 252) << 3)  + ( (c&0xFF) >> 3) )#define COL_555(c) ((( (c>>16) & 248)<<7) + (((c>>8) & 248)<<2)  + ((c&0xFF)>>3))staticGF_Err gf_stencil_set_texture(GF_STENCIL _this, char *pixels, u32 width, u32 height, u32 stride, GF_PixelFormat pixelFormat, GF_PixelFormat destination_format_hint, Bool no_copy){	char *ptr;	Bool is_yuv;	u32 pFormat, isBGR, BPP, i, j, col;	unsigned char a, r, g, b;	unsigned short val;	Bool copy;	GPSTEN();	CHECK_RET(GF_STENCIL_TEXTURE);	gf_cmat_reset(&_sten->cmat);	isBGR = 0;	BPP = 4;	copy = 0;	is_yuv = 0;	/*is pixel format supported ?*/	switch (pixelFormat) {	case GF_PIXEL_GREYSCALE:		pFormat = PixelFormat24bppRGB;		BPP = 1;		/*cannot get it to work without using 24bpp rgb*/		copy = 1;		break;	case GF_PIXEL_ALPHAGREY:		pFormat = PixelFormat32bppARGB;		BPP = 2;		/*cannot get it to work without using 32bpp argb*/		copy = 1;		break;	case GF_PIXEL_RGB_555:		pFormat = PixelFormat16bppRGB555;		BPP = 2;		break;	case GF_PIXEL_RGB_565:		pFormat = PixelFormat16bppRGB565;		BPP = 2;		break;	case GF_PIXEL_RGB_24:		pFormat = PixelFormat24bppRGB;		BPP = 3;		/*one day I'll hope to understand how color management works with GDIplus bitmaps...*/		isBGR = 1;//		copy = 1;		break;	case GF_PIXEL_BGR_24:		pFormat = PixelFormat24bppRGB;		BPP = 3;		break;	case GF_PIXEL_RGB_32:		pFormat = PixelFormat32bppRGB;		BPP = 4;		break;	case GF_PIXEL_ARGB:		pFormat = PixelFormat32bppARGB;		BPP = 4;		break;	case GF_PIXEL_RGBA:		pFormat = PixelFormat32bppARGB;		BPP = 4;		copy = 1;		break;	case GF_PIXEL_YV12:	case GF_PIXEL_IYUV:	case GF_PIXEL_I420:		if ( (width*3)%4) return GF_NOT_SUPPORTED;		_sten->orig_format = GF_PIXEL_YV12;		is_yuv = 1;		break;	case GF_PIXEL_YUVA:		_sten->orig_format = GF_PIXEL_YUVA;		is_yuv = 1;		break;	default:		return GF_NOT_SUPPORTED;	}	if (_sten->pBitmap) GdipDisposeImage(_sten->pBitmap);	_sten->pBitmap = NULL;	_sten->width = width;	_sten->height = height;	_sten->destination_format = destination_format_hint;	if (is_yuv) {		_sten->orig_buf = (unsigned char*)pixels;		_sten->orig_stride = stride;		_sten->is_converted = 0;		return GF_OK;	}	_sten->is_converted = 1;	_sten->format = pFormat;	/*GDIplus limitation : horiz_stride shall be multiple of 4 and no support for pure grayscale without palette*/	if (!copy && pixels && !(stride%4)) {		if (no_copy && isBGR) return GF_NOT_SUPPORTED;		GdipCreateBitmapFromScan0(_sten->width, _sten->height, stride, pFormat, (unsigned char*)pixels, &_sten->pBitmap);		_sten->invert_br = isBGR;	}	/*all other cases: create a local bitmap in desired format*/	else {		if (no_copy) return GF_NOT_SUPPORTED;		GdipCreateBitmapFromScan0(_sten->width, _sten->height, 0, pFormat, NULL, &_sten->pBitmap);		ptr = pixels;		for (j=0; j<_sten->height; j++) {		for (i=0; i<_sten->width; i++) {			switch (pixelFormat) {			case GF_PIXEL_GREYSCALE:				col = GF_COL_ARGB(255, *ptr, *ptr, *ptr);				ptr ++;				break;			case GF_PIXEL_ALPHAGREY:				r = *ptr++;				a = *ptr++;				col = GF_COL_ARGB(a, r, r, r);				break;			case GF_PIXEL_RGB_555:				val = * (unsigned short *) (ptr);				ptr+= 2;				col = COL_555(val);				break;			case GF_PIXEL_RGB_565:				val = * (unsigned short *) (ptr);				ptr+= 2;				col = COL_565(val);				break;			/*scan0 uses bgr...*/			case GF_PIXEL_BGR_24:			case GF_PIXEL_RGB_24:				r = *ptr++;				g = *ptr++;				b = *ptr++;				if (!isBGR) {					col = GF_COL_ARGB(255, b, g, r);				} else {					col = GF_COL_ARGB(255, r, g, b);				}				break;			/*NOTE: we assume little-endian only for GDIplus platforms, so BGRA/BGRX*/			case GF_PIXEL_RGB_32:			case GF_PIXEL_ARGB:				b = *ptr++;				g = *ptr++;				r = *ptr++;				a = *ptr++;				if (pixelFormat==GF_PIXEL_RGB_32) a = 0xFF;				col = GF_COL_ARGB(a, r, g, b);				break;			case GF_PIXEL_RGBA:				r = *ptr++;				g = *ptr++;				b = *ptr++;				a = *ptr++;				col = GF_COL_ARGB(a, r, g, b);				break;			default:				col = GF_COL_ARGB(255, 255, 255, 255);				break;			}			GdipBitmapSetPixel(_sten->pBitmap, i, j, col);		}}	}	return GF_OK;}staticGF_Err gf_stencil_create_texture(GF_STENCIL _this, u32 width, u32 height, GF_PixelFormat pixelFormat){	u32 pFormat;	GPSTEN();	CHECK_RET(GF_STENCIL_TEXTURE);	gf_cmat_reset(&_sten->cmat);	/*is pixel format supported ?*/	switch (pixelFormat) {	case GF_PIXEL_BGR_24:	case GF_PIXEL_GREYSCALE:	case GF_PIXEL_RGB_24:		pFormat = PixelFormat24bppRGB;		break;	case GF_PIXEL_ALPHAGREY:		pFormat = PixelFormat32bppARGB;		break;	case GF_PIXEL_RGB_555:		pFormat = PixelFormat16bppRGB555;		break;	case GF_PIXEL_RGB_565:		pFormat = PixelFormat16bppRGB565;		break;	case GF_PIXEL_RGB_32:		pFormat = PixelFormat32bppRGB;		break;	case GF_PIXEL_ARGB:		pFormat = PixelFormat32bppARGB;		break;	default:		return GF_NOT_SUPPORTED;	}	if (_sten->pBitmap) GdipDisposeImage(_sten->pBitmap);	_sten->pBitmap = NULL;	_sten->width = width;	_sten->height = height;	_sten->is_converted = 1;	_sten->format = pFormat;	GdipCreateBitmapFromScan0(_sten->width, _sten->height, 0, pFormat, NULL, &_sten->pBitmap);	return GF_OK;}staticGF_Err gf_set_gf_sr_texture_repeat_mode(GF_STENCIL _this, GF_TextureTiling mode){	GPSTEN();	_sten->tiling = mode;	return GF_OK;}staticGF_Err gf_set_gf_sr_texture_filter(GF_STENCIL _this, GF_TextureFilter filter_mode){	GPSTEN();	CHECK_RET(GF_STENCIL_TEXTURE);	_sten->tFilter = filter_mode;	return GF_OK;}#if 0static void gf_cmat_multiply(GF_ColorMatrix *_this, GF_ColorMatrix *w){	Float res[20];	if (!_this || !w || w->identity) return;	res[0] = _this->m[0]*w->m[0] + _this->m[1]*w->m[5] + _this->m[2]*w->m[10] + _this->m[3]*w->m[15];	res[1] = _this->m[0]*w->m[1] + _this->m[1]*w->m[6] + _this->m[2]*w->m[11] + _this->m[3]*w->m[16];	res[2] = _this->m[0]*w->m[2] + _this->m[1]*w->m[7] + _this->m[2]*w->m[12] + _this->m[3]*w->m[17];	res[3] = _this->m[0]*w->m[3] + _this->m[1]*w->m[8] + _this->m[2]*w->m[13] + _this->m[3]*w->m[18];	res[4] = _this->m[0]*w->m[4] + _this->m[1]*w->m[9] + _this->m[2]*w->m[14] + _this->m[3]*w->m[19] + _this->m[4];		res[5] = _this->m[5]*w->m[0] + _this->m[6]*w->m[5] + _this->m[7]*w->m[10] + _this->m[8]*w->m[15];	res[6] = _this->m[5]*w->m[1] + _this->m[6]*w->m[6] + _this->m[7]*w->m[11] + _this->m[8]*w->m[16];	res[7] = _this->m[5]*w->m[2] + _this->m[6]*w->m[7] + _this->m[7]*w->m[12] + _this->m[8]*w->m[17];	res[8] = _this->m[5]*w->m[3] + _this->m[6]*w->m[8] + _this->m[7]*w->m[13] + _this->m[8]*w->m[18];	res[9] = _this->m[5]*w->m[4] + _this->m[6]*w->m[9] + _this->m[7]*w->m[14] + _this->m[8]*w->m[19] + _this->m[9];		res[10] = _this->m[10]*w->m[0] + _this->m[11]*w->m[5] + _this->m[12]*w->m[10] + _this->m[13]*w->m[15];	res[11] = _this->m[10]*w->m[1] + _this->m[11]*w->m[6] + _this->m[12]*w->m[11] + _this->m[13]*w->m[16];	res[12] = _this->m[10]*w->m[2] + _this->m[11]*w->m[7] + _this->m[12]*w->m[12] + _this->m[13]*w->m[17];	res[13] = _this->m[10]*w->m[3] + _this->m[11]*w->m[8] + _this->m[12]*w->m[13] + _this->m[13]*w->m[18];	res[14] = _this->m[10]*w->m[4] + _this->m[11]*w->m[9] + _this->m[12]*w->m[14] + _this->m[13]*w->m[19] + _this->m[14];		res[15] = _this->m[15]*w->m[0] + _this->m[16]*w->m[5] + _this->m[17]*w->m[10] + _this->m[18]*w->m[15];	res[16] = _this->m[15]*w->m[1] + _this->m[16]*w->m[6] + _this->m[17]*w->m[11] + _this->m[18]*w->m[16];	res[17] = _this->m[15]*w->m[2] + _this->m[16]*w->m[7] + _this->m[17]*w->m[12] + _this->m[18]*w->m[17];	res[18] = _this->m[15]*w->m[3] + _this->m[16]*w->m[8] + _this->m[17]*w->m[13] + _this->m[18]*w->m[18];	res[19] = _this->m[15]*w->m[4] + _this->m[16]*w->m[9] + _this->m[17]*w->m[14] + _this->m[18]*w->m[19] + _this->m[19];		memcpy(_this->m, res, sizeof(Float)*20);}#endifstaticGF_Err gf_stencil_set_color_matrix(GF_STENCIL _this, GF_ColorMatrix *cmat){	GPSTEN();	if (!cmat || cmat->identity) {		_sten->gf_sr_texture_invalid = _sten->has_cmat;		_sten->has_cmat = 0;	} else {		if (_sten->invert_br) {			GF_ColorMatrix fin, rev;			memcpy(&fin, cmat, sizeof(GF_ColorMatrix));			memset(&rev, 0, sizeof(GF_ColorMatrix));			rev.m[0] = 0;			rev.m[2] = 1;			rev.m[10] = 1;			rev.m[12] = 0;			rev.m[6] = rev.m[18] = 1;			gf_cmx_multiply(&fin, &rev);			cmat_gpac_to_gdip(&fin, &_sten->cmat);		} else {			cmat_gpac_to_gdip(cmat, &_sten->cmat);		}		_sten->has_cmat = 1;	}	_sten->gf_sr_texture_invalid = 1;	return GF_OK;}staticGF_Err gf_set_gf_sr_texture_alpha(GF_STENCIL _this, u8 alpha){	GPSTEN();	if (_sten->alpha != alpha) {		_sten->alpha = alpha;		_sten->gf_sr_texture_invalid = 1;	}	return GF_OK;}void gf_convert_texture(struct _stencil *sten);staticGF_Err gf_get_pixel(GF_STENCIL _this, u32 x, u32 y, u32 *col){	ARGB v;	GpStatus st;	GPSTEN();	if (!_sten->is_converted) gf_convert_texture(_sten);	if (!_sten->pBitmap) return GF_BAD_PARAM;	st = GdipBitmapGetPixel(_sten->pBitmap, x, y, &v);	if (_sten->invert_br) {		*col = GF_COL_ARGB( ((v>>24)&0xFF), ((v)&0xFF), ((v>>8)&0xFF), ((v>>16)&0xFF) );	} else {		*col = v;	}	return GF_OK;}staticGF_Err gf_set_pixel(GF_STENCIL _this, u32 x, u32 y, u32 col){	GpStatus st;	ARGB v;	GPSTEN();	if (!_sten->pBitmap) return GF_BAD_PARAM;	if (!_sten->is_converted) gf_convert_texture(_sten);	if (_sten->invert_br) {		v = GF_COL_ARGB( ((col>>24)&0xFF), ((col)&0xFF), ((col>>8)&0xFF), ((col>>16)&0xFF) );	} else {		v = col;	}	st = GdipBitmapSetPixel(_sten->pBitmap, x, y, v);	return GF_OK;}#if 0staticGF_Err gf_get_texture(GF_STENCIL _this, unsigned char **pixels, u32 *width, u32 *height, u32 *stride, GF_PixelFormat *pixelFormat){	GpRect rc;	BitmapData data;	GPSTEN();	if (!_sten->pBitmap) return GF_BAD_PARAM;	rc.X = rc.Y = 0;	rc.Width = _sten->width;	rc.Height = _sten->height;	GdipBitmapLockBits(_sten->pBitmap, &rc, ImageLockModeRead, _sten->format, &data);	*pixels = (unsigned char *) data.Scan0;	*width = data.Width;	*height = data.Height;	*stride = data.Stride;	switch (data.PixelFormat) {	case PixelFormat16bppRGB555:		*pixelFormat = GF_PIXEL_RGB_555;		break;	case PixelFormat16bppRGB565:		*pixelFormat = GF_PIXEL_RGB_565;		break;	case PixelFormat32bppRGB:		*pixelFormat = GF_PIXEL_RGB_32;		break;	case PixelFormat32bppARGB:		*pixelFormat = GF_PIXEL_ARGB;		break;	case PixelFormat24bppRGB:	default:		*pixelFormat = GF_PIXEL_RGB_24;		break;	}	return GF_OK;}#endifvoid gf_stencil_texture_modified(GF_STENCIL _this){	GPSTEN();	_sten->gf_sr_texture_invalid = 1;}void gf_init_driver_texture(GF_Raster2D *driver){	driver->stencil_set_texture = gf_stencil_set_texture;	driver->stencil_set_tiling = gf_set_gf_sr_texture_repeat_mode;	driver->stencil_set_filter = gf_set_gf_sr_texture_filter;	driver->stencil_set_color_matrix = gf_stencil_set_color_matrix;	driver->stencil_set_texture_alpha = gf_set_gf_sr_texture_alpha;	driver->stencil_create_texture = gf_stencil_create_texture;	driver->stencil_texture_modified = gf_stencil_texture_modified;}void gf_convert_texture(struct _stencil *sten){	u32 BPP, format;	GF_VideoSurface src, dst;	if (sten->orig_format == GF_PIXEL_YV12) {		BPP = 3;		dst.pixel_format = GF_PIXEL_BGR_24;		format = PixelFormat24bppRGB;	} else {		BPP = 4;		dst.pixel_format = GF_PIXEL_ARGB;		format = PixelFormat32bppARGB;	}	if (BPP*sten->width*sten->height > sten->conv_size) {		if (sten->conv_buf) free(sten->conv_buf);		sten->conv_size = BPP*sten->width*sten->height;		sten->conv_buf = (unsigned char *) malloc(sizeof(unsigned char)*sten->conv_size);	}	src.height = sten->height;	src.width = sten->width;	src.pitch = sten->orig_stride;	src.pixel_format = sten->orig_format;	src.video_buffer = (char*)sten->orig_buf;	dst.width = sten->width;	dst.height = sten->height;	dst.pitch = BPP*sten->width;	dst.video_buffer = (char*)sten->conv_buf;	gf_stretch_bits(&dst, &src, NULL, NULL, 0, 0xFF, 0, NULL, NULL);	if (sten->pBitmap) GdipDisposeImage(sten->pBitmap);	GdipCreateBitmapFromScan0(sten->width, sten->height, BPP*sten->width, format, sten->conv_buf, &sten->pBitmap);	sten->is_converted = 1;}void gf_load_texture(struct _stencil *sten){	GpImageAttributes *attr;	ColorMatrix _cmat;	if (sten->gf_sr_texture_invalid && sten->pTexture) {		GdipDeleteBrush(sten->pTexture);		sten->pTexture = NULL;	}	/*nothing to do*/	if (sten->is_converted && sten->pTexture) return;	sten->gf_sr_texture_invalid = 0;	/*convert*/	if (!sten->is_converted) gf_convert_texture(sten);	GdipCreateImageAttributes(&attr);	if (sten->has_cmat) {		memcpy(_cmat.m, sten->cmat.m, sizeof(REAL)*5*5);	} else {		memset(_cmat.m, 0, sizeof(REAL)*5*5);		_cmat.m[0][0] = _cmat.m[1][1] = _cmat.m[2][2] = _cmat.m[3][3] = _cmat.m[4][4] = 1.0;		if (sten->invert_br) {			_cmat.m[0][0] = 0;			_cmat.m[0][2] = 1;			_cmat.m[2][2] = 0;			_cmat.m[2][0] = 1;		}	}	_cmat.m[3][3] *= ((REAL) sten->alpha) /255.0f;	GdipSetImageAttributesColorMatrix(attr, ColorAdjustTypeDefault, TRUE, &_cmat, NULL, ColorMatrixFlagsDefault);	if (sten->pTexture) GdipDeleteBrush(sten->pTexture);	GdipCreateTextureIAI(sten->pBitmap, attr, 0, 0, sten->width, sten->height, &sten->pTexture);	/*1- wrap mode is actually ignored in constructor*/	/*2- GDIPlus does not support S / T clamping */	GdipSetTextureWrapMode(sten->pTexture, WrapModeTile);	GdipDisposeImageAttributes(attr);}

⌨️ 快捷键说明

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