From c3c893108d80e981dd8b089eb659f9fc256fc24a Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 30 Dec 2011 18:19:35 -0500 Subject: [PATCH] Added the ability to update a subrect of a YV12/IYUV texture. --- src/render/SDL_yuv_sw.c | 49 ++++++++++++++++++++++++++++++++++------- 1 file changed, 41 insertions(+), 8 deletions(-) diff --git a/src/render/SDL_yuv_sw.c b/src/render/SDL_yuv_sw.c index a42b62c0b..3a79f100b 100644 --- a/src/render/SDL_yuv_sw.c +++ b/src/render/SDL_yuv_sw.c @@ -1119,15 +1119,48 @@ SDL_SW_UpdateYUVTexture(SDL_SW_YUVTexture * swdata, const SDL_Rect * rect, switch (swdata->format) { case SDL_PIXELFORMAT_YV12: case SDL_PIXELFORMAT_IYUV: - if (rect - && (rect->x != 0 || rect->y != 0 || rect->w != swdata->w - || rect->h != swdata->h)) { - SDL_SetError - ("YV12 and IYUV textures only support full surface updates"); - return -1; + if (rect->x == 0 && rect->y == 0 && + rect->w == swdata->w && rect->h == swdata->h) { + SDL_memcpy(swdata->pixels, pixels, + (swdata->h * swdata->w) + (swdata->h * swdata->w) / 2); + } else { + Uint8 *src, *dst; + int row; + size_t length; + + /* Copy the Y plane */ + src = (Uint8 *) pixels; + dst = swdata->pixels + rect->y * swdata->w + rect->x; + length = rect->w; + for (row = 0; row < rect->h; ++row) { + SDL_memcpy(dst, src, length); + src += pitch; + dst += swdata->w; + } + + /* Copy the next plane */ + src = (Uint8 *) pixels + rect->h * pitch; + dst = swdata->pixels + swdata->h * swdata->w; + dst += rect->y/2 * swdata->w/2 + rect->x/2; + length = rect->w / 2; + for (row = 0; row < rect->h/2; ++row) { + SDL_memcpy(dst, src, length); + src += pitch/2; + dst += swdata->w/2; + } + + /* Copy the next plane */ + src = (Uint8 *) pixels + rect->h * pitch + (rect->h * pitch) / 4; + dst = swdata->pixels + swdata->h * swdata->w + + (swdata->h * swdata->w) / 4; + dst += rect->y/2 * swdata->w/2 + rect->x/2; + length = rect->w / 2; + for (row = 0; row < rect->h/2; ++row) { + SDL_memcpy(dst, src, length); + src += pitch/2; + dst += swdata->w/2; + } } - SDL_memcpy(swdata->pixels, pixels, - (swdata->h * swdata->w) + (swdata->h * swdata->w) / 2); break; case SDL_PIXELFORMAT_YUY2: case SDL_PIXELFORMAT_UYVY: