diff options
Diffstat (limited to '3rdparty/SDL2/src/video/SDL_RLEaccel.c')
-rw-r--r-- | 3rdparty/SDL2/src/video/SDL_RLEaccel.c | 1581 |
1 files changed, 0 insertions, 1581 deletions
diff --git a/3rdparty/SDL2/src/video/SDL_RLEaccel.c b/3rdparty/SDL2/src/video/SDL_RLEaccel.c deleted file mode 100644 index 67baaf664ee..00000000000 --- a/3rdparty/SDL2/src/video/SDL_RLEaccel.c +++ /dev/null @@ -1,1581 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ -#include "../SDL_internal.h" - -/* - * RLE encoding for software colorkey and alpha-channel acceleration - * - * Original version by Sam Lantinga - * - * Mattias Engdegård (Yorick): Rewrite. New encoding format, encoder and - * decoder. Added per-surface alpha blitter. Added per-pixel alpha - * format, encoder and blitter. - * - * Many thanks to Xark and johns for hints, benchmarks and useful comments - * leading to this code. - * - * Welcome to Macro Mayhem. - */ - -/* - * The encoding translates the image data to a stream of segments of the form - * - * <skip> <run> <data> - * - * where <skip> is the number of transparent pixels to skip, - * <run> is the number of opaque pixels to blit, - * and <data> are the pixels themselves. - * - * This basic structure is used both for colorkeyed surfaces, used for simple - * binary transparency and for per-surface alpha blending, and for surfaces - * with per-pixel alpha. The details differ, however: - * - * Encoding of colorkeyed surfaces: - * - * Encoded pixels always have the same format as the target surface. - * <skip> and <run> are unsigned 8 bit integers, except for 32 bit depth - * where they are 16 bit. This makes the pixel data aligned at all times. - * Segments never wrap around from one scan line to the next. - * - * The end of the sequence is marked by a zero <skip>,<run> pair at the * - * beginning of a line. - * - * Encoding of surfaces with per-pixel alpha: - * - * The sequence begins with a struct RLEDestFormat describing the target - * pixel format, to provide reliable un-encoding. - * - * Each scan line is encoded twice: First all completely opaque pixels, - * encoded in the target format as described above, and then all - * partially transparent (translucent) pixels (where 1 <= alpha <= 254), - * in the following 32-bit format: - * - * For 32-bit targets, each pixel has the target RGB format but with - * the alpha value occupying the highest 8 bits. The <skip> and <run> - * counts are 16 bit. - * - * For 16-bit targets, each pixel has the target RGB format, but with - * the middle component (usually green) shifted 16 steps to the left, - * and the hole filled with the 5 most significant bits of the alpha value. - * i.e. if the target has the format rrrrrggggggbbbbb, - * the encoded pixel will be 00000gggggg00000rrrrr0aaaaabbbbb. - * The <skip> and <run> counts are 8 bit for the opaque lines, 16 bit - * for the translucent lines. Two padding bytes may be inserted - * before each translucent line to keep them 32-bit aligned. - * - * The end of the sequence is marked by a zero <skip>,<run> pair at the - * beginning of an opaque line. - */ - -#include "SDL_video.h" -#include "SDL_sysvideo.h" -#include "SDL_blit.h" -#include "SDL_RLEaccel_c.h" - -#ifndef MAX -#define MAX(a, b) ((a) > (b) ? (a) : (b)) -#endif -#ifndef MIN -#define MIN(a, b) ((a) < (b) ? (a) : (b)) -#endif - -#define PIXEL_COPY(to, from, len, bpp) \ - SDL_memcpy(to, from, (size_t)(len) * (bpp)) - -/* - * Various colorkey blit methods, for opaque and per-surface alpha - */ - -#define OPAQUE_BLIT(to, from, length, bpp, alpha) \ - PIXEL_COPY(to, from, length, bpp) - -/* - * For 32bpp pixels on the form 0x00rrggbb: - * If we treat the middle component separately, we can process the two - * remaining in parallel. This is safe to do because of the gap to the left - * of each component, so the bits from the multiplication don't collide. - * This can be used for any RGB permutation of course. - */ -#define ALPHA_BLIT32_888(to, from, length, bpp, alpha) \ - do { \ - int i; \ - Uint32 *src = (Uint32 *)(from); \ - Uint32 *dst = (Uint32 *)(to); \ - for (i = 0; i < (int)(length); i++) { \ - Uint32 s = *src++; \ - Uint32 d = *dst; \ - Uint32 s1 = s & 0xff00ff; \ - Uint32 d1 = d & 0xff00ff; \ - d1 = (d1 + ((s1 - d1) * alpha >> 8)) & 0xff00ff; \ - s &= 0xff00; \ - d &= 0xff00; \ - d = (d + ((s - d) * alpha >> 8)) & 0xff00; \ - *dst++ = d1 | d; \ - } \ - } while (0) - -/* - * For 16bpp pixels we can go a step further: put the middle component - * in the high 16 bits of a 32 bit word, and process all three RGB - * components at the same time. Since the smallest gap is here just - * 5 bits, we have to scale alpha down to 5 bits as well. - */ -#define ALPHA_BLIT16_565(to, from, length, bpp, alpha) \ - do { \ - int i; \ - Uint16 *src = (Uint16 *)(from); \ - Uint16 *dst = (Uint16 *)(to); \ - Uint32 ALPHA = alpha >> 3; \ - for(i = 0; i < (int)(length); i++) { \ - Uint32 s = *src++; \ - Uint32 d = *dst; \ - s = (s | s << 16) & 0x07e0f81f; \ - d = (d | d << 16) & 0x07e0f81f; \ - d += (s - d) * ALPHA >> 5; \ - d &= 0x07e0f81f; \ - *dst++ = (Uint16)(d | d >> 16); \ - } \ - } while(0) - -#define ALPHA_BLIT16_555(to, from, length, bpp, alpha) \ - do { \ - int i; \ - Uint16 *src = (Uint16 *)(from); \ - Uint16 *dst = (Uint16 *)(to); \ - Uint32 ALPHA = alpha >> 3; \ - for(i = 0; i < (int)(length); i++) { \ - Uint32 s = *src++; \ - Uint32 d = *dst; \ - s = (s | s << 16) & 0x03e07c1f; \ - d = (d | d << 16) & 0x03e07c1f; \ - d += (s - d) * ALPHA >> 5; \ - d &= 0x03e07c1f; \ - *dst++ = (Uint16)(d | d >> 16); \ - } \ - } while(0) - -/* - * The general slow catch-all function, for remaining depths and formats - */ -#define ALPHA_BLIT_ANY(to, from, length, bpp, alpha) \ - do { \ - int i; \ - Uint8 *src = from; \ - Uint8 *dst = to; \ - for (i = 0; i < (int)(length); i++) { \ - Uint32 s, d; \ - unsigned rs, gs, bs, rd, gd, bd; \ - switch (bpp) { \ - case 2: \ - s = *(Uint16 *)src; \ - d = *(Uint16 *)dst; \ - break; \ - case 3: \ - if (SDL_BYTEORDER == SDL_BIG_ENDIAN) { \ - s = (src[0] << 16) | (src[1] << 8) | src[2]; \ - d = (dst[0] << 16) | (dst[1] << 8) | dst[2]; \ - } else { \ - s = (src[2] << 16) | (src[1] << 8) | src[0]; \ - d = (dst[2] << 16) | (dst[1] << 8) | dst[0]; \ - } \ - break; \ - case 4: \ - s = *(Uint32 *)src; \ - d = *(Uint32 *)dst; \ - break; \ - } \ - RGB_FROM_PIXEL(s, fmt, rs, gs, bs); \ - RGB_FROM_PIXEL(d, fmt, rd, gd, bd); \ - rd += (rs - rd) * alpha >> 8; \ - gd += (gs - gd) * alpha >> 8; \ - bd += (bs - bd) * alpha >> 8; \ - PIXEL_FROM_RGB(d, fmt, rd, gd, bd); \ - switch (bpp) { \ - case 2: \ - *(Uint16 *)dst = (Uint16)d; \ - break; \ - case 3: \ - if (SDL_BYTEORDER == SDL_BIG_ENDIAN) { \ - dst[0] = (Uint8)(d >> 16); \ - dst[1] = (Uint8)(d >> 8); \ - dst[2] = (Uint8)(d); \ - } else { \ - dst[0] = (Uint8)d; \ - dst[1] = (Uint8)(d >> 8); \ - dst[2] = (Uint8)(d >> 16); \ - } \ - break; \ - case 4: \ - *(Uint32 *)dst = d; \ - break; \ - } \ - src += bpp; \ - dst += bpp; \ - } \ - } while(0) - -/* - * Special case: 50% alpha (alpha=128) - * This is treated specially because it can be optimized very well, and - * since it is good for many cases of semi-translucency. - * The theory is to do all three components at the same time: - * First zero the lowest bit of each component, which gives us room to - * add them. Then shift right and add the sum of the lowest bits. - */ -#define ALPHA_BLIT32_888_50(to, from, length, bpp, alpha) \ - do { \ - int i; \ - Uint32 *src = (Uint32 *)(from); \ - Uint32 *dst = (Uint32 *)(to); \ - for(i = 0; i < (int)(length); i++) { \ - Uint32 s = *src++; \ - Uint32 d = *dst; \ - *dst++ = (((s & 0x00fefefe) + (d & 0x00fefefe)) >> 1) \ - + (s & d & 0x00010101); \ - } \ - } while(0) - -/* - * For 16bpp, we can actually blend two pixels in parallel, if we take - * care to shift before we add, not after. - */ - -/* helper: blend a single 16 bit pixel at 50% */ -#define BLEND16_50(dst, src, mask) \ - do { \ - Uint32 s = *src++; \ - Uint32 d = *dst; \ - *dst++ = (Uint16)((((s & mask) + (d & mask)) >> 1) + \ - (s & d & (~mask & 0xffff))); \ - } while(0) - -/* basic 16bpp blender. mask is the pixels to keep when adding. */ -#define ALPHA_BLIT16_50(to, from, length, bpp, alpha, mask) \ - do { \ - unsigned n = (length); \ - Uint16 *src = (Uint16 *)(from); \ - Uint16 *dst = (Uint16 *)(to); \ - if (((uintptr_t)src ^ (uintptr_t)dst) & 3) { \ - /* source and destination not in phase, blit one by one */ \ - while (n--) \ - BLEND16_50(dst, src, mask); \ - } else { \ - if ((uintptr_t)src & 3) { \ - /* first odd pixel */ \ - BLEND16_50(dst, src, mask); \ - n--; \ - } \ - for (; n > 1; n -= 2) { \ - Uint32 s = *(Uint32 *)src; \ - Uint32 d = *(Uint32 *)dst; \ - *(Uint32 *)dst = ((s & (mask | mask << 16)) >> 1) \ - + ((d & (mask | mask << 16)) >> 1) \ - + (s & d & (~(mask | mask << 16))); \ - src += 2; \ - dst += 2; \ - } \ - if (n) \ - BLEND16_50(dst, src, mask); /* last odd pixel */ \ - } \ - } while(0) - -#define ALPHA_BLIT16_565_50(to, from, length, bpp, alpha) \ - ALPHA_BLIT16_50(to, from, length, bpp, alpha, 0xf7de) - -#define ALPHA_BLIT16_555_50(to, from, length, bpp, alpha) \ - ALPHA_BLIT16_50(to, from, length, bpp, alpha, 0xfbde) - -#define CHOOSE_BLIT(blitter, alpha, fmt) \ - do { \ - if (alpha == 255) { \ - switch (fmt->BytesPerPixel) { \ - case 1: blitter(1, Uint8, OPAQUE_BLIT); break; \ - case 2: blitter(2, Uint8, OPAQUE_BLIT); break; \ - case 3: blitter(3, Uint8, OPAQUE_BLIT); break; \ - case 4: blitter(4, Uint16, OPAQUE_BLIT); break; \ - } \ - } else { \ - switch (fmt->BytesPerPixel) { \ - case 1: \ - /* No 8bpp alpha blitting */ \ - break; \ - \ - case 2: \ - switch (fmt->Rmask | fmt->Gmask | fmt->Bmask) { \ - case 0xffff: \ - if (fmt->Gmask == 0x07e0 \ - || fmt->Rmask == 0x07e0 \ - || fmt->Bmask == 0x07e0) { \ - if (alpha == 128) { \ - blitter(2, Uint8, ALPHA_BLIT16_565_50); \ - } else { \ - blitter(2, Uint8, ALPHA_BLIT16_565); \ - } \ - } else \ - goto general16; \ - break; \ - \ - case 0x7fff: \ - if (fmt->Gmask == 0x03e0 \ - || fmt->Rmask == 0x03e0 \ - || fmt->Bmask == 0x03e0) { \ - if (alpha == 128) { \ - blitter(2, Uint8, ALPHA_BLIT16_555_50); \ - } else { \ - blitter(2, Uint8, ALPHA_BLIT16_555); \ - } \ - break; \ - } else \ - goto general16; \ - break; \ - \ - default: \ - general16: \ - blitter(2, Uint8, ALPHA_BLIT_ANY); \ - } \ - break; \ - \ - case 3: \ - blitter(3, Uint8, ALPHA_BLIT_ANY); \ - break; \ - \ - case 4: \ - if ((fmt->Rmask | fmt->Gmask | fmt->Bmask) == 0x00ffffff \ - && (fmt->Gmask == 0xff00 || fmt->Rmask == 0xff00 \ - || fmt->Bmask == 0xff00)) { \ - if (alpha == 128) { \ - blitter(4, Uint16, ALPHA_BLIT32_888_50); \ - } else { \ - blitter(4, Uint16, ALPHA_BLIT32_888); \ - } \ - } else \ - blitter(4, Uint16, ALPHA_BLIT_ANY); \ - break; \ - } \ - } \ - } while(0) - -/* - * Set a pixel value using the given format, except that the alpha value is - * placed in the top byte. This is the format used for RLE with alpha. - */ -#define RLEPIXEL_FROM_RGBA(Pixel, fmt, r, g, b, a) \ -{ \ - Pixel = ((r>>fmt->Rloss)<<fmt->Rshift)| \ - ((g>>fmt->Gloss)<<fmt->Gshift)| \ - ((b>>fmt->Bloss)<<fmt->Bshift)| \ - (a<<24); \ -} - -/* - * This takes care of the case when the surface is clipped on the left and/or - * right. Top clipping has already been taken care of. - */ -static void -RLEClipBlit(int w, Uint8 * srcbuf, SDL_Surface * surf_dst, - Uint8 * dstbuf, SDL_Rect * srcrect, unsigned alpha) -{ - SDL_PixelFormat *fmt = surf_dst->format; - -#define RLECLIPBLIT(bpp, Type, do_blit) \ - do { \ - int linecount = srcrect->h; \ - int ofs = 0; \ - int left = srcrect->x; \ - int right = left + srcrect->w; \ - dstbuf -= left * bpp; \ - for (;;) { \ - int run; \ - ofs += *(Type *)srcbuf; \ - run = ((Type *)srcbuf)[1]; \ - srcbuf += 2 * sizeof(Type); \ - if (run) { \ - /* clip to left and right borders */ \ - if (ofs < right) { \ - int start = 0; \ - int len = run; \ - int startcol; \ - if (left - ofs > 0) { \ - start = left - ofs; \ - len -= start; \ - if (len <= 0) \ - goto nocopy ## bpp ## do_blit; \ - } \ - startcol = ofs + start; \ - if (len > right - startcol) \ - len = right - startcol; \ - do_blit(dstbuf + startcol * bpp, srcbuf + start * bpp, \ - len, bpp, alpha); \ - } \ - nocopy ## bpp ## do_blit: \ - srcbuf += run * bpp; \ - ofs += run; \ - } else if (!ofs) \ - break; \ - \ - if (ofs == w) { \ - ofs = 0; \ - dstbuf += surf_dst->pitch; \ - if (!--linecount) \ - break; \ - } \ - } \ - } while(0) - - CHOOSE_BLIT(RLECLIPBLIT, alpha, fmt); - -#undef RLECLIPBLIT - -} - - -/* blit a colorkeyed RLE surface */ -int -SDL_RLEBlit(SDL_Surface * surf_src, SDL_Rect * srcrect, - SDL_Surface * surf_dst, SDL_Rect * dstrect) -{ - Uint8 *dstbuf; - Uint8 *srcbuf; - int x, y; - int w = surf_src->w; - unsigned alpha; - - /* Lock the destination if necessary */ - if (SDL_MUSTLOCK(surf_dst)) { - if (SDL_LockSurface(surf_dst) < 0) { - return (-1); - } - } - - /* Set up the source and destination pointers */ - x = dstrect->x; - y = dstrect->y; - dstbuf = (Uint8 *) surf_dst->pixels - + y * surf_dst->pitch + x * surf_src->format->BytesPerPixel; - srcbuf = (Uint8 *) surf_src->map->data; - - { - /* skip lines at the top if necessary */ - int vskip = srcrect->y; - int ofs = 0; - if (vskip) { - -#define RLESKIP(bpp, Type) \ - for(;;) { \ - int run; \ - ofs += *(Type *)srcbuf; \ - run = ((Type *)srcbuf)[1]; \ - srcbuf += sizeof(Type) * 2; \ - if(run) { \ - srcbuf += run * bpp; \ - ofs += run; \ - } else if(!ofs) \ - goto done; \ - if(ofs == w) { \ - ofs = 0; \ - if(!--vskip) \ - break; \ - } \ - } - - switch (surf_src->format->BytesPerPixel) { - case 1: - RLESKIP(1, Uint8); - break; - case 2: - RLESKIP(2, Uint8); - break; - case 3: - RLESKIP(3, Uint8); - break; - case 4: - RLESKIP(4, Uint16); - break; - } - -#undef RLESKIP - - } - } - - alpha = surf_src->map->info.a; - /* if left or right edge clipping needed, call clip blit */ - if (srcrect->x || srcrect->w != surf_src->w) { - RLEClipBlit(w, srcbuf, surf_dst, dstbuf, srcrect, alpha); - } else { - SDL_PixelFormat *fmt = surf_src->format; - -#define RLEBLIT(bpp, Type, do_blit) \ - do { \ - int linecount = srcrect->h; \ - int ofs = 0; \ - for(;;) { \ - unsigned run; \ - ofs += *(Type *)srcbuf; \ - run = ((Type *)srcbuf)[1]; \ - srcbuf += 2 * sizeof(Type); \ - if(run) { \ - do_blit(dstbuf + ofs * bpp, srcbuf, run, bpp, alpha); \ - srcbuf += run * bpp; \ - ofs += run; \ - } else if(!ofs) \ - break; \ - if(ofs == w) { \ - ofs = 0; \ - dstbuf += surf_dst->pitch; \ - if(!--linecount) \ - break; \ - } \ - } \ - } while(0) - - CHOOSE_BLIT(RLEBLIT, alpha, fmt); - -#undef RLEBLIT - } - - done: - /* Unlock the destination if necessary */ - if (SDL_MUSTLOCK(surf_dst)) { - SDL_UnlockSurface(surf_dst); - } - return (0); -} - -#undef OPAQUE_BLIT - -/* - * Per-pixel blitting macros for translucent pixels: - * These use the same techniques as the per-surface blitting macros - */ - -/* - * For 32bpp pixels, we have made sure the alpha is stored in the top - * 8 bits, so proceed as usual - */ -#define BLIT_TRANSL_888(src, dst) \ - do { \ - Uint32 s = src; \ - Uint32 d = dst; \ - unsigned alpha = s >> 24; \ - Uint32 s1 = s & 0xff00ff; \ - Uint32 d1 = d & 0xff00ff; \ - d1 = (d1 + ((s1 - d1) * alpha >> 8)) & 0xff00ff; \ - s &= 0xff00; \ - d &= 0xff00; \ - d = (d + ((s - d) * alpha >> 8)) & 0xff00; \ - dst = d1 | d | 0xff000000; \ - } while(0) - -/* - * For 16bpp pixels, we have stored the 5 most significant alpha bits in - * bits 5-10. As before, we can process all 3 RGB components at the same time. - */ -#define BLIT_TRANSL_565(src, dst) \ - do { \ - Uint32 s = src; \ - Uint32 d = dst; \ - unsigned alpha = (s & 0x3e0) >> 5; \ - s &= 0x07e0f81f; \ - d = (d | d << 16) & 0x07e0f81f; \ - d += (s - d) * alpha >> 5; \ - d &= 0x07e0f81f; \ - dst = (Uint16)(d | d >> 16); \ - } while(0) - -#define BLIT_TRANSL_555(src, dst) \ - do { \ - Uint32 s = src; \ - Uint32 d = dst; \ - unsigned alpha = (s & 0x3e0) >> 5; \ - s &= 0x03e07c1f; \ - d = (d | d << 16) & 0x03e07c1f; \ - d += (s - d) * alpha >> 5; \ - d &= 0x03e07c1f; \ - dst = (Uint16)(d | d >> 16); \ - } while(0) - -/* used to save the destination format in the encoding. Designed to be - macro-compatible with SDL_PixelFormat but without the unneeded fields */ -typedef struct -{ - Uint8 BytesPerPixel; - Uint8 padding[3]; - Uint32 Rmask; - Uint32 Gmask; - Uint32 Bmask; - Uint32 Amask; - Uint8 Rloss; - Uint8 Gloss; - Uint8 Bloss; - Uint8 Aloss; - Uint8 Rshift; - Uint8 Gshift; - Uint8 Bshift; - Uint8 Ashift; -} RLEDestFormat; - -/* blit a pixel-alpha RLE surface clipped at the right and/or left edges */ -static void -RLEAlphaClipBlit(int w, Uint8 * srcbuf, SDL_Surface * surf_dst, - Uint8 * dstbuf, SDL_Rect * srcrect) -{ - SDL_PixelFormat *df = surf_dst->format; - /* - * clipped blitter: Ptype is the destination pixel type, - * Ctype the translucent count type, and do_blend the macro - * to blend one pixel. - */ -#define RLEALPHACLIPBLIT(Ptype, Ctype, do_blend) \ - do { \ - int linecount = srcrect->h; \ - int left = srcrect->x; \ - int right = left + srcrect->w; \ - dstbuf -= left * sizeof(Ptype); \ - do { \ - int ofs = 0; \ - /* blit opaque pixels on one line */ \ - do { \ - unsigned run; \ - ofs += ((Ctype *)srcbuf)[0]; \ - run = ((Ctype *)srcbuf)[1]; \ - srcbuf += 2 * sizeof(Ctype); \ - if(run) { \ - /* clip to left and right borders */ \ - int cofs = ofs; \ - int crun = run; \ - if(left - cofs > 0) { \ - crun -= left - cofs; \ - cofs = left; \ - } \ - if(crun > right - cofs) \ - crun = right - cofs; \ - if(crun > 0) \ - PIXEL_COPY(dstbuf + cofs * sizeof(Ptype), \ - srcbuf + (cofs - ofs) * sizeof(Ptype), \ - (unsigned)crun, sizeof(Ptype)); \ - srcbuf += run * sizeof(Ptype); \ - ofs += run; \ - } else if(!ofs) \ - return; \ - } while(ofs < w); \ - /* skip padding if necessary */ \ - if(sizeof(Ptype) == 2) \ - srcbuf += (uintptr_t)srcbuf & 2; \ - /* blit translucent pixels on the same line */ \ - ofs = 0; \ - do { \ - unsigned run; \ - ofs += ((Uint16 *)srcbuf)[0]; \ - run = ((Uint16 *)srcbuf)[1]; \ - srcbuf += 4; \ - if(run) { \ - /* clip to left and right borders */ \ - int cofs = ofs; \ - int crun = run; \ - if(left - cofs > 0) { \ - crun -= left - cofs; \ - cofs = left; \ - } \ - if(crun > right - cofs) \ - crun = right - cofs; \ - if(crun > 0) { \ - Ptype *dst = (Ptype *)dstbuf + cofs; \ - Uint32 *src = (Uint32 *)srcbuf + (cofs - ofs); \ - int i; \ - for(i = 0; i < crun; i++) \ - do_blend(src[i], dst[i]); \ - } \ - srcbuf += run * 4; \ - ofs += run; \ - } \ - } while(ofs < w); \ - dstbuf += surf_dst->pitch; \ - } while(--linecount); \ - } while(0) - - switch (df->BytesPerPixel) { - case 2: - if (df->Gmask == 0x07e0 || df->Rmask == 0x07e0 || df->Bmask == 0x07e0) - RLEALPHACLIPBLIT(Uint16, Uint8, BLIT_TRANSL_565); - else - RLEALPHACLIPBLIT(Uint16, Uint8, BLIT_TRANSL_555); - break; - case 4: - RLEALPHACLIPBLIT(Uint32, Uint16, BLIT_TRANSL_888); - break; - } -} - -/* blit a pixel-alpha RLE surface */ -int -SDL_RLEAlphaBlit(SDL_Surface * surf_src, SDL_Rect * srcrect, - SDL_Surface * surf_dst, SDL_Rect * dstrect) -{ - int x, y; - int w = surf_src->w; - Uint8 *srcbuf, *dstbuf; - SDL_PixelFormat *df = surf_dst->format; - - /* Lock the destination if necessary */ - if (SDL_MUSTLOCK(surf_dst)) { - if (SDL_LockSurface(surf_dst) < 0) { - return -1; - } - } - - x = dstrect->x; - y = dstrect->y; - dstbuf = (Uint8 *) surf_dst->pixels + y * surf_dst->pitch + x * df->BytesPerPixel; - srcbuf = (Uint8 *) surf_src->map->data + sizeof(RLEDestFormat); - - { - /* skip lines at the top if necessary */ - int vskip = srcrect->y; - if (vskip) { - int ofs; - if (df->BytesPerPixel == 2) { - /* the 16/32 interleaved format */ - do { - /* skip opaque line */ - ofs = 0; - do { - int run; - ofs += srcbuf[0]; - run = srcbuf[1]; - srcbuf += 2; - if (run) { - srcbuf += 2 * run; - ofs += run; - } else if (!ofs) - goto done; - } while (ofs < w); - - /* skip padding */ - srcbuf += (uintptr_t) srcbuf & 2; - - /* skip translucent line */ - ofs = 0; - do { - int run; - ofs += ((Uint16 *) srcbuf)[0]; - run = ((Uint16 *) srcbuf)[1]; - srcbuf += 4 * (run + 1); - ofs += run; - } while (ofs < w); - } while (--vskip); - } else { - /* the 32/32 interleaved format */ - vskip <<= 1; /* opaque and translucent have same format */ - do { - ofs = 0; - do { - int run; - ofs += ((Uint16 *) srcbuf)[0]; - run = ((Uint16 *) srcbuf)[1]; - srcbuf += 4; - if (run) { - srcbuf += 4 * run; - ofs += run; - } else if (!ofs) - goto done; - } while (ofs < w); - } while (--vskip); - } - } - } - - /* if left or right edge clipping needed, call clip blit */ - if (srcrect->x || srcrect->w != surf_src->w) { - RLEAlphaClipBlit(w, srcbuf, surf_dst, dstbuf, srcrect); - } else { - - /* - * non-clipped blitter. Ptype is the destination pixel type, - * Ctype the translucent count type, and do_blend the - * macro to blend one pixel. - */ -#define RLEALPHABLIT(Ptype, Ctype, do_blend) \ - do { \ - int linecount = srcrect->h; \ - do { \ - int ofs = 0; \ - /* blit opaque pixels on one line */ \ - do { \ - unsigned run; \ - ofs += ((Ctype *)srcbuf)[0]; \ - run = ((Ctype *)srcbuf)[1]; \ - srcbuf += 2 * sizeof(Ctype); \ - if(run) { \ - PIXEL_COPY(dstbuf + ofs * sizeof(Ptype), srcbuf, \ - run, sizeof(Ptype)); \ - srcbuf += run * sizeof(Ptype); \ - ofs += run; \ - } else if(!ofs) \ - goto done; \ - } while(ofs < w); \ - /* skip padding if necessary */ \ - if(sizeof(Ptype) == 2) \ - srcbuf += (uintptr_t)srcbuf & 2; \ - /* blit translucent pixels on the same line */ \ - ofs = 0; \ - do { \ - unsigned run; \ - ofs += ((Uint16 *)srcbuf)[0]; \ - run = ((Uint16 *)srcbuf)[1]; \ - srcbuf += 4; \ - if(run) { \ - Ptype *dst = (Ptype *)dstbuf + ofs; \ - unsigned i; \ - for(i = 0; i < run; i++) { \ - Uint32 src = *(Uint32 *)srcbuf; \ - do_blend(src, *dst); \ - srcbuf += 4; \ - dst++; \ - } \ - ofs += run; \ - } \ - } while(ofs < w); \ - dstbuf += surf_dst->pitch; \ - } while(--linecount); \ - } while(0) - - switch (df->BytesPerPixel) { - case 2: - if (df->Gmask == 0x07e0 || df->Rmask == 0x07e0 - || df->Bmask == 0x07e0) - RLEALPHABLIT(Uint16, Uint8, BLIT_TRANSL_565); - else - RLEALPHABLIT(Uint16, Uint8, BLIT_TRANSL_555); - break; - case 4: - RLEALPHABLIT(Uint32, Uint16, BLIT_TRANSL_888); - break; - } - } - - done: - /* Unlock the destination if necessary */ - if (SDL_MUSTLOCK(surf_dst)) { - SDL_UnlockSurface(surf_dst); - } - return 0; -} - -/* - * Auxiliary functions: - * The encoding functions take 32bpp rgb + a, and - * return the number of bytes copied to the destination. - * The decoding functions copy to 32bpp rgb + a, and - * return the number of bytes copied from the source. - * These are only used in the encoder and un-RLE code and are therefore not - * highly optimised. - */ - -/* encode 32bpp rgb + a into 16bpp rgb, losing alpha */ -static int -copy_opaque_16(void *dst, Uint32 * src, int n, - SDL_PixelFormat * sfmt, SDL_PixelFormat * dfmt) -{ - int i; - Uint16 *d = dst; - for (i = 0; i < n; i++) { - unsigned r, g, b; - RGB_FROM_PIXEL(*src, sfmt, r, g, b); - PIXEL_FROM_RGB(*d, dfmt, r, g, b); - src++; - d++; - } - return n * 2; -} - -/* decode opaque pixels from 16bpp to 32bpp rgb + a */ -static int -uncopy_opaque_16(Uint32 * dst, void *src, int n, - RLEDestFormat * sfmt, SDL_PixelFormat * dfmt) -{ - int i; - Uint16 *s = src; - unsigned alpha = dfmt->Amask ? 255 : 0; - for (i = 0; i < n; i++) { - unsigned r, g, b; - RGB_FROM_PIXEL(*s, sfmt, r, g, b); - PIXEL_FROM_RGBA(*dst, dfmt, r, g, b, alpha); - s++; - dst++; - } - return n * 2; -} - - - -/* encode 32bpp rgb + a into 32bpp G0RAB format for blitting into 565 */ -static int -copy_transl_565(void *dst, Uint32 * src, int n, - SDL_PixelFormat * sfmt, SDL_PixelFormat * dfmt) -{ - int i; - Uint32 *d = dst; - for (i = 0; i < n; i++) { - unsigned r, g, b, a; - Uint16 pix; - RGBA_FROM_8888(*src, sfmt, r, g, b, a); - PIXEL_FROM_RGB(pix, dfmt, r, g, b); - *d = ((pix & 0x7e0) << 16) | (pix & 0xf81f) | ((a << 2) & 0x7e0); - src++; - d++; - } - return n * 4; -} - -/* encode 32bpp rgb + a into 32bpp G0RAB format for blitting into 555 */ -static int -copy_transl_555(void *dst, Uint32 * src, int n, - SDL_PixelFormat * sfmt, SDL_PixelFormat * dfmt) -{ - int i; - Uint32 *d = dst; - for (i = 0; i < n; i++) { - unsigned r, g, b, a; - Uint16 pix; - RGBA_FROM_8888(*src, sfmt, r, g, b, a); - PIXEL_FROM_RGB(pix, dfmt, r, g, b); - *d = ((pix & 0x3e0) << 16) | (pix & 0xfc1f) | ((a << 2) & 0x3e0); - src++; - d++; - } - return n * 4; -} - -/* decode translucent pixels from 32bpp GORAB to 32bpp rgb + a */ -static int -uncopy_transl_16(Uint32 * dst, void *src, int n, - RLEDestFormat * sfmt, SDL_PixelFormat * dfmt) -{ - int i; - Uint32 *s = src; - for (i = 0; i < n; i++) { - unsigned r, g, b, a; - Uint32 pix = *s++; - a = (pix & 0x3e0) >> 2; - pix = (pix & ~0x3e0) | pix >> 16; - RGB_FROM_PIXEL(pix, sfmt, r, g, b); - PIXEL_FROM_RGBA(*dst, dfmt, r, g, b, a); - dst++; - } - return n * 4; -} - -/* encode 32bpp rgba into 32bpp rgba, keeping alpha (dual purpose) */ -static int -copy_32(void *dst, Uint32 * src, int n, - SDL_PixelFormat * sfmt, SDL_PixelFormat * dfmt) -{ - int i; - Uint32 *d = dst; - for (i = 0; i < n; i++) { - unsigned r, g, b, a; - RGBA_FROM_8888(*src, sfmt, r, g, b, a); - RLEPIXEL_FROM_RGBA(*d, dfmt, r, g, b, a); - d++; - src++; - } - return n * 4; -} - -/* decode 32bpp rgba into 32bpp rgba, keeping alpha (dual purpose) */ -static int -uncopy_32(Uint32 * dst, void *src, int n, - RLEDestFormat * sfmt, SDL_PixelFormat * dfmt) -{ - int i; - Uint32 *s = src; - for (i = 0; i < n; i++) { - unsigned r, g, b, a; - Uint32 pixel = *s++; - RGB_FROM_PIXEL(pixel, sfmt, r, g, b); - a = pixel >> 24; - PIXEL_FROM_RGBA(*dst, dfmt, r, g, b, a); - dst++; - } - return n * 4; -} - -#define ISOPAQUE(pixel, fmt) ((((pixel) & fmt->Amask) >> fmt->Ashift) == 255) - -#define ISTRANSL(pixel, fmt) \ - ((unsigned)((((pixel) & fmt->Amask) >> fmt->Ashift) - 1U) < 254U) - -/* convert surface to be quickly alpha-blittable onto dest, if possible */ -static int -RLEAlphaSurface(SDL_Surface * surface) -{ - SDL_Surface *dest; - SDL_PixelFormat *df; - int maxsize = 0; - int max_opaque_run; - int max_transl_run = 65535; - unsigned masksum; - Uint8 *rlebuf, *dst; - int (*copy_opaque) (void *, Uint32 *, int, - SDL_PixelFormat *, SDL_PixelFormat *); - int (*copy_transl) (void *, Uint32 *, int, - SDL_PixelFormat *, SDL_PixelFormat *); - - dest = surface->map->dst; - if (!dest) - return -1; - df = dest->format; - if (surface->format->BitsPerPixel != 32) - return -1; /* only 32bpp source supported */ - - /* find out whether the destination is one we support, - and determine the max size of the encoded result */ - masksum = df->Rmask | df->Gmask | df->Bmask; - switch (df->BytesPerPixel) { - case 2: - /* 16bpp: only support 565 and 555 formats */ - switch (masksum) { - case 0xffff: - if (df->Gmask == 0x07e0 - || df->Rmask == 0x07e0 || df->Bmask == 0x07e0) { - copy_opaque = copy_opaque_16; - copy_transl = copy_transl_565; - } else - return -1; - break; - case 0x7fff: - if (df->Gmask == 0x03e0 - || df->Rmask == 0x03e0 || df->Bmask == 0x03e0) { - copy_opaque = copy_opaque_16; - copy_transl = copy_transl_555; - } else - return -1; - break; - default: - return -1; - } - max_opaque_run = 255; /* runs stored as bytes */ - - /* worst case is alternating opaque and translucent pixels, - with room for alignment padding between lines */ - maxsize = surface->h * (2 + (4 + 2) * (surface->w + 1)) + 2; - break; - case 4: - if (masksum != 0x00ffffff) - return -1; /* requires unused high byte */ - copy_opaque = copy_32; - copy_transl = copy_32; - max_opaque_run = 255; /* runs stored as short ints */ - - /* worst case is alternating opaque and translucent pixels */ - maxsize = surface->h * 2 * 4 * (surface->w + 1) + 4; - break; - default: - return -1; /* anything else unsupported right now */ - } - - maxsize += sizeof(RLEDestFormat); - rlebuf = (Uint8 *) SDL_malloc(maxsize); - if (!rlebuf) { - return SDL_OutOfMemory(); - } - { - /* save the destination format so we can undo the encoding later */ - RLEDestFormat *r = (RLEDestFormat *) rlebuf; - r->BytesPerPixel = df->BytesPerPixel; - r->Rmask = df->Rmask; - r->Gmask = df->Gmask; - r->Bmask = df->Bmask; - r->Amask = df->Amask; - r->Rloss = df->Rloss; - r->Gloss = df->Gloss; - r->Bloss = df->Bloss; - r->Aloss = df->Aloss; - r->Rshift = df->Rshift; - r->Gshift = df->Gshift; - r->Bshift = df->Bshift; - r->Ashift = df->Ashift; - } - dst = rlebuf + sizeof(RLEDestFormat); - - /* Do the actual encoding */ - { - int x, y; - int h = surface->h, w = surface->w; - SDL_PixelFormat *sf = surface->format; - Uint32 *src = (Uint32 *) surface->pixels; - Uint8 *lastline = dst; /* end of last non-blank line */ - - /* opaque counts are 8 or 16 bits, depending on target depth */ -#define ADD_OPAQUE_COUNTS(n, m) \ - if(df->BytesPerPixel == 4) { \ - ((Uint16 *)dst)[0] = n; \ - ((Uint16 *)dst)[1] = m; \ - dst += 4; \ - } else { \ - dst[0] = n; \ - dst[1] = m; \ - dst += 2; \ - } - - /* translucent counts are always 16 bit */ -#define ADD_TRANSL_COUNTS(n, m) \ - (((Uint16 *)dst)[0] = n, ((Uint16 *)dst)[1] = m, dst += 4) - - for (y = 0; y < h; y++) { - int runstart, skipstart; - int blankline = 0; - /* First encode all opaque pixels of a scan line */ - x = 0; - do { - int run, skip, len; - skipstart = x; - while (x < w && !ISOPAQUE(src[x], sf)) - x++; - runstart = x; - while (x < w && ISOPAQUE(src[x], sf)) - x++; - skip = runstart - skipstart; - if (skip == w) - blankline = 1; - run = x - runstart; - while (skip > max_opaque_run) { - ADD_OPAQUE_COUNTS(max_opaque_run, 0); - skip -= max_opaque_run; - } - len = MIN(run, max_opaque_run); - ADD_OPAQUE_COUNTS(skip, len); - dst += copy_opaque(dst, src + runstart, len, sf, df); - runstart += len; - run -= len; - while (run) { - len = MIN(run, max_opaque_run); - ADD_OPAQUE_COUNTS(0, len); - dst += copy_opaque(dst, src + runstart, len, sf, df); - runstart += len; - run -= len; - } - } while (x < w); - - /* Make sure the next output address is 32-bit aligned */ - dst += (uintptr_t) dst & 2; - - /* Next, encode all translucent pixels of the same scan line */ - x = 0; - do { - int run, skip, len; - skipstart = x; - while (x < w && !ISTRANSL(src[x], sf)) - x++; - runstart = x; - while (x < w && ISTRANSL(src[x], sf)) - x++; - skip = runstart - skipstart; - blankline &= (skip == w); - run = x - runstart; - while (skip > max_transl_run) { - ADD_TRANSL_COUNTS(max_transl_run, 0); - skip -= max_transl_run; - } - len = MIN(run, max_transl_run); - ADD_TRANSL_COUNTS(skip, len); - dst += copy_transl(dst, src + runstart, len, sf, df); - runstart += len; - run -= len; - while (run) { - len = MIN(run, max_transl_run); - ADD_TRANSL_COUNTS(0, len); - dst += copy_transl(dst, src + runstart, len, sf, df); - runstart += len; - run -= len; - } - if (!blankline) - lastline = dst; - } while (x < w); - - src += surface->pitch >> 2; - } - dst = lastline; /* back up past trailing blank lines */ - ADD_OPAQUE_COUNTS(0, 0); - } - -#undef ADD_OPAQUE_COUNTS -#undef ADD_TRANSL_COUNTS - - /* Now that we have it encoded, release the original pixels */ - if (!(surface->flags & SDL_PREALLOC)) { - SDL_free(surface->pixels); - surface->pixels = NULL; - } - - /* realloc the buffer to release unused memory */ - { - Uint8 *p = SDL_realloc(rlebuf, dst - rlebuf); - if (!p) - p = rlebuf; - surface->map->data = p; - } - - return 0; -} - -static Uint32 -getpix_8(Uint8 * srcbuf) -{ - return *srcbuf; -} - -static Uint32 -getpix_16(Uint8 * srcbuf) -{ - return *(Uint16 *) srcbuf; -} - -static Uint32 -getpix_24(Uint8 * srcbuf) -{ -#if SDL_BYTEORDER == SDL_LIL_ENDIAN - return srcbuf[0] + (srcbuf[1] << 8) + (srcbuf[2] << 16); -#else - return (srcbuf[0] << 16) + (srcbuf[1] << 8) + srcbuf[2]; -#endif -} - -static Uint32 -getpix_32(Uint8 * srcbuf) -{ - return *(Uint32 *) srcbuf; -} - -typedef Uint32(*getpix_func) (Uint8 *); - -static const getpix_func getpixes[4] = { - getpix_8, getpix_16, getpix_24, getpix_32 -}; - -static int -RLEColorkeySurface(SDL_Surface * surface) -{ - Uint8 *rlebuf, *dst; - int maxn; - int y; - Uint8 *srcbuf, *lastline; - int maxsize = 0; - int bpp = surface->format->BytesPerPixel; - getpix_func getpix; - Uint32 ckey, rgbmask; - int w, h; - - /* calculate the worst case size for the compressed surface */ - switch (bpp) { - case 1: - /* worst case is alternating opaque and transparent pixels, - starting with an opaque pixel */ - maxsize = surface->h * 3 * (surface->w / 2 + 1) + 2; - break; - case 2: - case 3: - /* worst case is solid runs, at most 255 pixels wide */ - maxsize = surface->h * (2 * (surface->w / 255 + 1) - + surface->w * bpp) + 2; - break; - case 4: - /* worst case is solid runs, at most 65535 pixels wide */ - maxsize = surface->h * (4 * (surface->w / 65535 + 1) - + surface->w * 4) + 4; - break; - } - - rlebuf = (Uint8 *) SDL_malloc(maxsize); - if (rlebuf == NULL) { - return SDL_OutOfMemory(); - } - - /* Set up the conversion */ - srcbuf = (Uint8 *) surface->pixels; - maxn = bpp == 4 ? 65535 : 255; - dst = rlebuf; - rgbmask = ~surface->format->Amask; - ckey = surface->map->info.colorkey & rgbmask; - lastline = dst; - getpix = getpixes[bpp - 1]; - w = surface->w; - h = surface->h; - -#define ADD_COUNTS(n, m) \ - if(bpp == 4) { \ - ((Uint16 *)dst)[0] = n; \ - ((Uint16 *)dst)[1] = m; \ - dst += 4; \ - } else { \ - dst[0] = n; \ - dst[1] = m; \ - dst += 2; \ - } - - for (y = 0; y < h; y++) { - int x = 0; - int blankline = 0; - do { - int run, skip, len; - int runstart; - int skipstart = x; - - /* find run of transparent, then opaque pixels */ - while (x < w && (getpix(srcbuf + x * bpp) & rgbmask) == ckey) - x++; - runstart = x; - while (x < w && (getpix(srcbuf + x * bpp) & rgbmask) != ckey) - x++; - skip = runstart - skipstart; - if (skip == w) - blankline = 1; - run = x - runstart; - - /* encode segment */ - while (skip > maxn) { - ADD_COUNTS(maxn, 0); - skip -= maxn; - } - len = MIN(run, maxn); - ADD_COUNTS(skip, len); - SDL_memcpy(dst, srcbuf + runstart * bpp, len * bpp); - dst += len * bpp; - run -= len; - runstart += len; - while (run) { - len = MIN(run, maxn); - ADD_COUNTS(0, len); - SDL_memcpy(dst, srcbuf + runstart * bpp, len * bpp); - dst += len * bpp; - runstart += len; - run -= len; - } - if (!blankline) - lastline = dst; - } while (x < w); - - srcbuf += surface->pitch; - } - dst = lastline; /* back up bast trailing blank lines */ - ADD_COUNTS(0, 0); - -#undef ADD_COUNTS - - /* Now that we have it encoded, release the original pixels */ - if (!(surface->flags & SDL_PREALLOC)) { - SDL_free(surface->pixels); - surface->pixels = NULL; - } - - /* realloc the buffer to release unused memory */ - { - /* If realloc returns NULL, the original block is left intact */ - Uint8 *p = SDL_realloc(rlebuf, dst - rlebuf); - if (!p) - p = rlebuf; - surface->map->data = p; - } - - return (0); -} - -int -SDL_RLESurface(SDL_Surface * surface) -{ - int flags; - - /* Clear any previous RLE conversion */ - if ((surface->flags & SDL_RLEACCEL) == SDL_RLEACCEL) { - SDL_UnRLESurface(surface, 1); - } - - /* We don't support RLE encoding of bitmaps */ - if (surface->format->BitsPerPixel < 8) { - return -1; - } - - /* Make sure the pixels are available */ - if (!surface->pixels) { - return -1; - } - - /* If we don't have colorkey or blending, nothing to do... */ - flags = surface->map->info.flags; - if (!(flags & (SDL_COPY_COLORKEY | SDL_COPY_BLEND))) { - return -1; - } - - /* Pass on combinations not supported */ - if ((flags & SDL_COPY_MODULATE_COLOR) || - ((flags & SDL_COPY_MODULATE_ALPHA) && surface->format->Amask) || - (flags & (SDL_COPY_ADD | SDL_COPY_MOD)) || - (flags & SDL_COPY_NEAREST)) { - return -1; - } - - /* Encode and set up the blit */ - if (!surface->format->Amask || !(flags & SDL_COPY_BLEND)) { - if (!surface->map->identity) { - return -1; - } - if (RLEColorkeySurface(surface) < 0) { - return -1; - } - surface->map->blit = SDL_RLEBlit; - surface->map->info.flags |= SDL_COPY_RLE_COLORKEY; - } else { - if (RLEAlphaSurface(surface) < 0) { - return -1; - } - surface->map->blit = SDL_RLEAlphaBlit; - surface->map->info.flags |= SDL_COPY_RLE_ALPHAKEY; - } - - /* The surface is now accelerated */ - surface->flags |= SDL_RLEACCEL; - - return (0); -} - -/* - * Un-RLE a surface with pixel alpha - * This may not give back exactly the image before RLE-encoding; all - * completely transparent pixels will be lost, and color and alpha depth - * may have been reduced (when encoding for 16bpp targets). - */ -static SDL_bool -UnRLEAlpha(SDL_Surface * surface) -{ - Uint8 *srcbuf; - Uint32 *dst; - SDL_PixelFormat *sf = surface->format; - RLEDestFormat *df = surface->map->data; - int (*uncopy_opaque) (Uint32 *, void *, int, - RLEDestFormat *, SDL_PixelFormat *); - int (*uncopy_transl) (Uint32 *, void *, int, - RLEDestFormat *, SDL_PixelFormat *); - int w = surface->w; - int bpp = df->BytesPerPixel; - - if (bpp == 2) { - uncopy_opaque = uncopy_opaque_16; - uncopy_transl = uncopy_transl_16; - } else { - uncopy_opaque = uncopy_transl = uncopy_32; - } - - surface->pixels = SDL_malloc(surface->h * surface->pitch); - if (!surface->pixels) { - return (SDL_FALSE); - } - /* fill background with transparent pixels */ - SDL_memset(surface->pixels, 0, surface->h * surface->pitch); - - dst = surface->pixels; - srcbuf = (Uint8 *) (df + 1); - for (;;) { - /* copy opaque pixels */ - int ofs = 0; - do { - unsigned run; - if (bpp == 2) { - ofs += srcbuf[0]; - run = srcbuf[1]; - srcbuf += 2; - } else { - ofs += ((Uint16 *) srcbuf)[0]; - run = ((Uint16 *) srcbuf)[1]; - srcbuf += 4; - } - if (run) { - srcbuf += uncopy_opaque(dst + ofs, srcbuf, run, df, sf); - ofs += run; - } else if (!ofs) - return (SDL_TRUE); - } while (ofs < w); - - /* skip padding if needed */ - if (bpp == 2) - srcbuf += (uintptr_t) srcbuf & 2; - - /* copy translucent pixels */ - ofs = 0; - do { - unsigned run; - ofs += ((Uint16 *) srcbuf)[0]; - run = ((Uint16 *) srcbuf)[1]; - srcbuf += 4; - if (run) { - srcbuf += uncopy_transl(dst + ofs, srcbuf, run, df, sf); - ofs += run; - } - } while (ofs < w); - dst += surface->pitch >> 2; - } - /* Make the compiler happy */ - return (SDL_TRUE); -} - -void -SDL_UnRLESurface(SDL_Surface * surface, int recode) -{ - if (surface->flags & SDL_RLEACCEL) { - surface->flags &= ~SDL_RLEACCEL; - - if (recode && !(surface->flags & SDL_PREALLOC)) { - if (surface->map->info.flags & SDL_COPY_RLE_COLORKEY) { - SDL_Rect full; - - /* re-create the original surface */ - surface->pixels = SDL_malloc(surface->h * surface->pitch); - if (!surface->pixels) { - /* Oh crap... */ - surface->flags |= SDL_RLEACCEL; - return; - } - - /* fill it with the background color */ - SDL_FillRect(surface, NULL, surface->map->info.colorkey); - - /* now render the encoded surface */ - full.x = full.y = 0; - full.w = surface->w; - full.h = surface->h; - SDL_RLEBlit(surface, &full, surface, &full); - } else { - if (!UnRLEAlpha(surface)) { - /* Oh crap... */ - surface->flags |= SDL_RLEACCEL; - return; - } - } - } - surface->map->info.flags &= - ~(SDL_COPY_RLE_COLORKEY | SDL_COPY_RLE_ALPHAKEY); - - SDL_free(surface->map->data); - surface->map->data = NULL; - } -} - -/* vi: set ts=4 sw=4 expandtab: */ |