-namespace {
-#define BILINEAR
-
-#ifdef NAIVE
-SDL_Surface *scale(SDL_Surface *src, int numerator, int denominator)
-{
- if(numerator == denominator)
- {
- src->refcount++;
- return src;
- }
- else
- {
- SDL_Surface *dst = SDL_CreateRGBSurface(src->flags, src->w * numerator / denominator, src->h * numerator / denominator, src->format->BitsPerPixel, src->format->Rmask, src->format->Gmask, src->format->Bmask, src->format->Amask);
- int bpp = dst->format->BytesPerPixel;
- if(SDL_MUSTLOCK(src))
- {
- SDL_LockSurface(src);
- }
- if(SDL_MUSTLOCK(dst))
- {
- SDL_LockSurface(dst);
- }
- for(int y = 0;y < dst->h;y++) {
- for(int x = 0;x < dst->w;x++) {
- Uint8 *srcpixel = (Uint8 *) src->pixels + (y * denominator / numerator) * src->pitch + (x * denominator / numerator) * bpp;
- Uint8 *dstpixel = (Uint8 *) dst->pixels + y * dst->pitch + x * bpp;
- switch(bpp) {
- case 4:
- dstpixel[3] = srcpixel[3];
- case 3:
- dstpixel[2] = srcpixel[2];
- case 2:
- dstpixel[1] = srcpixel[1];
- case 1:
- dstpixel[0] = srcpixel[0];
- }
- }
- }
- if(SDL_MUSTLOCK(dst))
- {
- SDL_UnlockSurface(dst);
- }
- if(SDL_MUSTLOCK(src))
- {
- SDL_UnlockSurface(src);
- }
- if(!src->format->Amask)
- {
- if(src->flags & SDL_SRCALPHA)
- {
- SDL_SetAlpha(dst, SDL_SRCALPHA | SDL_RLEACCEL, src->format->alpha);
- }
- if(src->flags & SDL_SRCCOLORKEY)
- {
- SDL_SetColorKey(dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, src->format->colorkey);
- }
- }
- return dst;
- }
-} // namespace
-#endif
-
-#ifdef BILINEAR
-void getpixel(SDL_Surface *src, int srcx, int srcy, Uint8 color[4])
-{
- int bpp = src->format->BytesPerPixel;
- if(srcx == src->w)
- {
- srcx--;
- }
- if(srcy == src->h)
- {
- srcy--;
- }
- Uint8 *srcpixel = (Uint8 *) src->pixels + srcy * src->pitch + srcx * bpp;
- Uint32 mapped = 0;
- switch(bpp) {
- case 1:
- mapped = *srcpixel;
- break;
- case 2:
- mapped = *(Uint16 *)srcpixel;
- break;
- case 3:
-#if SDL_BYTEORDER == SDL_BIG_ENDIAN
- mapped |= srcpixel[0] << 16;
- mapped |= srcpixel[1] << 8;
- mapped |= srcpixel[2] << 0;
-#else
- mapped |= srcpixel[0] << 0;
- mapped |= srcpixel[1] << 8;
- mapped |= srcpixel[2] << 16;
-#endif
- break;
- case 4:
- mapped = *(Uint32 *)srcpixel;
- break;
- }
- SDL_GetRGBA(mapped, src->format, &color[0], &color[1], &color[2], &color[3]);
-}
-
-void merge(Uint8 color[4], Uint8 color0[4], Uint8 color1[4], int rem, int total)
-{
- color[0] = (color0[0] * (total - rem) + color1[0] * rem) / total;
- color[1] = (color0[1] * (total - rem) + color1[1] * rem) / total;
- color[2] = (color0[2] * (total - rem) + color1[2] * rem) / total;
- color[3] = (color0[3] * (total - rem) + color1[3] * rem) / total;
-}
-
-SDL_Surface *scale(SDL_Surface *src, int numerator, int denominator)
-{
- if(numerator == denominator)
- {
- src->refcount++;
- return src;
- }
- else
- {
- SDL_Surface *dst = SDL_CreateRGBSurface(src->flags, src->w * numerator / denominator, src->h * numerator / denominator, src->format->BitsPerPixel, src->format->Rmask, src->format->Gmask, src->format->Bmask, src->format->Amask);
- int bpp = dst->format->BytesPerPixel;
- if(SDL_MUSTLOCK(src))
- {
- SDL_LockSurface(src);
- }
- if(SDL_MUSTLOCK(dst))
- {
- SDL_LockSurface(dst);
- }
- for(int y = 0;y < dst->h;y++) {
- for(int x = 0;x < dst->w;x++) {
- int srcx = x * denominator / numerator;
- int srcy = y * denominator / numerator;
- Uint8 color00[4], color01[4], color10[4], color11[4];
- getpixel(src, srcx, srcy, color00);
- getpixel(src, srcx + 1, srcy, color01);
- getpixel(src, srcx, srcy + 1, color10);
- getpixel(src, srcx + 1, srcy + 1, color11);
- Uint8 color0[4], color1[4], color[4];
- int remx = x * denominator % numerator;
- merge(color0, color00, color01, remx, numerator);
- merge(color1, color10, color11, remx, numerator);
- int remy = y * denominator % numerator;
- merge(color, color0, color1, remy, numerator);
- Uint8 *dstpixel = (Uint8 *) dst->pixels + y * dst->pitch + x * bpp;
- Uint32 mapped = SDL_MapRGBA(dst->format, color[0], color[1], color[2], color[3]);
- switch(bpp) {
- case 1:
- *dstpixel = mapped;
- break;
- case 2:
- *(Uint16 *)dstpixel = mapped;
- break;
- case 3:
-#if SDL_BYTEORDER == SDL_BIG_ENDIAN
- dstpixel[0] = (mapped >> 16) & 0xff;
- dstpixel[1] = (mapped >> 8) & 0xff;
- dstpixel[2] = (mapped >> 0) & 0xff;
-#else
- dstpixel[0] = (mapped >> 0) & 0xff;
- dstpixel[1] = (mapped >> 8) & 0xff;
- dstpixel[2] = (mapped >> 16) & 0xff;
-#endif
- break;
- case 4:
- *(Uint32 *)dstpixel = mapped;
- break;
- }
- }
- }
- if(SDL_MUSTLOCK(dst))
- {
- SDL_UnlockSurface(dst);
- }
- if(SDL_MUSTLOCK(src))
- {
- SDL_UnlockSurface(src);
- }
- if(!src->format->Amask)
- {
- if(src->flags & SDL_SRCALPHA)
- {
- SDL_SetAlpha(dst, SDL_SRCALPHA | SDL_RLEACCEL, src->format->alpha);
- }
- if(src->flags & SDL_SRCCOLORKEY)
- {
- SDL_SetColorKey(dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, src->format->colorkey);
- }
- }
- return dst;
- }
-}
-#endif
-
-SDL_Surface *horz_flip(SDL_Surface *src)
-{
- SDL_Surface *dst = SDL_CreateRGBSurface(src->flags, src->w, src->h, src->format->BitsPerPixel, src->format->Rmask, src->format->Gmask, src->format->Bmask, src->format->Amask);
- int bpp = dst->format->BytesPerPixel;
- if(SDL_MUSTLOCK(src))
- {
- SDL_LockSurface(src);
- }
- if(SDL_MUSTLOCK(dst))
- {
- SDL_LockSurface(dst);
- }
- for(int y = 0;y < dst->h;y++) {
- for(int x = 0;x < dst->w;x++) {
- Uint8 *srcpixel = (Uint8 *) src->pixels + y * src->pitch + x * bpp;
- Uint8 *dstpixel = (Uint8 *) dst->pixels + y * dst->pitch + (dst->w - x - 1) * bpp;
- switch(bpp) {
- case 4:
- dstpixel[3] = srcpixel[3];
- case 3:
- dstpixel[2] = srcpixel[2];
- case 2:
- dstpixel[1] = srcpixel[1];
- case 1:
- dstpixel[0] = srcpixel[0];
- }
- }
- }
- if(SDL_MUSTLOCK(dst))
- {
- SDL_UnlockSurface(dst);
- }
- if(SDL_MUSTLOCK(src))
- {
- SDL_UnlockSurface(src);
- }
- if(!src->format->Amask)
- {
- if(src->flags & SDL_SRCALPHA)
- {
- SDL_SetAlpha(dst, SDL_SRCALPHA | SDL_RLEACCEL, src->format->alpha);
- }
- if(src->flags & SDL_SRCCOLORKEY)
- {
- SDL_SetColorKey(dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, src->format->colorkey);
- }
- }
- return dst;
-}
-
-SDL_Surface *vert_flip(SDL_Surface *src)
-{
- SDL_Surface *dst = SDL_CreateRGBSurface(src->flags, src->w, src->h, src->format->BitsPerPixel, src->format->Rmask, src->format->Gmask, src->format->Bmask, src->format->Amask);
- int bpp = dst->format->BytesPerPixel;
- if(SDL_MUSTLOCK(src))
- {
- SDL_LockSurface(src);
- }
- if(SDL_MUSTLOCK(dst))
- {
- SDL_LockSurface(dst);
- }
- for(int y = 0;y < dst->h;y++) {
- for(int x = 0;x < dst->w;x++) {
- Uint8 *srcpixel = (Uint8 *) src->pixels + y * src->pitch + x * bpp;
- Uint8 *dstpixel = (Uint8 *) dst->pixels + (dst->h - y - 1) * dst->pitch + x * bpp;
- switch(bpp) {
- case 4:
- dstpixel[3] = srcpixel[3];
- case 3:
- dstpixel[2] = srcpixel[2];
- case 2:
- dstpixel[1] = srcpixel[1];
- case 1:
- dstpixel[0] = srcpixel[0];
- }
- }
- }
- if(SDL_MUSTLOCK(dst))
- {
- SDL_UnlockSurface(dst);
- }
- if(SDL_MUSTLOCK(src))
- {
- SDL_UnlockSurface(src);
- }
- if(!src->format->Amask)
- {
- if(src->flags & SDL_SRCALPHA)
- {
- SDL_SetAlpha(dst, SDL_SRCALPHA | SDL_RLEACCEL, src->format->alpha);
- }
- if(src->flags & SDL_SRCCOLORKEY)
- {
- SDL_SetColorKey(dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, src->format->colorkey);
- }
- }
- return dst;
-}
-
-SDL_Surface *colorize(SDL_Surface *src, const Color &color)
-{
- // FIXME: This is really slow
- assert(color.red != 1.0 || color.green != 1.0 || color.blue != 1.0);
- int red = (int) (color.red * 256);
- int green = (int) (color.green * 256);
- int blue = (int) (color.blue * 256);
- SDL_Surface *dst = SDL_CreateRGBSurface(src->flags, src->w, src->h, src->format->BitsPerPixel, src->format->Rmask, src->format->Gmask, src->format->Bmask, src->format->Amask);
- int bpp = dst->format->BytesPerPixel;
- if(SDL_MUSTLOCK(src))
- {
- SDL_LockSurface(src);
- }
- if(SDL_MUSTLOCK(dst))
- {
- SDL_LockSurface(dst);
- }
- for(int y = 0;y < dst->h;y++) {
- for(int x = 0;x < dst->w;x++) {
- Uint8 *srcpixel = (Uint8 *) src->pixels + y * src->pitch + x * bpp;
- Uint8 *dstpixel = (Uint8 *) dst->pixels + y * dst->pitch + x * bpp;
- Uint32 mapped = 0;
- switch(bpp) {
- case 1:
- mapped = *srcpixel;
- break;
- case 2:
- mapped = *(Uint16 *)srcpixel;
- break;
- case 3:
-#if SDL_BYTEORDER == SDL_BIG_ENDIAN
- mapped |= srcpixel[0] << 16;
- mapped |= srcpixel[1] << 8;
- mapped |= srcpixel[2] << 0;
-#else
- mapped |= srcpixel[0] << 0;
- mapped |= srcpixel[1] << 8;
- mapped |= srcpixel[2] << 16;
-#endif
- break;
- case 4:
- mapped = *(Uint32 *)srcpixel;
- break;
- }
- if(src->format->Amask || !(src->flags & SDL_SRCCOLORKEY) || mapped != src->format->colorkey)
- {
- Uint8 r, g, b, a;
- SDL_GetRGBA(mapped, src->format, &r, &g, &b, &a);
- mapped = SDL_MapRGBA(dst->format, (r * red) >> 8, (g * green) >> 8, (b * blue) >> 8, a);
- }
- switch(bpp) {
- case 1:
- *dstpixel = mapped;
- break;
- case 2:
- *(Uint16 *)dstpixel = mapped;
- break;
- case 3:
-#if SDL_BYTEORDER == SDL_BIG_ENDIAN
- dstpixel[0] = (mapped >> 16) & 0xff;
- dstpixel[1] = (mapped >> 8) & 0xff;
- dstpixel[2] = (mapped >> 0) & 0xff;
-#else
- dstpixel[0] = (mapped >> 0) & 0xff;
- dstpixel[1] = (mapped >> 8) & 0xff;
- dstpixel[2] = (mapped >> 16) & 0xff;
-#endif
- break;
- case 4:
- *(Uint32 *)dstpixel = mapped;
- break;
- }
- }
- }
- if(SDL_MUSTLOCK(dst))
- {
- SDL_UnlockSurface(dst);
- }
- if(SDL_MUSTLOCK(src))
- {
- SDL_UnlockSurface(src);
- }
- if(!src->format->Amask)
- {
- if(src->flags & SDL_SRCALPHA)
- {
- SDL_SetAlpha(dst, SDL_SRCALPHA | SDL_RLEACCEL, src->format->alpha);
- }
- if(src->flags & SDL_SRCCOLORKEY)
- {
- SDL_SetColorKey(dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, src->format->colorkey);
- }
- }
- return dst;
-}
-
-SDL_Surface *optimize(SDL_Surface *src)