63 Image(name, surface) {
68 Image(data, width, height) {
73 Image(name, data, width, height) {
102 SDL_Surface* dst, SDL_Rect* dstRect,
uint8_t alpha ) {
107 int32_t screenX, screenY;
109 screenX = dstRect->x;
110 screenY = dstRect->y;
112 screenX = dst->clip_rect.x;
113 screenY = dst->clip_rect.y;
116 int32_t width, height, tX, tY;
123 tX = src->clip_rect.x;
124 tY = src->clip_rect.y;
125 width = src->clip_rect.w;
126 height = src->clip_rect.h;
130 if( ( screenX >= ( dst->clip_rect.x + dst->clip_rect.w ) ) ||
131 ( screenY >= ( dst->clip_rect.y + dst->clip_rect.h ) ) ||
132 ( ( screenX + width ) <= dst->clip_rect.x ) ||
133 ( ( screenY + height ) <= dst->clip_rect.y ) ) {
137 if( screenX < dst->clip_rect.x ) {
138 int32_t dX = dst->clip_rect.x - screenX;
144 if( ( screenX + width ) > ( dst->clip_rect.x + dst->clip_rect.w ) ) {
145 int32_t dX = ( screenX + width ) - ( dst->clip_rect.x + dst->clip_rect.w );
149 if( screenY < dst->clip_rect.y ) {
150 int32_t dY = dst->clip_rect.y - screenY;
156 if( ( screenY + height ) > ( dst->clip_rect.y + dst->clip_rect.h ) ) {
157 int32_t dY = ( screenY + height ) - ( dst->clip_rect.y + dst->clip_rect.h );
161 if( ( 0 >= height ) || ( 0 >= width ) ) {
165 SDL_LockSurface( dst );
171 srcData += tY * src->pitch + tX * src->format->BytesPerPixel;
172 dstData += screenY * dst->pitch + screenX * dst->format->BytesPerPixel;
174 switch( src->format->BitsPerPixel ) {
176 switch( dst->format->BitsPerPixel ) {
178 if( 0xFFFF == ( dst->format->Rmask | dst->format->Gmask | dst->format->Bmask ) ) {
179 for( int32_t y = height; y > 0; --y ) {
181 srcData += src->pitch;
182 dstData += dst->pitch;
189 for( int32_t y = height; y > 0; --y ) {
191 srcData += src->pitch;
192 dstData += dst->pitch;
198 for( int32_t y = height; y > 0; --y ) {
200 srcData += src->pitch;
201 dstData += dst->pitch;
213 if( 0x000F == src->format->Amask ) {
214 if( ( 16 == dst->format->BitsPerPixel ) &&
215 ( 0xFFFF == ( dst->format->Rmask | dst->format->Gmask | dst->format->Bmask ) ) ) {
216 for( int32_t y = height; y > 0; --y ) {
218 srcData += src->pitch;
219 dstData += dst->pitch;
230 SDL_UnlockSurface( dst );
235 uint32_t* src_help_pointer = src_pointer;
238 int32_t x, y, *sx_ca, *sy_ca;
239 int32_t sx =
static_cast<int32_t
>(0xffff * src->w / dst->w);
240 int32_t sy =
static_cast<int32_t
>(0xffff * src->h / dst->h);
245 int32_t* sx_a =
new int32_t[dst->w + 1];
247 for (x = 0; x <= dst->w; x++) {
254 int32_t* sy_a =
new int32_t[dst->h + 1];
256 for (y = 0; y <= dst->h; y++) {
266 if (SDL_MUSTLOCK(src)) {
267 SDL_LockSurface(src);
269 if (SDL_MUSTLOCK(dst)) {
270 SDL_LockSurface(dst);
273 for (y = 0; y < dst->h; y++) {
274 src_pointer = src_help_pointer;
276 for (x = 0; x < dst->w; x++) {
277 *dst_pointer = *src_pointer;
279 src_pointer += (*sx_ca >> 16);
283 src_help_pointer = (
uint32_t*)((
uint8_t*)src_help_pointer + (*sy_ca >> 16) * src->pitch);
286 if (SDL_MUSTLOCK(dst)) {
287 SDL_UnlockSurface(dst);
289 if (SDL_MUSTLOCK(src)) {
290 SDL_UnlockSurface(src);
302 SDL_Surface *zoom_src;
303 SDL_Surface *zoom_dst;
304 int32_t dst_w =
static_cast<int32_t
>(round(src->w * zoomx));
305 int32_t dst_h =
static_cast<int32_t
>(round(src->h * zoomy));
312 if (src->format->Amask == 0) {
313 zoom_src = SDL_CreateRGBSurface(SDL_SWSURFACE, src->w, src->h, 32,
316 SDL_BlitSurface(src, NULL, zoom_src, NULL);
321 zoom_dst = SDL_CreateRGBSurface(SDL_SWSURFACE, dst_w, dst_h, 32,
322 zoom_src->format->Rmask, zoom_src->format->Gmask,
323 zoom_src->format->Bmask, zoom_src->format->Amask);
332 return ABS(a - b) <= 0.00001;
343 if (rect.
right() < 0 || rect.
x >
static_cast<int32_t
>(target->w) ||
344 rect.
bottom() < 0 || rect.
y >
static_cast<int32_t
>(target->h)) {
355 float scale_x =
static_cast<float>(rect.
w) / static_cast<float>(
m_surface->w);
356 float scale_y =
static_cast<float>(rect.
h) / static_cast<float>(
m_surface->h);
374 SDL_SetAlpha(
m_surface, SDL_SRCALPHA | SDL_RLEACCEL, alpha);
377 SDL_BlitSurface(
m_surface, 0, target, &r);
400 SDL_BlitSurface(
m_surface, 0, target, &r);
430 SDL_SetColorKey(
m_surface, SDL_SRCCOLORKEY, key);
437 if( m_isalphaoptimized ) {
440 SDL_SetAlpha(
m_surface, SDL_SRCALPHA, 255);
444 SDL_SetColorKey(
m_surface, SDL_SRCCOLORKEY, key);
450 SDL_FreeSurface(old_surface);
464 int32_t transparent = 0;
466 int32_t semitransparent = 0;
467 int32_t alphasum = 0;
468 int32_t alphasquaresum = 0;
469 bool colors[(1 << 12)];
470 memset(colors, 0, (1 << 12) *
sizeof(
bool));
472 int32_t bpp = src->format->BytesPerPixel;
473 if(SDL_MUSTLOCK(src)) {
474 SDL_LockSurface(src);
480 for(int32_t y = 0;y < src->h;y++) {
481 for(int32_t x = 0;x < src->w;x++) {
482 Uint8 *pixel = (Uint8 *) src->pixels + y * src->pitch + x * bpp;
489 mapped = *(Uint16 *)pixel;
492 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
493 mapped |= pixel[0] << 16;
494 mapped |= pixel[1] << 8;
495 mapped |= pixel[2] << 0;
497 mapped |= pixel[0] << 0;
498 mapped |= pixel[1] << 8;
499 mapped |= pixel[2] << 16;
503 mapped = *(Uint32 *)pixel;
506 Uint8 red, green, blue, alpha;
507 SDL_GetRGBA(mapped, src->format, &red, &green, &blue, &alpha);
510 }
else if (alpha > 240) {
513 alphasquaresum += alpha*alpha;
517 alphasquaresum += alpha*alpha;
521 colors[((red & 0xf0) << 4) | (green & 0xf0) | ((blue & 0xf0) >> 4)] =
true;
525 int32_t avgalpha = (opaque + semitransparent) ? alphasum / (opaque + semitransparent) : 0;
526 int32_t alphavariance = 0;
528 if(SDL_MUSTLOCK(src)) {
529 SDL_UnlockSurface(src);
531 alphasquaresum /= (opaque + semitransparent) ? (opaque + semitransparent) : 1;
532 alphavariance = alphasquaresum - avgalpha*avgalpha;
533 if(semitransparent > ((transparent + opaque + semitransparent) / 8)
534 && alphavariance > 16) {
536 <<
"Trying to alpha-optimize image. FAILED: real alpha usage. "
537 <<
" alphavariance=" << alphavariance
538 <<
" total=" << (transparent + opaque + semitransparent)
539 <<
" semitransparent=" << semitransparent
540 <<
"(" << (
float(semitransparent)/(transparent + opaque + semitransparent))
542 return SDL_DisplayFormatAlpha(src);
546 int32_t keycolor = -1;
547 for(int32_t i = 0;i < (1 << 12);i++) {
554 FL_DBG(
_log,
LMsg(
"sdlimage") <<
"Trying to alpha-optimize image. FAILED: no free color");
555 return SDL_DisplayFormatAlpha(src);
558 SDL_Surface *dst = SDL_CreateRGBSurface((src->flags & ~(SDL_SRCALPHA)) | SDL_SWSURFACE,
560 src->format->BitsPerPixel,
561 src->format->Rmask, src->format->Gmask,
562 src->format->Bmask, 0);
563 bpp = dst->format->BytesPerPixel;
569 key = SDL_MapRGB(dst->format,
570 (((keycolor & 0xf00) >> 4) | 0xf),
571 ((keycolor & 0xf0) | 0xf),
572 (((keycolor & 0xf) << 4) | 0xf));
575 if(SDL_MUSTLOCK(src)) {
576 SDL_LockSurface(src);
578 if(SDL_MUSTLOCK(dst)) {
579 SDL_LockSurface(dst);
581 for(int32_t y = 0;y < dst->h;y++) {
582 for(int32_t x = 0;x < dst->w;x++) {
583 Uint8 *srcpixel = (Uint8 *) src->pixels + y * src->pitch + x * bpp;
584 Uint8 *dstpixel = (Uint8 *) dst->pixels + y * dst->pitch + x * bpp;
591 mapped = *(Uint16 *)srcpixel;
594 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
595 mapped |= srcpixel[0] << 16;
596 mapped |= srcpixel[1] << 8;
597 mapped |= srcpixel[2] << 0;
599 mapped |= srcpixel[0] << 0;
600 mapped |= srcpixel[1] << 8;
601 mapped |= srcpixel[2] << 16;
605 mapped = *(Uint32 *)srcpixel;
608 Uint8 red, green, blue, alpha;
609 SDL_GetRGBA(mapped, src->format, &red, &green, &blue, &alpha);
610 if(alpha < (avgalpha / 4)) {
613 mapped = SDL_MapRGB(dst->format, red, green, blue);
620 *(Uint16 *)dstpixel = mapped;
623 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
624 dstpixel[0] = (mapped >> 16) & 0xff;
625 dstpixel[1] = (mapped >> 8) & 0xff;
626 dstpixel[2] = (mapped >> 0) & 0xff;
628 dstpixel[0] = (mapped >> 0) & 0xff;
629 dstpixel[1] = (mapped >> 8) & 0xff;
630 dstpixel[2] = (mapped >> 16) & 0xff;
634 *(Uint32 *)dstpixel = mapped;
639 if(SDL_MUSTLOCK(dst)) {
640 SDL_UnlockSurface(dst);
642 if(SDL_MUSTLOCK(src)) {
643 SDL_UnlockSurface(src);
652 SDL_SetColorKey(dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, key);
653 SDL_Surface *convert = SDL_DisplayFormat(dst);
654 SDL_FreeSurface(dst);
656 <<
"Trying to alpha-optimize image. SUCCESS: colorkey is " << key);
676 SDL_Surface* src_surface = shared->
getSurface();
677 SDL_Surface* surface = SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_SRCALPHA, region.
w, region.
h,
678 src_surface->format->BitsPerPixel, src_surface->format->Rmask, src_surface->format->Gmask,
679 src_surface->format->Bmask, src_surface->format->Amask);
681 SDL_SetAlpha(src_surface, 0, 0);
682 SDL_Rect srcrect = { region.
x, region.
y, region.
w, region.
h };
683 SDL_BlitSurface(src_surface, &srcrect, surface, NULL);
684 SDL_SetAlpha(src_surface, SDL_SRCALPHA, 0);
virtual ImagePtr create(IResourceLoader *loader=0)
Creates a blank Image but does not load it immediately.
void SDL_BlendRow_RGBA8_to_RGB8(const uint8_t *src, uint8_t *dst, uint32_t alpha, int32_t n)
Blends one row of n pixels from src with n pixels of dst.
void SDL_BlendRow_RGBA8_to_RGBA8(const uint8_t *src, uint8_t *dst, uint32_t alpha, int32_t n)
Blends one row of n pixels from src with n pixels of dst.
void reset(SDL_Surface *surface)
Resets the image to default values (including the x and y shift values), frees the current surface an...
virtual bool exists(const std::string &name)
Checks to see if an Image exists.
virtual ResourceState getState()
SDL_Surface * getZoomedSurface(SDL_Surface *src, double zoomx, double zoomy)
T h
Height of the rectangle.
Helper class to create log strings out from separate parts Usage: LMsg("some text") << variable << "...
The main class of the SDL-based renderer.
void zoomSurface(SDL_Surface *src, SDL_Surface *dst)
static Logger _log(LM_AUDIO)
void SDL_BlitSurfaceWithAlpha(const SDL_Surface *src, const SDL_Rect *srcRect, SDL_Surface *dst, SDL_Rect *dstRect, uint8_t alpha)
static RenderBackend * instance()
virtual void render(const Rect &rect, uint8_t alpha=255, uint8_t const *rgb=0)
Renders itself to the current render target (main screen or attached destination image) at the rectan...
T bottom() const
The Y coordinate of the bottom edge.
SDL_Surface * getSurface()
const SDL_Color & getColorKey() const
Gets the global colorkey setting.
virtual const std::string & getName()
SDL_Surface * m_zoom_surface
void SDL_BlendRow_RGBA4_to_RGB565(const uint8_t *src, uint8_t *dst, uint32_t alpha, int32_t n)
Blends one row of n pixels from src with n pixels of dst.
T right() const
The X coordinate of the right edge.
virtual void setState(const ResourceState &state)
SDL_Surface * getRenderTargetSurface()
Returns currently attached render surface.
bool nearlyEqual(float a, float b)
virtual void forceLoadInternal()
Forces to load the image into internal memory of GPU.
virtual void setSurface(SDL_Surface *surface)
This frees the current suface and replaces it with the surface passed in the parameter (which can be ...
void SDL_BlendRow_RGBA8_to_RGB565(const uint8_t *src, uint8_t *dst, uint32_t alpha, int32_t n)
Blends one row of n pixels from src with n pixels of dst.
SDLImage(IResourceLoader *loader=0)
virtual void useSharedImage(const ImagePtr &shared, const Rect ®ion)
After this call all image data will be taken from the given image and its subregion.
T w
Width of the rectangle.
#define FL_DBG(logger, msg)
SDL_Surface * optimize(SDL_Surface *surface)
SDL Alpha Optimizer This tries to convert an image with a fake alpha channel to an RGB image when the...
bool isAlphaOptimizerEnabled() const