|
|
|
|
@@ -878,23 +878,6 @@ static int copy_opaque_16(void *dst, const Uint32 *src, int n,
|
|
|
|
|
return n * 2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// decode opaque pixels from 16bpp to 32bpp rgb + a
|
|
|
|
|
static int uncopy_opaque_16(Uint32 *dst, const void *src, int n,
|
|
|
|
|
const SDL_PixelFormatDetails *sfmt, const SDL_PixelFormatDetails *dfmt)
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
const Uint16 *s = (const Uint16 *)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, const Uint32 *src, int n,
|
|
|
|
|
const SDL_PixelFormatDetails *sfmt, const SDL_PixelFormatDetails *dfmt)
|
|
|
|
|
@@ -931,24 +914,6 @@ static int copy_transl_555(void *dst, const Uint32 *src, int n,
|
|
|
|
|
return n * 4;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// decode translucent pixels from 32bpp GORAB to 32bpp rgb + a
|
|
|
|
|
static int uncopy_transl_16(Uint32 *dst, const void *src, int n,
|
|
|
|
|
const SDL_PixelFormatDetails *sfmt, const SDL_PixelFormatDetails *dfmt)
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
const Uint32 *s = (const Uint32 *)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, const Uint32 *src, int n,
|
|
|
|
|
const SDL_PixelFormatDetails *sfmt, const SDL_PixelFormatDetails *dfmt)
|
|
|
|
|
@@ -965,23 +930,6 @@ static int copy_32(void *dst, const Uint32 *src, int n,
|
|
|
|
|
return n * 4;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// decode 32bpp rgba into 32bpp rgba, keeping alpha (dual purpose)
|
|
|
|
|
static int uncopy_32(Uint32 *dst, const void *src, int n,
|
|
|
|
|
const SDL_PixelFormatDetails *sfmt, const SDL_PixelFormatDetails *dfmt)
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
const Uint32 *s = (const Uint32 *)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) \
|
|
|
|
|
@@ -1177,17 +1125,6 @@ static bool RLEAlphaSurface(SDL_Surface *surface)
|
|
|
|
|
#undef ADD_OPAQUE_COUNTS
|
|
|
|
|
#undef ADD_TRANSL_COUNTS
|
|
|
|
|
|
|
|
|
|
// Now that we have it encoded, release the original pixels
|
|
|
|
|
if (!(surface->flags & SDL_SURFACE_PREALLOCATED)) {
|
|
|
|
|
if (surface->flags & SDL_SURFACE_SIMD_ALIGNED) {
|
|
|
|
|
SDL_aligned_free(surface->pixels);
|
|
|
|
|
surface->flags &= ~SDL_SURFACE_SIMD_ALIGNED;
|
|
|
|
|
} else {
|
|
|
|
|
SDL_free(surface->pixels);
|
|
|
|
|
}
|
|
|
|
|
surface->pixels = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// reallocate the buffer to release unused memory
|
|
|
|
|
{
|
|
|
|
|
Uint8 *p = (Uint8 *)SDL_realloc(rlebuf, dst - rlebuf);
|
|
|
|
|
@@ -1353,17 +1290,6 @@ static bool RLEColorkeySurface(SDL_Surface *surface)
|
|
|
|
|
|
|
|
|
|
#undef ADD_COUNTS
|
|
|
|
|
|
|
|
|
|
// Now that we have it encoded, release the original pixels
|
|
|
|
|
if (!(surface->flags & SDL_SURFACE_PREALLOCATED)) {
|
|
|
|
|
if (surface->flags & SDL_SURFACE_SIMD_ALIGNED) {
|
|
|
|
|
SDL_aligned_free(surface->pixels);
|
|
|
|
|
surface->flags &= ~SDL_SURFACE_SIMD_ALIGNED;
|
|
|
|
|
} else {
|
|
|
|
|
SDL_free(surface->pixels);
|
|
|
|
|
}
|
|
|
|
|
surface->pixels = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// reallocate the buffer to release unused memory
|
|
|
|
|
{
|
|
|
|
|
// If SDL_realloc returns NULL, the original block is left intact
|
|
|
|
|
@@ -1383,7 +1309,7 @@ bool SDL_RLESurface(SDL_Surface *surface)
|
|
|
|
|
|
|
|
|
|
// Clear any previous RLE conversion
|
|
|
|
|
if (surface->internal_flags & SDL_INTERNAL_SURFACE_RLEACCEL) {
|
|
|
|
|
SDL_UnRLESurface(surface, true);
|
|
|
|
|
SDL_UnRLESurface(surface);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// We don't support RLE encoding of bitmaps
|
|
|
|
|
@@ -1432,6 +1358,11 @@ bool SDL_RLESurface(SDL_Surface *surface)
|
|
|
|
|
surface->map.info.flags |= SDL_COPY_RLE_ALPHAKEY;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!(surface->flags & SDL_SURFACE_PREALLOCATED)) {
|
|
|
|
|
surface->saved_pixels = surface->pixels;
|
|
|
|
|
surface->pixels = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// The surface is now accelerated
|
|
|
|
|
surface->internal_flags |= SDL_INTERNAL_SURFACE_RLEACCEL;
|
|
|
|
|
SDL_UpdateSurfaceLockFlag(surface);
|
|
|
|
|
@@ -1439,135 +1370,18 @@ bool SDL_RLESurface(SDL_Surface *surface)
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* 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 bool UnRLEAlpha(SDL_Surface *surface)
|
|
|
|
|
{
|
|
|
|
|
Uint8 *srcbuf;
|
|
|
|
|
Uint32 *dst;
|
|
|
|
|
const SDL_PixelFormatDetails *sf = surface->fmt;
|
|
|
|
|
const SDL_PixelFormatDetails *df = SDL_GetPixelFormatDetails(*(SDL_PixelFormat *)surface->map.data);
|
|
|
|
|
int (*uncopy_opaque)(Uint32 *, const void *, int,
|
|
|
|
|
const SDL_PixelFormatDetails *, const SDL_PixelFormatDetails *);
|
|
|
|
|
int (*uncopy_transl)(Uint32 *, const void *, int,
|
|
|
|
|
const SDL_PixelFormatDetails *, const SDL_PixelFormatDetails *);
|
|
|
|
|
int w = surface->w;
|
|
|
|
|
int bpp = df->bytes_per_pixel;
|
|
|
|
|
size_t size;
|
|
|
|
|
|
|
|
|
|
if (bpp == 2) {
|
|
|
|
|
uncopy_opaque = uncopy_opaque_16;
|
|
|
|
|
uncopy_transl = uncopy_transl_16;
|
|
|
|
|
} else {
|
|
|
|
|
uncopy_opaque = uncopy_transl = uncopy_32;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!SDL_size_mul_check_overflow(surface->h, surface->pitch, &size)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
surface->pixels = SDL_aligned_alloc(SDL_GetSIMDAlignment(), size);
|
|
|
|
|
if (!surface->pixels) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
surface->flags |= SDL_SURFACE_SIMD_ALIGNED;
|
|
|
|
|
// fill background with transparent pixels
|
|
|
|
|
SDL_memset(surface->pixels, 0, (size_t)surface->h * surface->pitch);
|
|
|
|
|
|
|
|
|
|
dst = (Uint32 *)surface->pixels;
|
|
|
|
|
srcbuf = (Uint8 *)surface->map.data + sizeof(SDL_PixelFormat);
|
|
|
|
|
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) {
|
|
|
|
|
goto end_function;
|
|
|
|
|
}
|
|
|
|
|
} 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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
end_function:
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SDL_UnRLESurface(SDL_Surface *surface, bool recode)
|
|
|
|
|
void SDL_UnRLESurface(SDL_Surface *surface)
|
|
|
|
|
{
|
|
|
|
|
if (surface->internal_flags & SDL_INTERNAL_SURFACE_RLEACCEL) {
|
|
|
|
|
surface->internal_flags &= ~SDL_INTERNAL_SURFACE_RLEACCEL;
|
|
|
|
|
|
|
|
|
|
if (recode && !(surface->flags & SDL_SURFACE_PREALLOCATED)) {
|
|
|
|
|
if (surface->map.info.flags & SDL_COPY_RLE_COLORKEY) {
|
|
|
|
|
SDL_Rect full;
|
|
|
|
|
size_t size;
|
|
|
|
|
|
|
|
|
|
// re-create the original surface
|
|
|
|
|
if (!SDL_size_mul_check_overflow(surface->h, surface->pitch, &size)) {
|
|
|
|
|
// Memory corruption?
|
|
|
|
|
surface->internal_flags |= SDL_INTERNAL_SURFACE_RLEACCEL;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
surface->pixels = SDL_aligned_alloc(SDL_GetSIMDAlignment(), size);
|
|
|
|
|
if (!surface->pixels) {
|
|
|
|
|
// Oh crap...
|
|
|
|
|
surface->internal_flags |= SDL_INTERNAL_SURFACE_RLEACCEL;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
surface->flags |= SDL_SURFACE_SIMD_ALIGNED;
|
|
|
|
|
|
|
|
|
|
// fill it with the background color
|
|
|
|
|
SDL_FillSurfaceRect(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->internal_flags |= SDL_INTERNAL_SURFACE_RLEACCEL;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
surface->map.info.flags &= ~(SDL_COPY_RLE_COLORKEY | SDL_COPY_RLE_ALPHAKEY);
|
|
|
|
|
|
|
|
|
|
if (!(surface->flags & SDL_SURFACE_PREALLOCATED)) {
|
|
|
|
|
surface->pixels = surface->saved_pixels;
|
|
|
|
|
surface->saved_pixels = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SDL_free(surface->map.data);
|
|
|
|
|
surface->map.data = NULL;
|
|
|
|
|
|
|
|
|
|
|