📄 stencil.c
字号:
return (a2<<24) | (r2<<16) | (g2<<8) | b2;}#endifstatic void bmp_fill_run(EVGStencil *p, EVGSurface *surf, s32 _x, s32 _y, u32 count) { s32 cx; u32 x0, y0, pix, replace_col; Bool has_alpha, has_replace_cmat, has_cmat, repeat_s, repeat_t; Fixed x, y, _fd; u32 *data = surf->stencil_pix_run; EVG_Texture *_this = (EVG_Texture *) p; /* reverse to texture coords*/ x = INT2FIX(_x); y = INT2FIX(_y); gf_mx2d_apply_coords(&_this->smat, &x, &y); _fd = INT2FIX(_this->width); repeat_s = _this->mod & GF_TEXTURE_REPEAT_S; if (!repeat_s && (x < - _fd)) x = 0; while (x<0) x += _fd; _fd = INT2FIX(_this->height); repeat_t = _this->mod & GF_TEXTURE_REPEAT_T; if (!repeat_t && (y < - _fd)) y = 0; while (y<0) y += _fd; y0 = (s32) FIX2INT(y); has_alpha = (_this->alpha != 255) ? 1 : 0; has_replace_cmat = _this->cmat_is_replace ? 1 : 0; has_cmat = _this->cmat.identity ? 0 : 1; replace_col = _this->replace_col; while (count) { x0 = FIX2INT(x); if (repeat_s) { x0 = (x0) % _this->width; } else { x0 = MIN(x0, _this->width-1); } x += _this->inc_x; y0 = FIX2INT(y); if (repeat_t) { y0 = (y0) % _this->height; } else if (y0 >= _this->width) y0 = _this->height-1; y += _this->inc_y; pix = _this->tx_get_pixel(_this->pixels + _this->stride*y0 + _this->Bpp*x0); /*bilinear filtering - disabled (too slow and not precise enough)*/#if 0 if (_this->filter==GF_TEXTURE_FILTER_HIGH_QUALITY) { u32 p00, p01, p10, p11, x1, y1; u8 tx, ty; x1 = (x0+1) % _this->width; y1 = (y0+1) % _this->height; p00 = pix; p01 = _this->tx_get_pixel(_this->pixels + _this->stride*y0 + _this->Bpp*x1); p10 = _this->tx_get_pixel(_this->pixels + _this->stride*y1 + _this->Bpp*x0); p11 = _this->tx_get_pixel(_this->pixels + _this->stride*y1 + _this->Bpp*x1); tx = FIX2INT(gf_muldiv(x, 255, _this->width) ); ty = FIX2INT(gf_muldiv(y, 255, _this->height) ); p00 = EVG_LERP(p00, p01, tx); p10 = EVG_LERP(p10, p11, tx); pix = EVG_LERP(p00, p10, ty); }#endif if (has_alpha) { cx = ((GF_COL_A(pix) + 1) * _this->alpha) >> 8; pix = ( ((cx<<24) & 0xFF000000) ) | (pix & 0x00FFFFFF); } if (has_replace_cmat) { u32 __a; __a = GF_COL_A(pix); __a = (u32) (_this->cmat.m[18] * __a); pix = ((__a<<24) | (replace_col & 0x00FFFFFF)); } else if (has_cmat) { pix = gf_cmx_apply(&_this->cmat, pix); } *data++ = pix; count--; }}/*just a little faster...*/static void bmp_fill_run_straight(EVGStencil *p, EVGSurface *surf, s32 _x, s32 _y, u32 count) { s32 x0, y0; u32 pix; u32 __a; Bool repeat_s = 0; Fixed x, y, _fdim; char *pix_line; u32 *data = surf->stencil_pix_run; EVG_Texture *_this = (EVG_Texture *) p; /*get texture coords in FIXED*/ x = _this->smat.m[0]*_x + _this->smat.m[2]; y = _this->smat.m[4]*_y + _this->smat.m[5]; /* and move in absolute coords*/ _fdim = INT2FIX(_this->width); if (!(_this->mod & GF_TEXTURE_REPEAT_S)) { if (x<- _fdim) x=0; repeat_s = 0; } else repeat_s = 1; while (x<0) x += _fdim; _fdim = INT2FIX(_this->height); if (!(_this->mod & GF_TEXTURE_REPEAT_T) && (y<- _fdim)) y=0; while (y<0) y += _fdim; y0 = FIX2INT(y); y0 = y0 % _this->height; pix_line = _this->pixels + _this->stride*y0; while (count) { x0 = FIX2INT(x); if (repeat_s) { x0 = (x0) % _this->width; } else if (x0 >= (s32) _this->width) x0 = _this->width-1; x += _this->inc_x; pix = _this->tx_get_pixel(pix_line + _this->Bpp*x0); if (_this->replace_col) { __a = GF_COL_A(pix); pix = ((__a<<24) | (_this->replace_col & 0x00FFFFFF)); } *data++ = pix; count--; }}void evg_bmp_init(EVGStencil *p) { GF_Point2D p0, p1; EVG_Texture *_this = (EVG_Texture *) p; p0.x = p0.y = p1.y = 0; p1.x = FIX_ONE; gf_mx2d_apply_point(&_this->smat, &p0); gf_mx2d_apply_point(&_this->smat, &p1); _this->inc_x = p1.x - p0.x; _this->inc_y = p1.y - p0.y; _this->replace_col = 0; _this->cmat_is_replace = 0; if (!_this->cmat.identity && !_this->cmat.m[0] && !_this->cmat.m[1] && !_this->cmat.m[2] && !_this->cmat.m[3] && !_this->cmat.m[5] && !_this->cmat.m[6] && !_this->cmat.m[7] && !_this->cmat.m[8] && !_this->cmat.m[10] && !_this->cmat.m[11] && !_this->cmat.m[12] && !_this->cmat.m[13] && !_this->cmat.m[15] && !_this->cmat.m[16] && !_this->cmat.m[17] && !_this->cmat.m[19]) { _this->cmat_is_replace = 1; _this->replace_col = GF_COL_ARGB(FIX2INT(_this->cmat.m[18]*255), FIX2INT(_this->cmat.m[4]*255), FIX2INT(_this->cmat.m[9]*255), FIX2INT(_this->cmat.m[14]*255)); } if ((_this->alpha == 255) && !_this->smat.m[1] && !_this->smat.m[3] && (_this->cmat.identity || _this->cmat_is_replace)) { _this->fill_run = bmp_fill_run_straight; } else { _this->fill_run = bmp_fill_run; }}EVGStencil *evg_gf_sr_texture_brush(){ EVG_Texture *tmp; GF_SAFEALLOC(tmp, EVG_Texture); if (!tmp) return 0L; tmp->fill_run = bmp_fill_run; tmp->type = GF_STENCIL_TEXTURE; /*default is using the surface settings*/ tmp->filter = GF_TEXTURE_FILTER_DEFAULT; tmp->mod = 0; gf_cmx_init(&tmp->cmat); tmp->alpha = 255; return (EVGStencil *) tmp;}/*by casting to u32 the input ARGB (BGRA on little endian) we get back to 0xAARRGGBB format on all machines*/u32 get_pix_argb(char *pix) {return *(u32 *) pix;}u32 get_pix_rgba(char *pix) { return GF_COL_ARGB(*(pix+3) & 0xFF, *pix & 0xFF, *(pix+1) & 0xFF, *(pix+2) & 0xFF); }/*same as argb: xxrgb, with indianness support*/u32 get_pix_rgb_32(char *pix) { return ((*(u32 *) pix) | 0xFF000000); }u32 get_pix_rgb_24(char *pix) { return GF_COL_ARGB(0xFF, *pix & 0xFF, *(pix+1) & 0xFF, *(pix+2) & 0xFF); }u32 get_pix_bgr_24(char *pix) { return GF_COL_ARGB(0xFF, *(pix+2) & 0xFF, * (pix+1) & 0xFF, *pix & 0xFF); }u32 get_pix_444(char *pix) { u16 val = *(u16*)pix; return GF_COL_ARGB(0xFF, (u8) ( (val >> 4) & 0xf0), (u8) ( (val) & 0xf0), (u8) ( (val << 4) & 0xf0) ); }u32 get_pix_555(char *pix) { u16 val = *(u16*)pix; return GF_COL_ARGB(0xFF, (u8) ( (val >> 7) & 0xf8), (u8) ( (val >> 2) & 0xf8), (u8) ( (val << 3) & 0xf8) ); }u32 get_pix_565(char *pix) { u16 val = *(u16*)pix; return GF_COL_ARGB(0xFF, (u8) ( (val >> 8) & 0xf8), (u8) ( (val >> 3) & 0xfc), (u8) ( (val << 3) & 0xf8) ); }u32 get_pix_grey(char *pix) { u8 val = *pix; return GF_COL_ARGB(0xFF, val, val, val); }u32 get_pix_alphagrey(char *pix) { return GF_COL_ARGB((u8) *(pix+1), (u8) *pix, (u8) *pix, (u8) *pix); }static void gf_sr_texture_set_callback(EVG_Texture *_this){ switch (_this->pixel_format) { case GF_PIXEL_RGBA: _this->tx_get_pixel = get_pix_rgba; return; case GF_PIXEL_ARGB: _this->tx_get_pixel = get_pix_argb; return; case GF_PIXEL_RGB_32: _this->tx_get_pixel = get_pix_rgb_32; return; case GF_PIXEL_RGB_24: _this->tx_get_pixel = get_pix_rgb_24; return; case GF_PIXEL_BGR_24: _this->tx_get_pixel = get_pix_bgr_24; return; case GF_PIXEL_RGB_444: _this->tx_get_pixel = get_pix_444; return; case GF_PIXEL_RGB_555: _this->tx_get_pixel = get_pix_555; return; case GF_PIXEL_RGB_565: _this->tx_get_pixel = get_pix_565; return; case GF_PIXEL_GREYSCALE: _this->tx_get_pixel = get_pix_grey; return; case GF_PIXEL_ALPHAGREY: _this->tx_get_pixel = get_pix_alphagrey; return; }}GF_Err evg_stencil_set_texture(GF_STENCIL st, char *pixels, u32 width, u32 height, u32 stride, GF_PixelFormat pixelFormat, GF_PixelFormat destination_format_hint, Bool no_copy){ EVG_Texture *_this = (EVG_Texture *) st; if (!_this || (_this->type != GF_STENCIL_TEXTURE) || !pixels || !width || !height || !stride || _this->owns_texture) return GF_BAD_PARAM; _this->pixels = 0L; _this->is_converted = 1; switch (pixelFormat) { case GF_PIXEL_ARGB: case GF_PIXEL_RGBA: case GF_PIXEL_RGB_32: _this->Bpp = 4; break; case GF_PIXEL_RGB_24: case GF_PIXEL_BGR_24: _this->Bpp = 3; break; case GF_PIXEL_RGB_555: case GF_PIXEL_RGB_565: case GF_PIXEL_RGB_444: case GF_PIXEL_ALPHAGREY: _this->Bpp = 2; break; case GF_PIXEL_GREYSCALE: _this->Bpp = 1; break; case GF_PIXEL_YV12: case GF_PIXEL_IYUV: case GF_PIXEL_I420: _this->orig_format = GF_PIXEL_YV12; _this->orig_buf = pixels; _this->orig_stride = stride; _this->is_converted = 0; break; case GF_PIXEL_YUVA: _this->orig_format = GF_PIXEL_YUVA; _this->orig_buf = pixels; _this->orig_stride = stride; _this->is_converted = 0; break; default: /*the rest is not supported (eg BGR32)*/ return GF_NOT_SUPPORTED; } _this->pixel_format = pixelFormat; _this->width = width; _this->height = height; _this->stride = stride; _this->pixels = (char *) pixels; gf_sr_texture_set_callback(_this); return GF_OK;}GF_Err evg_stencil_set_tiling(GF_STENCIL st, GF_TextureTiling mode){ EVG_Texture *_this = (EVG_Texture *) st; if (!_this || (_this->type != GF_STENCIL_TEXTURE)) return GF_BAD_PARAM; _this->mod = mode; return GF_OK;}GF_Err evg_stencil_set_filter(GF_STENCIL st, GF_TextureFilter filter_mode){ EVG_Texture *_this = (EVG_Texture *) st; if (!_this || (_this->type != GF_STENCIL_TEXTURE)) return GF_BAD_PARAM; _this->filter = filter_mode; return GF_OK;}GF_Err evg_stencil_set_color_matrix(GF_STENCIL st, GF_ColorMatrix *cmat){ EVG_Texture *_this = (EVG_Texture *)st; if (!_this) return GF_BAD_PARAM; if (!cmat) gf_cmx_init(&_this->cmat); else gf_cmx_copy(&_this->cmat, cmat); return GF_OK;}GF_Err evg_stencil_set_texture_alpha(GF_STENCIL st, u8 alpha){ EVG_Texture *_this = (EVG_Texture *)st; if (!_this || (_this->type!=GF_STENCIL_TEXTURE)) return GF_BAD_PARAM; _this->alpha = alpha; return GF_OK;}/*internal*/void evg_set_texture_active(EVGStencil *st){ GF_VideoSurface src, dst; EVG_Texture *_this = (EVG_Texture *)st; if (_this->is_converted) return; /*perform YUV->RGB*/ if (_this->orig_format == GF_PIXEL_YV12) { _this->Bpp = 3; _this->pixel_format = GF_PIXEL_RGB_24; } else { _this->Bpp = 4; _this->pixel_format = GF_PIXEL_ARGB; } if (_this->Bpp * _this->width * _this->height > _this->conv_size) { if (_this->conv_buf) free(_this->conv_buf); _this->conv_size = _this->Bpp * _this->width * _this->height; _this->conv_buf = (unsigned char *) malloc(sizeof(unsigned char)*_this->conv_size); } src.height = _this->height; src.width = _this->width; src.pitch = _this->orig_stride; src.pixel_format = _this->orig_format; src.video_buffer = _this->orig_buf; dst.width = _this->width; dst.height = _this->height; dst.pitch = _this->Bpp * _this->width; dst.pixel_format = _this->pixel_format; dst.video_buffer = _this->conv_buf; gf_stretch_bits(&dst, &src, NULL, NULL, 0, 0xFF, 0, NULL, NULL); _this->is_converted = 1; _this->pixels = (char *) _this->conv_buf; _this->stride = _this->Bpp * _this->width; gf_sr_texture_set_callback(_this);}GF_Err evg_stencil_create_texture(GF_STENCIL st, u32 width, u32 height, GF_PixelFormat pixelFormat){ EVG_Texture *_this = (EVG_Texture *)st; if (_this->orig_buf) return GF_BAD_PARAM; _this->pixels = 0L; _this->is_converted = 1; switch (pixelFormat) { case GF_PIXEL_ARGB: case GF_PIXEL_RGBA: case GF_PIXEL_RGB_32: _this->Bpp = 4; break; case GF_PIXEL_RGB_24: case GF_PIXEL_BGR_24: _this->Bpp = 3; break; case GF_PIXEL_RGB_555: case GF_PIXEL_RGB_565: case GF_PIXEL_RGB_444: case GF_PIXEL_ALPHAGREY: _this->Bpp = 2; break; case GF_PIXEL_GREYSCALE: _this->Bpp = 1; break; default: return GF_NOT_SUPPORTED; } _this->pixel_format = pixelFormat; _this->width = width; _this->height = height; _this->stride = width*_this->Bpp; if (_this->pixels) free(_this->pixels); _this->pixels = (char *) malloc(sizeof(char) * _this->stride * _this->height); memset(_this->pixels, 0, sizeof(char) * _this->stride * _this->height); _this->owns_texture = 1; gf_sr_texture_set_callback(_this); return GF_OK;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -