SDL  2.0
SDL_RLEaccel_c.h File Reference
#include "../SDL_internal.h"
+ Include dependency graph for SDL_RLEaccel_c.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

int SDL_RLESurface (SDL_Surface *surface)
 
int SDL_RLEBlit (SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect)
 
int SDL_RLEAlphaBlit (SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect)
 
void SDL_UnRLESurface (SDL_Surface *surface, int recode)
 

Function Documentation

◆ SDL_RLEAlphaBlit()

int SDL_RLEAlphaBlit ( SDL_Surface src,
SDL_Rect srcrect,
SDL_Surface dst,
SDL_Rect dstrect 
)

Definition at line 727 of file SDL_RLEaccel.c.

References BLIT_TRANSL_555, BLIT_TRANSL_565, BLIT_TRANSL_888, SDL_PixelFormat::Bmask, SDL_PixelFormat::BytesPerPixel, SDL_BlitMap::data, done, SDL_Surface::format, SDL_PixelFormat::Gmask, SDL_Surface::map, SDL_Surface::pitch, SDL_Surface::pixels, RLEALPHABLIT, RLEAlphaClipBlit(), SDL_PixelFormat::Rmask, SDL_LockSurface, SDL_MUSTLOCK, SDL_UnlockSurface, SDL_Rect::w, SDL_Surface::w, SDL_Rect::x, and SDL_Rect::y.

Referenced by SDL_RLESurface().

729 {
730  int x, y;
731  int w = surf_src->w;
732  Uint8 *srcbuf, *dstbuf;
733  SDL_PixelFormat *df = surf_dst->format;
734 
735  /* Lock the destination if necessary */
736  if (SDL_MUSTLOCK(surf_dst)) {
737  if (SDL_LockSurface(surf_dst) < 0) {
738  return -1;
739  }
740  }
741 
742  x = dstrect->x;
743  y = dstrect->y;
744  dstbuf = (Uint8 *) surf_dst->pixels + y * surf_dst->pitch + x * df->BytesPerPixel;
745  srcbuf = (Uint8 *) surf_src->map->data + sizeof(RLEDestFormat);
746 
747  {
748  /* skip lines at the top if necessary */
749  int vskip = srcrect->y;
750  if (vskip) {
751  int ofs;
752  if (df->BytesPerPixel == 2) {
753  /* the 16/32 interleaved format */
754  do {
755  /* skip opaque line */
756  ofs = 0;
757  do {
758  int run;
759  ofs += srcbuf[0];
760  run = srcbuf[1];
761  srcbuf += 2;
762  if (run) {
763  srcbuf += 2 * run;
764  ofs += run;
765  } else if (!ofs)
766  goto done;
767  } while (ofs < w);
768 
769  /* skip padding */
770  srcbuf += (uintptr_t) srcbuf & 2;
771 
772  /* skip translucent line */
773  ofs = 0;
774  do {
775  int run;
776  ofs += ((Uint16 *) srcbuf)[0];
777  run = ((Uint16 *) srcbuf)[1];
778  srcbuf += 4 * (run + 1);
779  ofs += run;
780  } while (ofs < w);
781  } while (--vskip);
782  } else {
783  /* the 32/32 interleaved format */
784  vskip <<= 1; /* opaque and translucent have same format */
785  do {
786  ofs = 0;
787  do {
788  int run;
789  ofs += ((Uint16 *) srcbuf)[0];
790  run = ((Uint16 *) srcbuf)[1];
791  srcbuf += 4;
792  if (run) {
793  srcbuf += 4 * run;
794  ofs += run;
795  } else if (!ofs)
796  goto done;
797  } while (ofs < w);
798  } while (--vskip);
799  }
800  }
801  }
802 
803  /* if left or right edge clipping needed, call clip blit */
804  if (srcrect->x || srcrect->w != surf_src->w) {
805  RLEAlphaClipBlit(w, srcbuf, surf_dst, dstbuf, srcrect);
806  } else {
807 
808  /*
809  * non-clipped blitter. Ptype is the destination pixel type,
810  * Ctype the translucent count type, and do_blend the
811  * macro to blend one pixel.
812  */
813 #define RLEALPHABLIT(Ptype, Ctype, do_blend) \
814  do { \
815  int linecount = srcrect->h; \
816  do { \
817  int ofs = 0; \
818  /* blit opaque pixels on one line */ \
819  do { \
820  unsigned run; \
821  ofs += ((Ctype *)srcbuf)[0]; \
822  run = ((Ctype *)srcbuf)[1]; \
823  srcbuf += 2 * sizeof(Ctype); \
824  if(run) { \
825  PIXEL_COPY(dstbuf + ofs * sizeof(Ptype), srcbuf, \
826  run, sizeof(Ptype)); \
827  srcbuf += run * sizeof(Ptype); \
828  ofs += run; \
829  } else if(!ofs) \
830  goto done; \
831  } while(ofs < w); \
832  /* skip padding if necessary */ \
833  if(sizeof(Ptype) == 2) \
834  srcbuf += (uintptr_t)srcbuf & 2; \
835  /* blit translucent pixels on the same line */ \
836  ofs = 0; \
837  do { \
838  unsigned run; \
839  ofs += ((Uint16 *)srcbuf)[0]; \
840  run = ((Uint16 *)srcbuf)[1]; \
841  srcbuf += 4; \
842  if(run) { \
843  Ptype *dst = (Ptype *)dstbuf + ofs; \
844  unsigned i; \
845  for(i = 0; i < run; i++) { \
846  Uint32 src = *(Uint32 *)srcbuf; \
847  do_blend(src, *dst); \
848  srcbuf += 4; \
849  dst++; \
850  } \
851  ofs += run; \
852  } \
853  } while(ofs < w); \
854  dstbuf += surf_dst->pitch; \
855  } while(--linecount); \
856  } while(0)
857 
858  switch (df->BytesPerPixel) {
859  case 2:
860  if (df->Gmask == 0x07e0 || df->Rmask == 0x07e0
861  || df->Bmask == 0x07e0)
863  else
865  break;
866  case 4:
868  break;
869  }
870  }
871 
872  done:
873  /* Unlock the destination if necessary */
874  if (SDL_MUSTLOCK(surf_dst)) {
875  SDL_UnlockSurface(surf_dst);
876  }
877  return 0;
878 }
#define SDL_UnlockSurface
#define BLIT_TRANSL_555(src, dst)
Definition: SDL_RLEaccel.c:601
GLint GLint GLint GLint GLint x
Definition: SDL_opengl.h:1574
Uint8 BytesPerPixel
Definition: SDL_pixels.h:320
uint32_t Uint32
Definition: SDL_stdinc.h:181
static void RLEAlphaClipBlit(int w, Uint8 *srcbuf, SDL_Surface *surf_dst, Uint8 *dstbuf, SDL_Rect *srcrect)
Definition: SDL_RLEaccel.c:635
uint8_t Uint8
Definition: SDL_stdinc.h:157
int done
Definition: checkkeys.c:28
GLubyte GLubyte GLubyte GLubyte w
unsigned int uintptr_t
GLint GLint GLint GLint GLint GLint y
Definition: SDL_opengl.h:1574
int x
Definition: SDL_rect.h:66
int w
Definition: SDL_rect.h:67
#define SDL_LockSurface
#define RLEALPHABLIT(Ptype, Ctype, do_blend)
#define SDL_MUSTLOCK(S)
Definition: SDL_surface.h:61
#define BLIT_TRANSL_565(src, dst)
Definition: SDL_RLEaccel.c:589
#define BLIT_TRANSL_888(src, dst)
Definition: SDL_RLEaccel.c:571
uint16_t Uint16
Definition: SDL_stdinc.h:169
int y
Definition: SDL_rect.h:66

◆ SDL_RLEBlit()

int SDL_RLEBlit ( SDL_Surface src,
SDL_Rect srcrect,
SDL_Surface dst,
SDL_Rect dstrect 
)

Definition at line 449 of file SDL_RLEaccel.c.

References SDL_BlitInfo::a, SDL_PixelFormat::BytesPerPixel, CHOOSE_BLIT, SDL_BlitMap::data, done, SDL_Surface::format, SDL_BlitMap::info, SDL_Surface::map, SDL_Surface::pitch, SDL_Surface::pixels, RLEBLIT, RLEClipBlit(), RLESKIP, SDL_LockSurface, SDL_MUSTLOCK, SDL_UnlockSurface, SDL_Rect::w, SDL_Surface::w, SDL_Rect::x, and SDL_Rect::y.

Referenced by SDL_RLESurface(), and SDL_UnRLESurface().

451 {
452  Uint8 *dstbuf;
453  Uint8 *srcbuf;
454  int x, y;
455  int w = surf_src->w;
456  unsigned alpha;
457 
458  /* Lock the destination if necessary */
459  if (SDL_MUSTLOCK(surf_dst)) {
460  if (SDL_LockSurface(surf_dst) < 0) {
461  return (-1);
462  }
463  }
464 
465  /* Set up the source and destination pointers */
466  x = dstrect->x;
467  y = dstrect->y;
468  dstbuf = (Uint8 *) surf_dst->pixels
469  + y * surf_dst->pitch + x * surf_src->format->BytesPerPixel;
470  srcbuf = (Uint8 *) surf_src->map->data;
471 
472  {
473  /* skip lines at the top if necessary */
474  int vskip = srcrect->y;
475  int ofs = 0;
476  if (vskip) {
477 
478 #define RLESKIP(bpp, Type) \
479  for(;;) { \
480  int run; \
481  ofs += *(Type *)srcbuf; \
482  run = ((Type *)srcbuf)[1]; \
483  srcbuf += sizeof(Type) * 2; \
484  if(run) { \
485  srcbuf += run * bpp; \
486  ofs += run; \
487  } else if(!ofs) \
488  goto done; \
489  if(ofs == w) { \
490  ofs = 0; \
491  if(!--vskip) \
492  break; \
493  } \
494  }
495 
496  switch (surf_src->format->BytesPerPixel) {
497  case 1:
498  RLESKIP(1, Uint8);
499  break;
500  case 2:
501  RLESKIP(2, Uint8);
502  break;
503  case 3:
504  RLESKIP(3, Uint8);
505  break;
506  case 4:
507  RLESKIP(4, Uint16);
508  break;
509  }
510 
511 #undef RLESKIP
512 
513  }
514  }
515 
516  alpha = surf_src->map->info.a;
517  /* if left or right edge clipping needed, call clip blit */
518  if (srcrect->x || srcrect->w != surf_src->w) {
519  RLEClipBlit(w, srcbuf, surf_dst, dstbuf, srcrect, alpha);
520  } else {
521  SDL_PixelFormat *fmt = surf_src->format;
522 
523 #define RLEBLIT(bpp, Type, do_blit) \
524  do { \
525  int linecount = srcrect->h; \
526  int ofs = 0; \
527  for(;;) { \
528  unsigned run; \
529  ofs += *(Type *)srcbuf; \
530  run = ((Type *)srcbuf)[1]; \
531  srcbuf += 2 * sizeof(Type); \
532  if(run) { \
533  do_blit(dstbuf + ofs * bpp, srcbuf, run, bpp, alpha); \
534  srcbuf += run * bpp; \
535  ofs += run; \
536  } else if(!ofs) \
537  break; \
538  if(ofs == w) { \
539  ofs = 0; \
540  dstbuf += surf_dst->pitch; \
541  if(!--linecount) \
542  break; \
543  } \
544  } \
545  } while(0)
546 
547  CHOOSE_BLIT(RLEBLIT, alpha, fmt);
548 
549 #undef RLEBLIT
550  }
551 
552  done:
553  /* Unlock the destination if necessary */
554  if (SDL_MUSTLOCK(surf_dst)) {
555  SDL_UnlockSurface(surf_dst);
556  }
557  return (0);
558 }
#define CHOOSE_BLIT(blitter, alpha, fmt)
Definition: SDL_RLEaccel.c:303
#define SDL_UnlockSurface
GLint GLint GLint GLint GLint x
Definition: SDL_opengl.h:1574
GLfloat GLfloat GLfloat alpha
uint8_t Uint8
Definition: SDL_stdinc.h:157
int done
Definition: checkkeys.c:28
GLubyte GLubyte GLubyte GLubyte w
#define RLESKIP(bpp, Type)
GLint GLint GLint GLint GLint GLint y
Definition: SDL_opengl.h:1574
int x
Definition: SDL_rect.h:66
static void RLEClipBlit(int w, Uint8 *srcbuf, SDL_Surface *surf_dst, Uint8 *dstbuf, SDL_Rect *srcrect, unsigned alpha)
Definition: SDL_RLEaccel.c:390
int w
Definition: SDL_rect.h:67
#define SDL_LockSurface
#define SDL_MUSTLOCK(S)
Definition: SDL_surface.h:61
uint16_t Uint16
Definition: SDL_stdinc.h:169
int y
Definition: SDL_rect.h:66
#define RLEBLIT(bpp, Type, do_blit)

◆ SDL_RLESurface()

int SDL_RLESurface ( SDL_Surface surface)

Definition at line 1403 of file SDL_RLEaccel.c.

References SDL_PixelFormat::Amask, SDL_PixelFormat::BitsPerPixel, SDL_BlitMap::blit, SDL_BlitInfo::flags, SDL_Surface::flags, SDL_Surface::format, SDL_BlitMap::identity, SDL_BlitMap::info, SDL_Surface::map, SDL_Surface::pixels, RLEAlphaSurface(), RLEColorkeySurface(), SDL_COPY_ADD, SDL_COPY_BLEND, SDL_COPY_COLORKEY, SDL_COPY_MOD, SDL_COPY_MODULATE_ALPHA, SDL_COPY_MODULATE_COLOR, SDL_COPY_NEAREST, SDL_COPY_RLE_ALPHAKEY, SDL_COPY_RLE_COLORKEY, SDL_RLEACCEL, SDL_RLEAlphaBlit(), SDL_RLEBlit(), and SDL_UnRLESurface().

Referenced by SDL_CalculateBlit(), and SDL_UnlockSurface().

1404 {
1405  int flags;
1406 
1407  /* Clear any previous RLE conversion */
1408  if ((surface->flags & SDL_RLEACCEL) == SDL_RLEACCEL) {
1409  SDL_UnRLESurface(surface, 1);
1410  }
1411 
1412  /* We don't support RLE encoding of bitmaps */
1413  if (surface->format->BitsPerPixel < 8) {
1414  return -1;
1415  }
1416 
1417  /* Make sure the pixels are available */
1418  if (!surface->pixels) {
1419  return -1;
1420  }
1421 
1422  /* If we don't have colorkey or blending, nothing to do... */
1423  flags = surface->map->info.flags;
1424  if (!(flags & (SDL_COPY_COLORKEY | SDL_COPY_BLEND))) {
1425  return -1;
1426  }
1427 
1428  /* Pass on combinations not supported */
1429  if ((flags & SDL_COPY_MODULATE_COLOR) ||
1430  ((flags & SDL_COPY_MODULATE_ALPHA) && surface->format->Amask) ||
1431  (flags & (SDL_COPY_ADD | SDL_COPY_MOD)) ||
1432  (flags & SDL_COPY_NEAREST)) {
1433  return -1;
1434  }
1435 
1436  /* Encode and set up the blit */
1437  if (!surface->format->Amask || !(flags & SDL_COPY_BLEND)) {
1438  if (!surface->map->identity) {
1439  return -1;
1440  }
1441  if (RLEColorkeySurface(surface) < 0) {
1442  return -1;
1443  }
1444  surface->map->blit = SDL_RLEBlit;
1445  surface->map->info.flags |= SDL_COPY_RLE_COLORKEY;
1446  } else {
1447  if (RLEAlphaSurface(surface) < 0) {
1448  return -1;
1449  }
1450  surface->map->blit = SDL_RLEAlphaBlit;
1451  surface->map->info.flags |= SDL_COPY_RLE_ALPHAKEY;
1452  }
1453 
1454  /* The surface is now accelerated */
1455  surface->flags |= SDL_RLEACCEL;
1456 
1457  return (0);
1458 }
#define SDL_COPY_MODULATE_COLOR
Definition: SDL_blit.h:34
#define SDL_COPY_COLORKEY
Definition: SDL_blit.h:39
SDL_blit blit
Definition: SDL_blit.h:90
#define SDL_COPY_MOD
Definition: SDL_blit.h:38
void SDL_UnRLESurface(SDL_Surface *surface, int recode)
#define SDL_COPY_RLE_COLORKEY
Definition: SDL_blit.h:42
int SDL_RLEBlit(SDL_Surface *surf_src, SDL_Rect *srcrect, SDL_Surface *surf_dst, SDL_Rect *dstrect)
Definition: SDL_RLEaccel.c:449
#define SDL_COPY_ADD
Definition: SDL_blit.h:37
Uint32 flags
Definition: SDL_surface.h:71
#define SDL_COPY_NEAREST
Definition: SDL_blit.h:40
struct SDL_BlitMap * map
Definition: SDL_surface.h:88
void * pixels
Definition: SDL_surface.h:75
Uint8 BitsPerPixel
Definition: SDL_pixels.h:319
int SDL_RLEAlphaBlit(SDL_Surface *surf_src, SDL_Rect *srcrect, SDL_Surface *surf_dst, SDL_Rect *dstrect)
Definition: SDL_RLEaccel.c:727
static int RLEColorkeySurface(SDL_Surface *surface)
SDL_PixelFormat * format
Definition: SDL_surface.h:72
GLbitfield flags
#define SDL_COPY_MODULATE_ALPHA
Definition: SDL_blit.h:35
#define SDL_COPY_RLE_ALPHAKEY
Definition: SDL_blit.h:43
static int RLEAlphaSurface(SDL_Surface *surface)
int identity
Definition: SDL_blit.h:89
#define SDL_COPY_BLEND
Definition: SDL_blit.h:36
SDL_BlitInfo info
Definition: SDL_blit.h:92
#define SDL_RLEACCEL
Definition: SDL_surface.h:54

◆ SDL_UnRLESurface()

void SDL_UnRLESurface ( SDL_Surface surface,
int  recode 
)

Definition at line 1540 of file SDL_RLEaccel.c.

References SDL_BlitInfo::colorkey, SDL_BlitMap::data, SDL_BlitInfo::flags, SDL_Surface::flags, SDL_Rect::h, SDL_Surface::h, SDL_BlitMap::info, SDL_Surface::map, NULL, SDL_Surface::pitch, SDL_Surface::pixels, SDL_COPY_RLE_ALPHAKEY, SDL_COPY_RLE_COLORKEY, SDL_FillRect, SDL_free, SDL_malloc, SDL_PREALLOC, SDL_RLEACCEL, SDL_RLEBlit(), UnRLEAlpha(), SDL_Rect::w, SDL_Surface::w, SDL_Rect::x, and SDL_Rect::y.

Referenced by SDL_CalculateBlit(), SDL_FreeSurface(), SDL_LockSurface(), SDL_MapSurface(), and SDL_RLESurface().

1541 {
1542  if (surface->flags & SDL_RLEACCEL) {
1543  surface->flags &= ~SDL_RLEACCEL;
1544 
1545  if (recode && !(surface->flags & SDL_PREALLOC)) {
1546  if (surface->map->info.flags & SDL_COPY_RLE_COLORKEY) {
1547  SDL_Rect full;
1548 
1549  /* re-create the original surface */
1550  surface->pixels = SDL_malloc(surface->h * surface->pitch);
1551  if (!surface->pixels) {
1552  /* Oh crap... */
1553  surface->flags |= SDL_RLEACCEL;
1554  return;
1555  }
1556 
1557  /* fill it with the background color */
1558  SDL_FillRect(surface, NULL, surface->map->info.colorkey);
1559 
1560  /* now render the encoded surface */
1561  full.x = full.y = 0;
1562  full.w = surface->w;
1563  full.h = surface->h;
1564  SDL_RLEBlit(surface, &full, surface, &full);
1565  } else {
1566  if (!UnRLEAlpha(surface)) {
1567  /* Oh crap... */
1568  surface->flags |= SDL_RLEACCEL;
1569  return;
1570  }
1571  }
1572  }
1573  surface->map->info.flags &=
1575 
1576  SDL_free(surface->map->data);
1577  surface->map->data = NULL;
1578  }
1579 }
#define SDL_COPY_RLE_COLORKEY
Definition: SDL_blit.h:42
int SDL_RLEBlit(SDL_Surface *surf_src, SDL_Rect *srcrect, SDL_Surface *surf_dst, SDL_Rect *dstrect)
Definition: SDL_RLEaccel.c:449
Uint32 colorkey
Definition: SDL_blit.h:69
Uint32 flags
Definition: SDL_surface.h:71
struct SDL_BlitMap * map
Definition: SDL_surface.h:88
void * pixels
Definition: SDL_surface.h:75
#define SDL_free
int x
Definition: SDL_rect.h:66
int w
Definition: SDL_rect.h:67
#define NULL
Definition: begin_code.h:164
static SDL_bool UnRLEAlpha(SDL_Surface *surface)
int h
Definition: SDL_rect.h:67
#define SDL_COPY_RLE_ALPHAKEY
Definition: SDL_blit.h:43
#define SDL_FillRect
void * data
Definition: SDL_blit.h:91
#define SDL_malloc
int y
Definition: SDL_rect.h:66
SDL_BlitInfo info
Definition: SDL_blit.h:92
#define SDL_PREALLOC
Definition: SDL_surface.h:53
A rectangle, with the origin at the upper left.
Definition: SDL_rect.h:64
#define SDL_RLEACCEL
Definition: SDL_surface.h:54