SDL  2.0
SDL_surface.c File Reference
#include "../SDL_internal.h"
#include "SDL_video.h"
#include "SDL_sysvideo.h"
#include "SDL_blit.h"
#include "SDL_RLEaccel_c.h"
#include "SDL_pixels_c.h"
#include "SDL_yuv_c.h"
+ Include dependency graph for SDL_surface.c:

Go to the source code of this file.

Functions

 SDL_COMPILE_TIME_ASSERT (surface_size_assumptions, sizeof(int)==sizeof(Sint32) &&sizeof(size_t) >=sizeof(Sint32))
 
static int SDL_CalculatePitch (Uint32 format, int width)
 
SDL_SurfaceSDL_CreateRGBSurfaceWithFormat (Uint32 flags, int width, int height, int depth, Uint32 format)
 
SDL_SurfaceSDL_CreateRGBSurface (Uint32 flags, int width, int height, int depth, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask)
 
SDL_SurfaceSDL_CreateRGBSurfaceFrom (void *pixels, int width, int height, int depth, int pitch, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask)
 
SDL_SurfaceSDL_CreateRGBSurfaceWithFormatFrom (void *pixels, int width, int height, int depth, int pitch, Uint32 format)
 
int SDL_SetSurfacePalette (SDL_Surface *surface, SDL_Palette *palette)
 Set the palette used by a surface. More...
 
int SDL_SetSurfaceRLE (SDL_Surface *surface, int flag)
 Sets the RLE acceleration hint for a surface. More...
 
int SDL_SetColorKey (SDL_Surface *surface, int flag, Uint32 key)
 Sets the color key (transparent pixel) in a blittable surface. More...
 
SDL_bool SDL_HasColorKey (SDL_Surface *surface)
 Returns whether the surface has a color key. More...
 
int SDL_GetColorKey (SDL_Surface *surface, Uint32 *key)
 Gets the color key (transparent pixel) in a blittable surface. More...
 
static void SDL_ConvertColorkeyToAlpha (SDL_Surface *surface)
 
int SDL_SetSurfaceColorMod (SDL_Surface *surface, Uint8 r, Uint8 g, Uint8 b)
 Set an additional color value used in blit operations. More...
 
int SDL_GetSurfaceColorMod (SDL_Surface *surface, Uint8 *r, Uint8 *g, Uint8 *b)
 Get the additional color value used in blit operations. More...
 
int SDL_SetSurfaceAlphaMod (SDL_Surface *surface, Uint8 alpha)
 Set an additional alpha value used in blit operations. More...
 
int SDL_GetSurfaceAlphaMod (SDL_Surface *surface, Uint8 *alpha)
 Get the additional alpha value used in blit operations. More...
 
int SDL_SetSurfaceBlendMode (SDL_Surface *surface, SDL_BlendMode blendMode)
 Set the blend mode used for blit operations. More...
 
int SDL_GetSurfaceBlendMode (SDL_Surface *surface, SDL_BlendMode *blendMode)
 Get the blend mode used for blit operations. More...
 
SDL_bool SDL_SetClipRect (SDL_Surface *surface, const SDL_Rect *rect)
 
void SDL_GetClipRect (SDL_Surface *surface, SDL_Rect *rect)
 
int SDL_LowerBlit (SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect)
 
int SDL_UpperBlit (SDL_Surface *src, const SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect)
 
int SDL_UpperBlitScaled (SDL_Surface *src, const SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect)
 
int SDL_LowerBlitScaled (SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect)
 
int SDL_LockSurface (SDL_Surface *surface)
 Sets up a surface for directly accessing the pixels. More...
 
void SDL_UnlockSurface (SDL_Surface *surface)
 
SDL_SurfaceSDL_DuplicateSurface (SDL_Surface *surface)
 
SDL_SurfaceSDL_ConvertSurface (SDL_Surface *surface, const SDL_PixelFormat *format, Uint32 flags)
 
SDL_SurfaceSDL_ConvertSurfaceFormat (SDL_Surface *surface, Uint32 pixel_format, Uint32 flags)
 
static SDL_INLINE SDL_bool SDL_CreateSurfaceOnStack (int width, int height, Uint32 pixel_format, void *pixels, int pitch, SDL_Surface *surface, SDL_PixelFormat *format, SDL_BlitMap *blitmap)
 
int SDL_ConvertPixels (int width, int height, Uint32 src_format, const void *src, int src_pitch, Uint32 dst_format, void *dst, int dst_pitch)
 Copy a block of pixels of one format to another format. More...
 
void SDL_FreeSurface (SDL_Surface *surface)
 

Function Documentation

◆ SDL_CalculatePitch()

static int SDL_CalculatePitch ( Uint32  format,
int  width 
)
static

Definition at line 41 of file SDL_surface.c.

42 {
43  int pitch;
44 
45  /* Surface should be 4-byte aligned for speed */
46  pitch = width * SDL_BYTESPERPIXEL(format);
47  switch (SDL_BITSPERPIXEL(format)) {
48  case 1:
49  pitch = (pitch + 7) / 8;
50  break;
51  case 4:
52  pitch = (pitch + 1) / 2;
53  break;
54  default:
55  break;
56  }
57  pitch = (pitch + 3) & ~3; /* 4-byte aligning */
58  return pitch;
59 }

References SDL_BITSPERPIXEL, and SDL_BYTESPERPIXEL.

Referenced by SDL_CreateRGBSurfaceWithFormat().

◆ SDL_COMPILE_TIME_ASSERT()

SDL_COMPILE_TIME_ASSERT ( surface_size_assumptions  ,
sizeof(int)  = =sizeof(Sint32) &&sizeof(size_t) >=sizeof(Sint32) 
)

◆ SDL_ConvertColorkeyToAlpha()

static void SDL_ConvertColorkeyToAlpha ( SDL_Surface surface)
static

Definition at line 328 of file SDL_surface.c.

329 {
330  int x, y;
331 
332  if (!surface) {
333  return;
334  }
335 
336  if (!(surface->map->info.flags & SDL_COPY_COLORKEY) ||
337  !surface->format->Amask) {
338  return;
339  }
340 
342 
343  switch (surface->format->BytesPerPixel) {
344  case 2:
345  {
346  Uint16 *row, *spot;
347  Uint16 ckey = (Uint16) surface->map->info.colorkey;
348  Uint16 mask = (Uint16) (~surface->format->Amask);
349 
350  /* Ignore alpha in colorkey comparison */
351  ckey &= mask;
352  row = (Uint16 *) surface->pixels;
353  for (y = surface->h; y--;) {
354  spot = row;
355  for (x = surface->w; x--;) {
356  if ((*spot & mask) == ckey) {
357  *spot &= mask;
358  }
359  ++spot;
360  }
361  row += surface->pitch / 2;
362  }
363  }
364  break;
365  case 3:
366  /* FIXME */
367  break;
368  case 4:
369  {
370  Uint32 *row, *spot;
371  Uint32 ckey = surface->map->info.colorkey;
372  Uint32 mask = ~surface->format->Amask;
373 
374  /* Ignore alpha in colorkey comparison */
375  ckey &= mask;
376  row = (Uint32 *) surface->pixels;
377  for (y = surface->h; y--;) {
378  spot = row;
379  for (x = surface->w; x--;) {
380  if ((*spot & mask) == ckey) {
381  *spot &= mask;
382  }
383  ++spot;
384  }
385  row += surface->pitch / 4;
386  }
387  }
388  break;
389  }
390 
392 
393  SDL_SetColorKey(surface, 0, 0);
395 }

References SDL_BLENDMODE_BLEND, SDL_COPY_COLORKEY, SDL_LockSurface(), SDL_SetColorKey(), SDL_SetSurfaceBlendMode(), and SDL_UnlockSurface().

Referenced by SDL_ConvertSurface().

◆ SDL_ConvertPixels()

int SDL_ConvertPixels ( int  width,
int  height,
Uint32  src_format,
const void src,
int  src_pitch,
Uint32  dst_format,
void dst,
int  dst_pitch 
)

Copy a block of pixels of one format to another format.

Returns
0 on success, or -1 if there was an error

Definition at line 1152 of file SDL_surface.c.

1155 {
1156  SDL_Surface src_surface, dst_surface;
1157  SDL_PixelFormat src_fmt, dst_fmt;
1158  SDL_BlitMap src_blitmap, dst_blitmap;
1159  SDL_Rect rect;
1160  void *nonconst_src = (void *) src;
1161 
1162  /* Check to make sure we are blitting somewhere, so we don't crash */
1163  if (!dst) {
1164  return SDL_InvalidParamError("dst");
1165  }
1166  if (!dst_pitch) {
1167  return SDL_InvalidParamError("dst_pitch");
1168  }
1169 
1170  if (SDL_ISPIXELFORMAT_FOURCC(src_format) && SDL_ISPIXELFORMAT_FOURCC(dst_format)) {
1171  return SDL_ConvertPixels_YUV_to_YUV(width, height, src_format, src, src_pitch, dst_format, dst, dst_pitch);
1172  } else if (SDL_ISPIXELFORMAT_FOURCC(src_format)) {
1173  return SDL_ConvertPixels_YUV_to_RGB(width, height, src_format, src, src_pitch, dst_format, dst, dst_pitch);
1174  } else if (SDL_ISPIXELFORMAT_FOURCC(dst_format)) {
1175  return SDL_ConvertPixels_RGB_to_YUV(width, height, src_format, src, src_pitch, dst_format, dst, dst_pitch);
1176  }
1177 
1178  /* Fast path for same format copy */
1179  if (src_format == dst_format) {
1180  int i;
1181  const int bpp = SDL_BYTESPERPIXEL(src_format);
1182  width *= bpp;
1183  for (i = height; i--;) {
1184  SDL_memcpy(dst, src, width);
1185  src = (const Uint8*)src + src_pitch;
1186  dst = (Uint8*)dst + dst_pitch;
1187  }
1188  return 0;
1189  }
1190 
1191  if (!SDL_CreateSurfaceOnStack(width, height, src_format, nonconst_src,
1192  src_pitch,
1193  &src_surface, &src_fmt, &src_blitmap)) {
1194  return -1;
1195  }
1196  if (!SDL_CreateSurfaceOnStack(width, height, dst_format, dst, dst_pitch,
1197  &dst_surface, &dst_fmt, &dst_blitmap)) {
1198  return -1;
1199  }
1200 
1201  /* Set up the rect and go! */
1202  rect.x = 0;
1203  rect.y = 0;
1204  rect.w = width;
1205  rect.h = height;
1206  return SDL_LowerBlit(&src_surface, &rect, &dst_surface, &rect);
1207 }

References SDL_Rect::h, i, rect, SDL_BYTESPERPIXEL, SDL_ConvertPixels_RGB_to_YUV(), SDL_ConvertPixels_YUV_to_RGB(), SDL_ConvertPixels_YUV_to_YUV(), SDL_CreateSurfaceOnStack(), SDL_InvalidParamError, SDL_ISPIXELFORMAT_FOURCC, SDL_LowerBlit(), SDL_memcpy, SDL_Rect::w, SDL_Rect::x, and SDL_Rect::y.

◆ SDL_ConvertSurface()

SDL_Surface* SDL_ConvertSurface ( SDL_Surface src,
const SDL_PixelFormat fmt,
Uint32  flags 
)

Creates a new surface of the specified format, and then copies and maps the given surface to it so the blit of the converted surface will be as fast as possible. If this function fails, it returns NULL.

The flags parameter is passed to SDL_CreateRGBSurface() and has those semantics. You can also pass SDL_RLEACCEL in the flags parameter and SDL will try to RLE accelerate colorkey and alpha blits in the resulting surface.

Definition at line 939 of file SDL_surface.c.

941 {
942  SDL_Surface *convert;
943  Uint32 copy_flags;
944  SDL_Color copy_color;
945  SDL_Rect bounds;
946 
947  if (!surface) {
948  SDL_InvalidParamError("surface");
949  return NULL;
950  }
951  if (!format) {
952  SDL_InvalidParamError("format");
953  return NULL;
954  }
955 
956  /* Check for empty destination palette! (results in empty image) */
957  if (format->palette != NULL) {
958  int i;
959  for (i = 0; i < format->palette->ncolors; ++i) {
960  if ((format->palette->colors[i].r != 0xFF) ||
961  (format->palette->colors[i].g != 0xFF) ||
962  (format->palette->colors[i].b != 0xFF))
963  break;
964  }
965  if (i == format->palette->ncolors) {
966  SDL_SetError("Empty destination palette");
967  return (NULL);
968  }
969  }
970 
971  /* Create a new surface with the desired format */
972  convert = SDL_CreateRGBSurface(flags, surface->w, surface->h,
973  format->BitsPerPixel, format->Rmask,
974  format->Gmask, format->Bmask,
975  format->Amask);
976  if (convert == NULL) {
977  return (NULL);
978  }
979 
980  /* Copy the palette if any */
981  if (format->palette && convert->format->palette) {
982  SDL_memcpy(convert->format->palette->colors,
983  format->palette->colors,
984  format->palette->ncolors * sizeof(SDL_Color));
985  convert->format->palette->ncolors = format->palette->ncolors;
986  }
987 
988  /* Save the original copy flags */
989  copy_flags = surface->map->info.flags;
990  copy_color.r = surface->map->info.r;
991  copy_color.g = surface->map->info.g;
992  copy_color.b = surface->map->info.b;
993  copy_color.a = surface->map->info.a;
994  surface->map->info.r = 0xFF;
995  surface->map->info.g = 0xFF;
996  surface->map->info.b = 0xFF;
997  surface->map->info.a = 0xFF;
998  surface->map->info.flags = 0;
1000 
1001  /* Copy over the image data */
1002  bounds.x = 0;
1003  bounds.y = 0;
1004  bounds.w = surface->w;
1005  bounds.h = surface->h;
1006  SDL_LowerBlit(surface, &bounds, convert, &bounds);
1007 
1008  /* Clean up the original surface, and update converted surface */
1009  convert->map->info.r = copy_color.r;
1010  convert->map->info.g = copy_color.g;
1011  convert->map->info.b = copy_color.b;
1012  convert->map->info.a = copy_color.a;
1013  convert->map->info.flags =
1014  (copy_flags &
1018  surface->map->info.r = copy_color.r;
1019  surface->map->info.g = copy_color.g;
1020  surface->map->info.b = copy_color.b;
1021  surface->map->info.a = copy_color.a;
1022  surface->map->info.flags = copy_flags;
1023  SDL_InvalidateMap(surface->map);
1024  if (copy_flags & SDL_COPY_COLORKEY) {
1025  SDL_bool set_colorkey_by_color = SDL_FALSE;
1026 
1027  if (surface->format->palette) {
1028  if (format->palette &&
1029  surface->format->palette->ncolors <= format->palette->ncolors &&
1030  (SDL_memcmp(surface->format->palette->colors, format->palette->colors,
1031  surface->format->palette->ncolors * sizeof(SDL_Color)) == 0)) {
1032  /* The palette is identical, just set the same colorkey */
1033  SDL_SetColorKey(convert, 1, surface->map->info.colorkey);
1034  } else if (format->Amask) {
1035  /* The alpha was set in the destination from the palette */
1036  } else {
1037  set_colorkey_by_color = SDL_TRUE;
1038  }
1039  } else {
1040  set_colorkey_by_color = SDL_TRUE;
1041  }
1042 
1043  if (set_colorkey_by_color) {
1044  SDL_Surface *tmp;
1045  SDL_Surface *tmp2;
1046  int converted_colorkey = 0;
1047 
1048  /* Create a dummy surface to get the colorkey converted */
1049  tmp = SDL_CreateRGBSurface(0, 1, 1,
1050  surface->format->BitsPerPixel, surface->format->Rmask,
1051  surface->format->Gmask, surface->format->Bmask,
1052  surface->format->Amask);
1053 
1054  /* Share the palette, if any */
1055  if (surface->format->palette) {
1056  SDL_SetSurfacePalette(tmp, surface->format->palette);
1057  }
1058 
1059  SDL_FillRect(tmp, NULL, surface->map->info.colorkey);
1060 
1061  tmp->map->info.flags &= ~SDL_COPY_COLORKEY;
1062 
1063  /* Convertion of the colorkey */
1064  tmp2 = SDL_ConvertSurface(tmp, format, 0);
1065 
1066  /* Get the converted colorkey */
1067  SDL_memcpy(&converted_colorkey, tmp2->pixels, tmp2->format->BytesPerPixel);
1068 
1069  SDL_FreeSurface(tmp);
1070  SDL_FreeSurface(tmp2);
1071 
1072  /* Set the converted colorkey on the new surface */
1073  SDL_SetColorKey(convert, 1, converted_colorkey);
1074 
1075  /* This is needed when converting for 3D texture upload */
1076  SDL_ConvertColorkeyToAlpha(convert);
1077  }
1078  }
1079  SDL_SetClipRect(convert, &surface->clip_rect);
1080 
1081  /* Enable alpha blending by default if the new surface has an
1082  * alpha channel or alpha modulation */
1083  if ((surface->format->Amask && format->Amask) ||
1084  (copy_flags & SDL_COPY_MODULATE_ALPHA)) {
1086  }
1087  if ((copy_flags & SDL_COPY_RLE_DESIRED) || (flags & SDL_RLEACCEL)) {
1088  SDL_SetSurfaceRLE(convert, SDL_RLEACCEL);
1089  }
1090 
1091  /* We're ready to go! */
1092  return (convert);
1093 }

References SDL_Color::a, SDL_BlitInfo::a, SDL_Color::b, SDL_BlitInfo::b, SDL_PixelFormat::BytesPerPixel, SDL_Surface::clip_rect, SDL_BlitInfo::colorkey, SDL_Palette::colors, SDL_BlitInfo::flags, SDL_Surface::format, SDL_Color::g, SDL_BlitInfo::g, SDL_Rect::h, i, SDL_BlitMap::info, SDL_Surface::map, SDL_Palette::ncolors, NULL, SDL_PixelFormat::palette, SDL_Surface::pixels, SDL_Color::r, SDL_BlitInfo::r, SDL_BLENDMODE_BLEND, SDL_ConvertColorkeyToAlpha(), SDL_COPY_BLEND, SDL_COPY_COLORKEY, SDL_COPY_MODULATE_ALPHA, SDL_COPY_RLE_ALPHAKEY, SDL_COPY_RLE_COLORKEY, SDL_COPY_RLE_DESIRED, SDL_CreateRGBSurface(), SDL_FALSE, SDL_FillRect, SDL_FreeSurface(), SDL_InvalidateMap(), SDL_InvalidParamError, SDL_LowerBlit(), SDL_memcmp, SDL_memcpy, SDL_RLEACCEL, SDL_SetClipRect(), SDL_SetColorKey(), SDL_SetError, SDL_SetSurfaceBlendMode(), SDL_SetSurfacePalette(), SDL_SetSurfaceRLE(), SDL_TRUE, SDL_Rect::w, SDL_Rect::x, and SDL_Rect::y.

Referenced by SDL_ConvertSurfaceFormat(), and SDL_DuplicateSurface().

◆ SDL_ConvertSurfaceFormat()

SDL_Surface* SDL_ConvertSurfaceFormat ( SDL_Surface surface,
Uint32  pixel_format,
Uint32  flags 
)

Definition at line 1096 of file SDL_surface.c.

1098 {
1099  SDL_PixelFormat *fmt;
1100  SDL_Surface *convert = NULL;
1101 
1102  fmt = SDL_AllocFormat(pixel_format);
1103  if (fmt) {
1104  convert = SDL_ConvertSurface(surface, fmt, flags);
1105  SDL_FreeFormat(fmt);
1106  }
1107  return convert;
1108 }

References NULL, SDL_AllocFormat, SDL_ConvertSurface(), and SDL_FreeFormat.

◆ SDL_CreateRGBSurface()

SDL_Surface* SDL_CreateRGBSurface ( Uint32  flags,
int  width,
int  height,
int  depth,
Uint32  Rmask,
Uint32  Gmask,
Uint32  Bmask,
Uint32  Amask 
)

Allocate and free an RGB surface.

If the depth is 4 or 8 bits, an empty palette is allocated for the surface. If the depth is greater than 8 bits, the pixel format is set using the flags '[RGB]mask'.

If the function runs out of memory, it will return NULL.

Parameters
flagsThe flags are obsolete and should be set to 0.
widthThe width in pixels of the surface to create.
heightThe height in pixels of the surface to create.
depthThe depth in bits of the surface to create.
RmaskThe red mask of the surface to create.
GmaskThe green mask of the surface to create.
BmaskThe blue mask of the surface to create.
AmaskThe alpha mask of the surface to create.

Definition at line 153 of file SDL_surface.c.

156 {
157  Uint32 format;
158 
159  /* Get the pixel format */
160  format = SDL_MasksToPixelFormatEnum(depth, Rmask, Gmask, Bmask, Amask);
162  SDL_SetError("Unknown pixel format");
163  return NULL;
164  }
165 
167 }

References NULL, SDL_CreateRGBSurfaceWithFormat(), SDL_MasksToPixelFormatEnum, SDL_PIXELFORMAT_UNKNOWN, and SDL_SetError.

Referenced by SDL_ConvertSurface(), and SDL_CreateRGBSurfaceFrom().

◆ SDL_CreateRGBSurfaceFrom()

SDL_Surface* SDL_CreateRGBSurfaceFrom ( void pixels,
int  width,
int  height,
int  depth,
int  pitch,
Uint32  Rmask,
Uint32  Gmask,
Uint32  Bmask,
Uint32  Amask 
)

Definition at line 173 of file SDL_surface.c.

177 {
179 
180  surface = SDL_CreateRGBSurface(0, 0, 0, depth, Rmask, Gmask, Bmask, Amask);
181  if (surface != NULL) {
182  surface->flags |= SDL_PREALLOC;
183  surface->pixels = pixels;
184  surface->w = width;
185  surface->h = height;
186  surface->pitch = pitch;
188  }
189  return surface;
190 }

References NULL, SDL_CreateRGBSurface(), SDL_PREALLOC, and SDL_SetClipRect().

◆ SDL_CreateRGBSurfaceWithFormat()

SDL_Surface* SDL_CreateRGBSurfaceWithFormat ( Uint32  flags,
int  width,
int  height,
int  depth,
Uint32  format 
)

Definition at line 66 of file SDL_surface.c.

68 {
70 
71  /* The flags are no longer used, make the compiler happy */
72  (void)flags;
73 
74  /* Allocate the surface */
75  surface = (SDL_Surface *) SDL_calloc(1, sizeof(*surface));
76  if (surface == NULL) {
78  return NULL;
79  }
80 
81  surface->format = SDL_AllocFormat(format);
82  if (!surface->format) {
84  return NULL;
85  }
86  surface->w = width;
87  surface->h = height;
90 
91  if (SDL_ISPIXELFORMAT_INDEXED(surface->format->format)) {
92  SDL_Palette *palette =
93  SDL_AllocPalette((1 << surface->format->BitsPerPixel));
94  if (!palette) {
96  return NULL;
97  }
98  if (palette->ncolors == 2) {
99  /* Create a black and white bitmap palette */
100  palette->colors[0].r = 0xFF;
101  palette->colors[0].g = 0xFF;
102  palette->colors[0].b = 0xFF;
103  palette->colors[1].r = 0x00;
104  palette->colors[1].g = 0x00;
105  palette->colors[1].b = 0x00;
106  }
107  SDL_SetSurfacePalette(surface, palette);
108  SDL_FreePalette(palette);
109  }
110 
111  /* Get the pixels */
112  if (surface->w && surface->h) {
113  /* Assumptions checked in surface_size_assumptions assert above */
114  Sint64 size = ((Sint64)surface->h * surface->pitch);
116  /* Overflow... */
118  SDL_OutOfMemory();
119  return NULL;
120  }
121 
122  surface->pixels = SDL_malloc((size_t)size);
123  if (!surface->pixels) {
125  SDL_OutOfMemory();
126  return NULL;
127  }
128  /* This is important for bitmaps */
129  SDL_memset(surface->pixels, 0, surface->h * surface->pitch);
130  }
131 
132  /* Allocate an empty mapping */
133  surface->map = SDL_AllocBlitMap();
134  if (!surface->map) {
136  return NULL;
137  }
138 
139  /* By default surface with an alpha mask are set up for blending */
140  if (surface->format->Amask) {
142  }
143 
144  /* The surface is ready to go */
145  surface->refcount = 1;
146  return surface;
147 }

References SDL_Color::b, SDL_Palette::colors, SDL_Color::g, SDL_Palette::ncolors, NULL, SDL_Color::r, SDL_AllocBlitMap(), SDL_AllocFormat, SDL_AllocPalette, SDL_BLENDMODE_BLEND, SDL_CalculatePitch(), SDL_calloc, SDL_FreePalette, SDL_FreeSurface(), SDL_ISPIXELFORMAT_INDEXED, SDL_malloc, SDL_MAX_SINT32, SDL_memset, SDL_OutOfMemory, SDL_SetClipRect(), SDL_SetSurfaceBlendMode(), SDL_SetSurfacePalette(), and void.

Referenced by SDL_CreateRGBSurface(), and SDL_CreateRGBSurfaceWithFormatFrom().

◆ SDL_CreateRGBSurfaceWithFormatFrom()

SDL_Surface* SDL_CreateRGBSurfaceWithFormatFrom ( void pixels,
int  width,
int  height,
int  depth,
int  pitch,
Uint32  format 
)

Definition at line 197 of file SDL_surface.c.

200 {
202 
204  if (surface != NULL) {
205  surface->flags |= SDL_PREALLOC;
206  surface->pixels = pixels;
207  surface->w = width;
208  surface->h = height;
209  surface->pitch = pitch;
211  }
212  return surface;
213 }

References NULL, SDL_CreateRGBSurfaceWithFormat(), SDL_PREALLOC, and SDL_SetClipRect().

◆ SDL_CreateSurfaceOnStack()

static SDL_INLINE SDL_bool SDL_CreateSurfaceOnStack ( int  width,
int  height,
Uint32  pixel_format,
void pixels,
int  pitch,
SDL_Surface surface,
SDL_PixelFormat format,
SDL_BlitMap blitmap 
)
static

Definition at line 1114 of file SDL_surface.c.

1117 {
1118  if (SDL_ISPIXELFORMAT_INDEXED(pixel_format)) {
1119  SDL_SetError("Indexed pixel formats not supported");
1120  return SDL_FALSE;
1121  }
1122  if (SDL_InitFormat(format, pixel_format) < 0) {
1123  return SDL_FALSE;
1124  }
1125 
1126  SDL_zerop(surface);
1127  surface->flags = SDL_PREALLOC;
1128  surface->format = format;
1129  surface->pixels = pixels;
1130  surface->w = width;
1131  surface->h = height;
1132  surface->pitch = pitch;
1133  /* We don't actually need to set up the clip rect for our purposes */
1134  /* SDL_SetClipRect(surface, NULL); */
1135 
1136  /* Allocate an empty mapping */
1137  SDL_zerop(blitmap);
1138  blitmap->info.r = 0xFF;
1139  blitmap->info.g = 0xFF;
1140  blitmap->info.b = 0xFF;
1141  blitmap->info.a = 0xFF;
1142  surface->map = blitmap;
1143 
1144  /* The surface is ready to go */
1145  surface->refcount = 1;
1146  return SDL_TRUE;
1147 }

References SDL_BlitInfo::a, SDL_BlitInfo::b, SDL_BlitInfo::g, SDL_BlitMap::info, SDL_BlitInfo::r, SDL_FALSE, SDL_InitFormat(), SDL_ISPIXELFORMAT_INDEXED, SDL_PREALLOC, SDL_SetError, SDL_TRUE, and SDL_zerop.

Referenced by SDL_ConvertPixels().

◆ SDL_DuplicateSurface()

SDL_Surface* SDL_DuplicateSurface ( SDL_Surface surface)

Definition at line 930 of file SDL_surface.c.

931 {
932  return SDL_ConvertSurface(surface, surface->format, surface->flags);
933 }

References SDL_ConvertSurface().

◆ SDL_FreeSurface()

void SDL_FreeSurface ( SDL_Surface surface)

Definition at line 1213 of file SDL_surface.c.

1214 {
1215  if (surface == NULL) {
1216  return;
1217  }
1218  if (surface->flags & SDL_DONTFREE) {
1219  return;
1220  }
1221  SDL_InvalidateMap(surface->map);
1222 
1223  if (--surface->refcount > 0) {
1224  return;
1225  }
1226  while (surface->locked > 0) {
1228  }
1229  if (surface->flags & SDL_RLEACCEL) {
1231  }
1232  if (surface->format) {
1234  SDL_FreeFormat(surface->format);
1235  surface->format = NULL;
1236  }
1237  if (!(surface->flags & SDL_PREALLOC)) {
1238  SDL_free(surface->pixels);
1239  }
1240  if (surface->map) {
1241  SDL_FreeBlitMap(surface->map);
1242  }
1243  SDL_free(surface);
1244 }

References NULL, SDL_DONTFREE, SDL_free, SDL_FreeBlitMap(), SDL_FreeFormat, SDL_InvalidateMap(), SDL_PREALLOC, SDL_RLEACCEL, SDL_SetSurfacePalette(), SDL_UnlockSurface(), and SDL_UnRLESurface().

Referenced by SDL_ConvertSurface(), and SDL_CreateRGBSurfaceWithFormat().

◆ SDL_GetClipRect()

void SDL_GetClipRect ( SDL_Surface surface,
SDL_Rect rect 
)

Gets the clipping rectangle for the destination surface in a blit.

rect must be a pointer to a valid rectangle which will be filled with the correct values.

Definition at line 569 of file SDL_surface.c.

570 {
571  if (surface && rect) {
572  *rect = surface->clip_rect;
573  }
574 }

References rect.

◆ SDL_GetColorKey()

int SDL_GetColorKey ( SDL_Surface surface,
Uint32 key 
)

Gets the color key (transparent pixel) in a blittable surface.

Parameters
surfaceThe surface to update
keyA pointer filled in with the transparent pixel in the native surface format
Returns
0 on success, or -1 if the surface is not valid or colorkey is not enabled.

Definition at line 310 of file SDL_surface.c.

311 {
312  if (!surface) {
313  return SDL_InvalidParamError("surface");
314  }
315 
316  if (!(surface->map->info.flags & SDL_COPY_COLORKEY)) {
317  return SDL_SetError("Surface doesn't have a colorkey");
318  }
319 
320  if (key) {
321  *key = surface->map->info.colorkey;
322  }
323  return 0;
324 }

References SDL_COPY_COLORKEY, SDL_InvalidParamError, and SDL_SetError.

◆ SDL_GetSurfaceAlphaMod()

int SDL_GetSurfaceAlphaMod ( SDL_Surface surface,
Uint8 alpha 
)

Get the additional alpha value used in blit operations.

Parameters
surfaceThe surface to query.
alphaA pointer filled in with the current alpha value.
Returns
0 on success, or -1 if the surface is not valid.
See also
SDL_SetSurfaceAlphaMod()

Definition at line 466 of file SDL_surface.c.

467 {
468  if (!surface) {
469  return -1;
470  }
471 
472  if (alpha) {
473  *alpha = surface->map->info.a;
474  }
475  return 0;
476 }

◆ SDL_GetSurfaceBlendMode()

int SDL_GetSurfaceBlendMode ( SDL_Surface surface,
SDL_BlendMode blendMode 
)

Get the blend mode used for blit operations.

Parameters
surfaceThe surface to query.
blendModeA pointer filled in with the current blend mode.
Returns
0 on success, or -1 if the surface is not valid.
See also
SDL_SetSurfaceBlendMode()

Definition at line 516 of file SDL_surface.c.

517 {
518  if (!surface) {
519  return -1;
520  }
521 
522  if (!blendMode) {
523  return 0;
524  }
525 
526  switch (surface->map->
527  info.flags & (SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD)) {
528  case SDL_COPY_BLEND:
530  break;
531  case SDL_COPY_ADD:
533  break;
534  case SDL_COPY_MOD:
536  break;
537  default:
539  break;
540  }
541  return 0;
542 }

References blendMode, SDL_BLENDMODE_ADD, SDL_BLENDMODE_BLEND, SDL_BLENDMODE_MOD, SDL_BLENDMODE_NONE, SDL_COPY_ADD, SDL_COPY_BLEND, and SDL_COPY_MOD.

◆ SDL_GetSurfaceColorMod()

int SDL_GetSurfaceColorMod ( SDL_Surface surface,
Uint8 r,
Uint8 g,
Uint8 b 
)

Get the additional color value used in blit operations.

Parameters
surfaceThe surface to query.
rA pointer filled in with the current red color value.
gA pointer filled in with the current green color value.
bA pointer filled in with the current blue color value.
Returns
0 on success, or -1 if the surface is not valid.
See also
SDL_SetSurfaceColorMod()

Definition at line 424 of file SDL_surface.c.

425 {
426  if (!surface) {
427  return -1;
428  }
429 
430  if (r) {
431  *r = surface->map->info.r;
432  }
433  if (g) {
434  *g = surface->map->info.g;
435  }
436  if (b) {
437  *b = surface->map->info.b;
438  }
439  return 0;
440 }

◆ SDL_HasColorKey()

SDL_bool SDL_HasColorKey ( SDL_Surface surface)

Returns whether the surface has a color key.

Returns
SDL_TRUE if the surface has a color key, or SDL_FALSE if the surface is NULL or has no color key

Definition at line 296 of file SDL_surface.c.

297 {
298  if (!surface) {
299  return SDL_FALSE;
300  }
301 
302  if (!(surface->map->info.flags & SDL_COPY_COLORKEY)) {
303  return SDL_FALSE;
304  }
305 
306  return SDL_TRUE;
307 }

References SDL_COPY_COLORKEY, SDL_FALSE, and SDL_TRUE.

◆ SDL_LockSurface()

int SDL_LockSurface ( SDL_Surface surface)

Sets up a surface for directly accessing the pixels.

Between calls to SDL_LockSurface() / SDL_UnlockSurface(), you can write to and read from surface->pixels, using the pixel format stored in surface->format. Once you are done accessing the surface, you should use SDL_UnlockSurface() to release it.

Not all surfaces require locking. If SDL_MUSTLOCK(surface) evaluates to 0, then you can read and write to the surface at any time, and the pixel format of the surface will not change.

No operating system or library calls should be made between lock/unlock pairs, as critical system locks may be held during this time.

SDL_LockSurface() returns 0, or -1 if the surface couldn't be locked.

See also
SDL_UnlockSurface()

Definition at line 891 of file SDL_surface.c.

892 {
893  if (!surface->locked) {
894  /* Perform the lock */
895  if (surface->flags & SDL_RLEACCEL) {
897  surface->flags |= SDL_RLEACCEL; /* save accel'd state */
898  }
899  }
900 
901  /* Increment the surface lock count, for recursive locks */
902  ++surface->locked;
903 
904  /* Ready to go.. */
905  return (0);
906 }

References SDL_RLEACCEL, and SDL_UnRLESurface().

Referenced by SDL_ConvertColorkeyToAlpha().

◆ SDL_LowerBlit()

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

This is a semi-private blit function and it performs low-level surface blitting only.

Definition at line 588 of file SDL_surface.c.

590 {
591  /* Check to make sure the blit mapping is valid */
592  if ((src->map->dst != dst) ||
593  (dst->format->palette &&
594  src->map->dst_palette_version != dst->format->palette->version) ||
595  (src->format->palette &&
596  src->map->src_palette_version != src->format->palette->version)) {
597  if (SDL_MapSurface(src, dst) < 0) {
598  return (-1);
599  }
600  /* just here for debugging */
601 /* printf */
602 /* ("src = 0x%08X src->flags = %08X src->map->info.flags = %08x\ndst = 0x%08X dst->flags = %08X dst->map->info.flags = %08X\nsrc->map->blit = 0x%08x\n", */
603 /* src, dst->flags, src->map->info.flags, dst, dst->flags, */
604 /* dst->map->info.flags, src->map->blit); */
605  }
606  return (src->map->blit(src, srcrect, dst, dstrect));
607 }

References SDL_MapSurface().

Referenced by SDL_ConvertPixels(), SDL_ConvertSurface(), SDL_LowerBlitScaled(), and SDL_UpperBlit().

◆ SDL_LowerBlitScaled()

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

This is a semi-private blit function and it performs low-level surface scaled blitting only.

Definition at line 864 of file SDL_surface.c.

866 {
867  static const Uint32 complex_copy_flags = (
871  );
872 
873  if (!(src->map->info.flags & SDL_COPY_NEAREST)) {
874  src->map->info.flags |= SDL_COPY_NEAREST;
875  SDL_InvalidateMap(src->map);
876  }
877 
878  if ( !(src->map->info.flags & complex_copy_flags) &&
879  src->format->format == dst->format->format &&
880  !SDL_ISPIXELFORMAT_INDEXED(src->format->format) ) {
881  return SDL_SoftStretch( src, srcrect, dst, dstrect );
882  } else {
883  return SDL_LowerBlit( src, srcrect, dst, dstrect );
884  }
885 }

References SDL_COPY_ADD, SDL_COPY_BLEND, SDL_COPY_COLORKEY, SDL_COPY_MOD, SDL_COPY_MODULATE_ALPHA, SDL_COPY_MODULATE_COLOR, SDL_COPY_NEAREST, SDL_InvalidateMap(), SDL_ISPIXELFORMAT_INDEXED, SDL_LowerBlit(), and SDL_SoftStretch.

Referenced by SDL_UpperBlitScaled().

◆ SDL_SetClipRect()

SDL_bool SDL_SetClipRect ( SDL_Surface surface,
const SDL_Rect rect 
)

Sets the clipping rectangle for the destination surface in a blit.

If the clip rectangle is NULL, clipping will be disabled.

If the clip rectangle doesn't intersect the surface, the function will return SDL_FALSE and blits will be completely clipped. Otherwise the function returns SDL_TRUE and blits to the surface will be clipped to the intersection of the surface area and the clipping rectangle.

Note that blits are automatically clipped to the edges of the source and destination surfaces.

Definition at line 545 of file SDL_surface.c.

546 {
547  SDL_Rect full_rect;
548 
549  /* Don't do anything if there's no surface to act on */
550  if (!surface) {
551  return SDL_FALSE;
552  }
553 
554  /* Set up the full surface rectangle */
555  full_rect.x = 0;
556  full_rect.y = 0;
557  full_rect.w = surface->w;
558  full_rect.h = surface->h;
559 
560  /* Set the clipping rectangle */
561  if (!rect) {
562  surface->clip_rect = full_rect;
563  return SDL_TRUE;
564  }
565  return SDL_IntersectRect(rect, &full_rect, &surface->clip_rect);
566 }

References SDL_Rect::h, rect, SDL_FALSE, SDL_IntersectRect, SDL_TRUE, SDL_Rect::w, SDL_Rect::x, and SDL_Rect::y.

Referenced by SDL_ConvertSurface(), SDL_CreateRGBSurfaceFrom(), SDL_CreateRGBSurfaceWithFormat(), and SDL_CreateRGBSurfaceWithFormatFrom().

◆ SDL_SetColorKey()

int SDL_SetColorKey ( SDL_Surface surface,
int  flag,
Uint32  key 
)

Sets the color key (transparent pixel) in a blittable surface.

Parameters
surfaceThe surface to update
flagNon-zero to enable colorkey and 0 to disable colorkey
keyThe transparent pixel in the native surface format
Returns
0 on success, or -1 if the surface is not valid

You can pass SDL_RLEACCEL to enable RLE accelerated blits.

Definition at line 251 of file SDL_surface.c.

252 {
253  int flags;
254 
255  if (!surface) {
256  return SDL_InvalidParamError("surface");
257  }
258 
259  if (surface->format->palette && key >= ((Uint32) surface->format->palette->ncolors)) {
260  return SDL_InvalidParamError("key");
261  }
262 
263  if (flag & SDL_RLEACCEL) {
265  }
266 
267  flags = surface->map->info.flags;
268  if (flag) {
269  surface->map->info.flags |= SDL_COPY_COLORKEY;
270  surface->map->info.colorkey = key;
271  if (surface->format->palette) {
272  surface->format->palette->colors[surface->map->info.colorkey].a = SDL_ALPHA_TRANSPARENT;
273  ++surface->format->palette->version;
274  if (!surface->format->palette->version) {
275  surface->format->palette->version = 1;
276  }
277  }
278  } else {
279  if (surface->format->palette) {
280  surface->format->palette->colors[surface->map->info.colorkey].a = SDL_ALPHA_OPAQUE;
281  ++surface->format->palette->version;
282  if (!surface->format->palette->version) {
283  surface->format->palette->version = 1;
284  }
285  }
286  surface->map->info.flags &= ~SDL_COPY_COLORKEY;
287  }
288  if (surface->map->info.flags != flags) {
290  }
291 
292  return 0;
293 }

References SDL_ALPHA_OPAQUE, SDL_ALPHA_TRANSPARENT, SDL_COPY_COLORKEY, SDL_InvalidateMap(), SDL_InvalidParamError, SDL_RLEACCEL, and SDL_SetSurfaceRLE().

Referenced by SDL_ConvertColorkeyToAlpha(), and SDL_ConvertSurface().

◆ SDL_SetSurfaceAlphaMod()

int SDL_SetSurfaceAlphaMod ( SDL_Surface surface,
Uint8  alpha 
)

Set an additional alpha value used in blit operations.

Parameters
surfaceThe surface to update.
alphaThe alpha value multiplied into blit operations.
Returns
0 on success, or -1 if the surface is not valid.
See also
SDL_GetSurfaceAlphaMod()

Definition at line 443 of file SDL_surface.c.

444 {
445  int flags;
446 
447  if (!surface) {
448  return -1;
449  }
450 
451  surface->map->info.a = alpha;
452 
453  flags = surface->map->info.flags;
454  if (alpha != 0xFF) {
455  surface->map->info.flags |= SDL_COPY_MODULATE_ALPHA;
456  } else {
457  surface->map->info.flags &= ~SDL_COPY_MODULATE_ALPHA;
458  }
459  if (surface->map->info.flags != flags) {
461  }
462  return 0;
463 }

References SDL_COPY_MODULATE_ALPHA, and SDL_InvalidateMap().

◆ SDL_SetSurfaceBlendMode()

int SDL_SetSurfaceBlendMode ( SDL_Surface surface,
SDL_BlendMode  blendMode 
)

Set the blend mode used for blit operations.

Parameters
surfaceThe surface to update.
blendModeSDL_BlendMode to use for blit blending.
Returns
0 on success, or -1 if the parameters are not valid.
See also
SDL_GetSurfaceBlendMode()

Definition at line 479 of file SDL_surface.c.

480 {
481  int flags, status;
482 
483  if (!surface) {
484  return -1;
485  }
486 
487  status = 0;
488  flags = surface->map->info.flags;
489  surface->map->info.flags &=
491  switch (blendMode) {
492  case SDL_BLENDMODE_NONE:
493  break;
494  case SDL_BLENDMODE_BLEND:
495  surface->map->info.flags |= SDL_COPY_BLEND;
496  break;
497  case SDL_BLENDMODE_ADD:
498  surface->map->info.flags |= SDL_COPY_ADD;
499  break;
500  case SDL_BLENDMODE_MOD:
501  surface->map->info.flags |= SDL_COPY_MOD;
502  break;
503  default:
504  status = SDL_Unsupported();
505  break;
506  }
507 
508  if (surface->map->info.flags != flags) {
510  }
511 
512  return status;
513 }

References blendMode, SDL_BLENDMODE_ADD, SDL_BLENDMODE_BLEND, SDL_BLENDMODE_MOD, SDL_BLENDMODE_NONE, SDL_COPY_ADD, SDL_COPY_BLEND, SDL_COPY_MOD, SDL_InvalidateMap(), and SDL_Unsupported.

Referenced by SDL_ConvertColorkeyToAlpha(), SDL_ConvertSurface(), and SDL_CreateRGBSurfaceWithFormat().

◆ SDL_SetSurfaceColorMod()

int SDL_SetSurfaceColorMod ( SDL_Surface surface,
Uint8  r,
Uint8  g,
Uint8  b 
)

Set an additional color value used in blit operations.

Parameters
surfaceThe surface to update.
rThe red color value multiplied into blit operations.
gThe green color value multiplied into blit operations.
bThe blue color value multiplied into blit operations.
Returns
0 on success, or -1 if the surface is not valid.
See also
SDL_GetSurfaceColorMod()

Definition at line 398 of file SDL_surface.c.

399 {
400  int flags;
401 
402  if (!surface) {
403  return -1;
404  }
405 
406  surface->map->info.r = r;
407  surface->map->info.g = g;
408  surface->map->info.b = b;
409 
410  flags = surface->map->info.flags;
411  if (r != 0xFF || g != 0xFF || b != 0xFF) {
412  surface->map->info.flags |= SDL_COPY_MODULATE_COLOR;
413  } else {
414  surface->map->info.flags &= ~SDL_COPY_MODULATE_COLOR;
415  }
416  if (surface->map->info.flags != flags) {
418  }
419  return 0;
420 }

References SDL_COPY_MODULATE_COLOR, and SDL_InvalidateMap().

◆ SDL_SetSurfacePalette()

int SDL_SetSurfacePalette ( SDL_Surface surface,
SDL_Palette palette 
)

Set the palette used by a surface.

Returns
0, or -1 if the surface format doesn't use a palette.
Note
A single palette can be shared with many surfaces.

Definition at line 216 of file SDL_surface.c.

217 {
218  if (!surface) {
219  return SDL_SetError("SDL_SetSurfacePalette() passed a NULL surface");
220  }
221  if (SDL_SetPixelFormatPalette(surface->format, palette) < 0) {
222  return -1;
223  }
225 
226  return 0;
227 }

References SDL_InvalidateMap(), SDL_SetError, and SDL_SetPixelFormatPalette.

Referenced by SDL_ConvertSurface(), SDL_CreateRGBSurfaceWithFormat(), and SDL_FreeSurface().

◆ SDL_SetSurfaceRLE()

int SDL_SetSurfaceRLE ( SDL_Surface surface,
int  flag 
)

Sets the RLE acceleration hint for a surface.

Returns
0 on success, or -1 if the surface is not valid
Note
If RLE is enabled, colorkey and alpha blending blits are much faster, but the surface must be locked before directly accessing the pixels.

Definition at line 230 of file SDL_surface.c.

231 {
232  int flags;
233 
234  if (!surface) {
235  return -1;
236  }
237 
238  flags = surface->map->info.flags;
239  if (flag) {
240  surface->map->info.flags |= SDL_COPY_RLE_DESIRED;
241  } else {
242  surface->map->info.flags &= ~SDL_COPY_RLE_DESIRED;
243  }
244  if (surface->map->info.flags != flags) {
246  }
247  return 0;
248 }

References SDL_COPY_RLE_DESIRED, and SDL_InvalidateMap().

Referenced by SDL_ConvertSurface(), and SDL_SetColorKey().

◆ SDL_UnlockSurface()

void SDL_UnlockSurface ( SDL_Surface surface)
See also
SDL_LockSurface()

Definition at line 912 of file SDL_surface.c.

913 {
914  /* Only perform an unlock if we are locked */
915  if (!surface->locked || (--surface->locked > 0)) {
916  return;
917  }
918 
919  /* Update RLE encoded surface with new data */
920  if ((surface->flags & SDL_RLEACCEL) == SDL_RLEACCEL) {
921  surface->flags &= ~SDL_RLEACCEL; /* stop lying */
923  }
924 }

References SDL_RLEACCEL, and SDL_RLESurface().

Referenced by SDL_ConvertColorkeyToAlpha(), and SDL_FreeSurface().

◆ SDL_UpperBlit()

int SDL_UpperBlit ( SDL_Surface src,
const SDL_Rect srcrect,
SDL_Surface dst,
SDL_Rect dstrect 
)

This is the public blit function, SDL_BlitSurface(), and it performs rectangle validation and clipping before passing it to SDL_LowerBlit()

Definition at line 611 of file SDL_surface.c.

613 {
614  SDL_Rect fulldst;
615  int srcx, srcy, w, h;
616 
617  /* Make sure the surfaces aren't locked */
618  if (!src || !dst) {
619  return SDL_SetError("SDL_UpperBlit: passed a NULL surface");
620  }
621  if (src->locked || dst->locked) {
622  return SDL_SetError("Surfaces must not be locked during blit");
623  }
624 
625  /* If the destination rectangle is NULL, use the entire dest surface */
626  if (dstrect == NULL) {
627  fulldst.x = fulldst.y = 0;
628  fulldst.w = dst->w;
629  fulldst.h = dst->h;
630  dstrect = &fulldst;
631  }
632 
633  /* clip the source rectangle to the source surface */
634  if (srcrect) {
635  int maxw, maxh;
636 
637  srcx = srcrect->x;
638  w = srcrect->w;
639  if (srcx < 0) {
640  w += srcx;
641  dstrect->x -= srcx;
642  srcx = 0;
643  }
644  maxw = src->w - srcx;
645  if (maxw < w)
646  w = maxw;
647 
648  srcy = srcrect->y;
649  h = srcrect->h;
650  if (srcy < 0) {
651  h += srcy;
652  dstrect->y -= srcy;
653  srcy = 0;
654  }
655  maxh = src->h - srcy;
656  if (maxh < h)
657  h = maxh;
658 
659  } else {
660  srcx = srcy = 0;
661  w = src->w;
662  h = src->h;
663  }
664 
665  /* clip the destination rectangle against the clip rectangle */
666  {
667  SDL_Rect *clip = &dst->clip_rect;
668  int dx, dy;
669 
670  dx = clip->x - dstrect->x;
671  if (dx > 0) {
672  w -= dx;
673  dstrect->x += dx;
674  srcx += dx;
675  }
676  dx = dstrect->x + w - clip->x - clip->w;
677  if (dx > 0)
678  w -= dx;
679 
680  dy = clip->y - dstrect->y;
681  if (dy > 0) {
682  h -= dy;
683  dstrect->y += dy;
684  srcy += dy;
685  }
686  dy = dstrect->y + h - clip->y - clip->h;
687  if (dy > 0)
688  h -= dy;
689  }
690 
691  /* Switch back to a fast blit if we were previously stretching */
692  if (src->map->info.flags & SDL_COPY_NEAREST) {
693  src->map->info.flags &= ~SDL_COPY_NEAREST;
694  SDL_InvalidateMap(src->map);
695  }
696 
697  if (w > 0 && h > 0) {
698  SDL_Rect sr;
699  sr.x = srcx;
700  sr.y = srcy;
701  sr.w = dstrect->w = w;
702  sr.h = dstrect->h = h;
703  return SDL_LowerBlit(src, &sr, dst, dstrect);
704  }
705  dstrect->w = dstrect->h = 0;
706  return 0;
707 }

References SDL_Rect::h, NULL, SDL_COPY_NEAREST, SDL_InvalidateMap(), SDL_LowerBlit(), SDL_SetError, SDL_Rect::w, SDL_Rect::x, and SDL_Rect::y.

◆ SDL_UpperBlitScaled()

int SDL_UpperBlitScaled ( SDL_Surface src,
const SDL_Rect srcrect,
SDL_Surface dst,
SDL_Rect dstrect 
)

This is the public scaled blit function, SDL_BlitScaled(), and it performs rectangle validation and clipping before passing it to SDL_LowerBlitScaled()

Definition at line 710 of file SDL_surface.c.

712 {
713  double src_x0, src_y0, src_x1, src_y1;
714  double dst_x0, dst_y0, dst_x1, dst_y1;
715  SDL_Rect final_src, final_dst;
716  double scaling_w, scaling_h;
717  int src_w, src_h;
718  int dst_w, dst_h;
719 
720  /* Make sure the surfaces aren't locked */
721  if (!src || !dst) {
722  return SDL_SetError("SDL_UpperBlitScaled: passed a NULL surface");
723  }
724  if (src->locked || dst->locked) {
725  return SDL_SetError("Surfaces must not be locked during blit");
726  }
727 
728  if (NULL == srcrect) {
729  src_w = src->w;
730  src_h = src->h;
731  } else {
732  src_w = srcrect->w;
733  src_h = srcrect->h;
734  }
735 
736  if (NULL == dstrect) {
737  dst_w = dst->w;
738  dst_h = dst->h;
739  } else {
740  dst_w = dstrect->w;
741  dst_h = dstrect->h;
742  }
743 
744  if (dst_w == src_w && dst_h == src_h) {
745  /* No scaling, defer to regular blit */
746  return SDL_BlitSurface(src, srcrect, dst, dstrect);
747  }
748 
749  scaling_w = (double)dst_w / src_w;
750  scaling_h = (double)dst_h / src_h;
751 
752  if (NULL == dstrect) {
753  dst_x0 = 0;
754  dst_y0 = 0;
755  dst_x1 = dst_w - 1;
756  dst_y1 = dst_h - 1;
757  } else {
758  dst_x0 = dstrect->x;
759  dst_y0 = dstrect->y;
760  dst_x1 = dst_x0 + dst_w - 1;
761  dst_y1 = dst_y0 + dst_h - 1;
762  }
763 
764  if (NULL == srcrect) {
765  src_x0 = 0;
766  src_y0 = 0;
767  src_x1 = src_w - 1;
768  src_y1 = src_h - 1;
769  } else {
770  src_x0 = srcrect->x;
771  src_y0 = srcrect->y;
772  src_x1 = src_x0 + src_w - 1;
773  src_y1 = src_y0 + src_h - 1;
774 
775  /* Clip source rectangle to the source surface */
776 
777  if (src_x0 < 0) {
778  dst_x0 -= src_x0 * scaling_w;
779  src_x0 = 0;
780  }
781 
782  if (src_x1 >= src->w) {
783  dst_x1 -= (src_x1 - src->w + 1) * scaling_w;
784  src_x1 = src->w - 1;
785  }
786 
787  if (src_y0 < 0) {
788  dst_y0 -= src_y0 * scaling_h;
789  src_y0 = 0;
790  }
791 
792  if (src_y1 >= src->h) {
793  dst_y1 -= (src_y1 - src->h + 1) * scaling_h;
794  src_y1 = src->h - 1;
795  }
796  }
797 
798  /* Clip destination rectangle to the clip rectangle */
799 
800  /* Translate to clip space for easier calculations */
801  dst_x0 -= dst->clip_rect.x;
802  dst_x1 -= dst->clip_rect.x;
803  dst_y0 -= dst->clip_rect.y;
804  dst_y1 -= dst->clip_rect.y;
805 
806  if (dst_x0 < 0) {
807  src_x0 -= dst_x0 / scaling_w;
808  dst_x0 = 0;
809  }
810 
811  if (dst_x1 >= dst->clip_rect.w) {
812  src_x1 -= (dst_x1 - dst->clip_rect.w + 1) / scaling_w;
813  dst_x1 = dst->clip_rect.w - 1;
814  }
815 
816  if (dst_y0 < 0) {
817  src_y0 -= dst_y0 / scaling_h;
818  dst_y0 = 0;
819  }
820 
821  if (dst_y1 >= dst->clip_rect.h) {
822  src_y1 -= (dst_y1 - dst->clip_rect.h + 1) / scaling_h;
823  dst_y1 = dst->clip_rect.h - 1;
824  }
825 
826  /* Translate back to surface coordinates */
827  dst_x0 += dst->clip_rect.x;
828  dst_x1 += dst->clip_rect.x;
829  dst_y0 += dst->clip_rect.y;
830  dst_y1 += dst->clip_rect.y;
831 
832  final_src.x = (int)SDL_floor(src_x0 + 0.5);
833  final_src.y = (int)SDL_floor(src_y0 + 0.5);
834  final_src.w = (int)SDL_floor(src_x1 + 1 + 0.5) - (int)SDL_floor(src_x0 + 0.5);
835  final_src.h = (int)SDL_floor(src_y1 + 1 + 0.5) - (int)SDL_floor(src_y0 + 0.5);
836 
837  final_dst.x = (int)SDL_floor(dst_x0 + 0.5);
838  final_dst.y = (int)SDL_floor(dst_y0 + 0.5);
839  final_dst.w = (int)SDL_floor(dst_x1 - dst_x0 + 1.5);
840  final_dst.h = (int)SDL_floor(dst_y1 - dst_y0 + 1.5);
841 
842  if (final_dst.w < 0)
843  final_dst.w = 0;
844  if (final_dst.h < 0)
845  final_dst.h = 0;
846 
847  if (dstrect)
848  *dstrect = final_dst;
849 
850  if (final_dst.w == 0 || final_dst.h == 0 ||
851  final_src.w <= 0 || final_src.h <= 0) {
852  /* No-op. */
853  return 0;
854  }
855 
856  return SDL_LowerBlitScaled(src, &final_src, dst, &final_dst);
857 }

References SDL_Rect::h, NULL, SDL_BlitSurface, SDL_floor, SDL_LowerBlitScaled(), SDL_SetError, SDL_Rect::w, SDL_Rect::x, and SDL_Rect::y.

format
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: SDL_opengl.h:1572
Uint8
uint8_t Uint8
Definition: SDL_stdinc.h:179
SDL_memset
#define SDL_memset
Definition: SDL_dynapi_overrides.h:386
SDL_BITSPERPIXEL
#define SDL_BITSPERPIXEL(X)
Definition: SDL_pixels.h:127
SDL_PixelFormat::BytesPerPixel
Uint8 BytesPerPixel
Definition: SDL_pixels.h:320
mask
GLenum GLint GLuint mask
Definition: SDL_opengl_glext.h:657
Uint16
uint16_t Uint16
Definition: SDL_stdinc.h:191
SDL_Palette::ncolors
int ncolors
Definition: SDL_pixels.h:306
blendMode
static SDL_BlendMode blendMode
Definition: testdraw2.c:34
SDL_Color::b
Uint8 b
Definition: SDL_pixels.h:299
SDL_Surface
A collection of pixels used in software blitting.
Definition: SDL_surface.h:70
SDL_LowerBlit
int SDL_LowerBlit(SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect)
Definition: SDL_surface.c:588
SDL_BlitMap
Definition: SDL_blit.h:87
SDL_SoftStretch
#define SDL_SoftStretch
Definition: SDL_dynapi_overrides.h:470
SDL_COPY_RLE_COLORKEY
#define SDL_COPY_RLE_COLORKEY
Definition: SDL_blit.h:42
SDL_RLEACCEL
#define SDL_RLEACCEL
Definition: SDL_surface.h:54
NULL
#define NULL
Definition: begin_code.h:164
surface
EGLSurface surface
Definition: eglext.h:248
SDL_ALPHA_OPAQUE
#define SDL_ALPHA_OPAQUE
Definition: SDL_pixels.h:46
b
GLboolean GLboolean GLboolean b
Definition: SDL_opengl_glext.h:1109
width
GLint GLint GLsizei width
Definition: SDL_opengl.h:1572
SDL_Surface::pixels
void * pixels
Definition: SDL_surface.h:75
g
GLboolean GLboolean g
Definition: SDL_opengl_glext.h:1109
SDL_BlitInfo::b
Uint8 b
Definition: SDL_blit.h:70
SDL_zerop
#define SDL_zerop(x)
Definition: SDL_stdinc.h:417
SDL_UnRLESurface
void SDL_UnRLESurface(SDL_Surface *surface, int recode)
Definition: SDL_RLEaccel.c:1540
SDL_BLENDMODE_BLEND
@ SDL_BLENDMODE_BLEND
Definition: SDL_blendmode.h:44
SDL_Color::r
Uint8 r
Definition: SDL_pixels.h:297
SDL_CreateSurfaceOnStack
static SDL_INLINE SDL_bool SDL_CreateSurfaceOnStack(int width, int height, Uint32 pixel_format, void *pixels, int pitch, SDL_Surface *surface, SDL_PixelFormat *format, SDL_BlitMap *blitmap)
Definition: SDL_surface.c:1114
r
GLdouble GLdouble GLdouble r
Definition: SDL_opengl.h:2079
SDL_MasksToPixelFormatEnum
#define SDL_MasksToPixelFormatEnum
Definition: SDL_dynapi_overrides.h:279
SDL_AllocBlitMap
SDL_BlitMap * SDL_AllocBlitMap(void)
Definition: SDL_pixels.c:952
SDL_InvalidParamError
#define SDL_InvalidParamError(param)
Definition: SDL_error.h:54
SDL_LowerBlitScaled
int SDL_LowerBlitScaled(SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect)
Definition: SDL_surface.c:864
SDL_IntersectRect
#define SDL_IntersectRect
Definition: SDL_dynapi_overrides.h:294
SDL_floor
#define SDL_floor
Definition: SDL_dynapi_overrides.h:431
SDL_DONTFREE
#define SDL_DONTFREE
Definition: SDL_surface.h:55
SDL_COPY_COLORKEY
#define SDL_COPY_COLORKEY
Definition: SDL_blit.h:39
Uint32
uint32_t Uint32
Definition: SDL_stdinc.h:203
SDL_ISPIXELFORMAT_INDEXED
#define SDL_ISPIXELFORMAT_INDEXED(format)
Definition: SDL_pixels.h:134
SDL_BlitMap::info
SDL_BlitInfo info
Definition: SDL_blit.h:92
h
GLfloat GLfloat GLfloat GLfloat h
Definition: SDL_opengl_glext.h:1946
SDL_Rect::x
int x
Definition: SDL_rect.h:66
SDL_AllocFormat
#define SDL_AllocFormat
Definition: SDL_dynapi_overrides.h:280
SDL_ConvertSurface
SDL_Surface * SDL_ConvertSurface(SDL_Surface *surface, const SDL_PixelFormat *format, Uint32 flags)
Definition: SDL_surface.c:939
SDL_Rect::w
int w
Definition: SDL_rect.h:67
row
GLenum GLenum void * row
Definition: SDL_opengl_glext.h:3138
SDL_Color::a
Uint8 a
Definition: SDL_pixels.h:300
SDL_COPY_RLE_DESIRED
#define SDL_COPY_RLE_DESIRED
Definition: SDL_blit.h:41
SDL_PREALLOC
#define SDL_PREALLOC
Definition: SDL_surface.h:53
alpha
GLfloat GLfloat GLfloat alpha
Definition: SDL_opengl_glext.h:412
dst
GLenum GLenum dst
Definition: SDL_opengl_glext.h:1737
SDL_SetSurfaceBlendMode
int SDL_SetSurfaceBlendMode(SDL_Surface *surface, SDL_BlendMode blendMode)
Set the blend mode used for blit operations.
Definition: SDL_surface.c:479
SDL_memcpy
#define SDL_memcpy
Definition: SDL_dynapi_overrides.h:387
SDL_Palette::colors
SDL_Color * colors
Definition: SDL_pixels.h:307
SDL_MapSurface
int SDL_MapSurface(SDL_Surface *src, SDL_Surface *dst)
Definition: SDL_pixels.c:991
x
GLint GLint GLint GLint GLint x
Definition: SDL_opengl.h:1574
SDL_Color::g
Uint8 g
Definition: SDL_pixels.h:298
SDL_Rect::y
int y
Definition: SDL_rect.h:66
SDL_memcmp
#define SDL_memcmp
Definition: SDL_dynapi_overrides.h:389
SDL_Rect::h
int h
Definition: SDL_rect.h:67
SDL_free
#define SDL_free
Definition: SDL_dynapi_overrides.h:377
SDL_BlitSurface
#define SDL_BlitSurface
Definition: SDL_surface.h:483
SDL_CreateRGBSurface
SDL_Surface * SDL_CreateRGBSurface(Uint32 flags, int width, int height, int depth, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask)
Definition: SDL_surface.c:153
SDL_BLENDMODE_NONE
@ SDL_BLENDMODE_NONE
Definition: SDL_blendmode.h:42
height
GLint GLint GLsizei GLsizei height
Definition: SDL_opengl.h:1572
SDL_COPY_BLEND
#define SDL_COPY_BLEND
Definition: SDL_blit.h:36
SDL_RLESurface
int SDL_RLESurface(SDL_Surface *surface)
Definition: SDL_RLEaccel.c:1403
rect
SDL_Rect rect
Definition: testrelative.c:27
SDL_PixelFormat::palette
SDL_Palette * palette
Definition: SDL_pixels.h:318
key
GLuint64 key
Definition: gl2ext.h:2192
SDL_SetColorKey
int SDL_SetColorKey(SDL_Surface *surface, int flag, Uint32 key)
Sets the color key (transparent pixel) in a blittable surface.
Definition: SDL_surface.c:251
SDL_FreeFormat
#define SDL_FreeFormat
Definition: SDL_dynapi_overrides.h:281
SDL_BlitInfo::g
Uint8 g
Definition: SDL_blit.h:70
SDL_Surface::map
struct SDL_BlitMap * map
Definition: SDL_surface.h:88
SDL_PIXELFORMAT_UNKNOWN
@ SDL_PIXELFORMAT_UNKNOWN
Definition: SDL_pixels.h:173
SDL_TRUE
@ SDL_TRUE
Definition: SDL_stdinc.h:164
SDL_PixelFormat
Definition: SDL_pixels.h:316
SDL_BlitInfo::a
Uint8 a
Definition: SDL_blit.h:70
depth
GLint GLint GLsizei GLsizei GLsizei depth
Definition: SDL_opengl.h:1572
SDL_UnlockSurface
void SDL_UnlockSurface(SDL_Surface *surface)
Definition: SDL_surface.c:912
pixels
GLint GLint GLsizei GLsizei GLsizei GLint GLenum GLenum const GLvoid * pixels
Definition: SDL_opengl.h:1572
SDL_ConvertColorkeyToAlpha
static void SDL_ConvertColorkeyToAlpha(SDL_Surface *surface)
Definition: SDL_surface.c:328
SDL_COPY_MODULATE_ALPHA
#define SDL_COPY_MODULATE_ALPHA
Definition: SDL_blit.h:35
SDL_SetClipRect
SDL_bool SDL_SetClipRect(SDL_Surface *surface, const SDL_Rect *rect)
Definition: SDL_surface.c:545
SDL_CreateRGBSurfaceWithFormat
SDL_Surface * SDL_CreateRGBSurfaceWithFormat(Uint32 flags, int width, int height, int depth, Uint32 format)
Definition: SDL_surface.c:66
SDL_OutOfMemory
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
SDL_FreePalette
#define SDL_FreePalette
Definition: SDL_dynapi_overrides.h:285
size
GLsizeiptr size
Definition: SDL_opengl_glext.h:537
y
GLint GLint GLint GLint GLint GLint y
Definition: SDL_opengl.h:1574
SDL_COPY_RLE_ALPHAKEY
#define SDL_COPY_RLE_ALPHAKEY
Definition: SDL_blit.h:43
SDL_SetSurfacePalette
int SDL_SetSurfacePalette(SDL_Surface *surface, SDL_Palette *palette)
Set the palette used by a surface.
Definition: SDL_surface.c:216
SDL_AllocPalette
#define SDL_AllocPalette
Definition: SDL_dynapi_overrides.h:282
SDL_calloc
#define SDL_calloc
Definition: SDL_dynapi_overrides.h:375
SDL_ConvertPixels_YUV_to_YUV
int SDL_ConvertPixels_YUV_to_YUV(int width, int height, Uint32 src_format, const void *src, int src_pitch, Uint32 dst_format, void *dst, int dst_pitch)
Definition: SDL_yuv.c:1810
SDL_CalculatePitch
static int SDL_CalculatePitch(Uint32 format, int width)
Definition: SDL_surface.c:41
SDL_Palette
Definition: SDL_pixels.h:305
src
GLenum src
Definition: SDL_opengl_glext.h:1737
SDL_SetSurfaceRLE
int SDL_SetSurfaceRLE(SDL_Surface *surface, int flag)
Sets the RLE acceleration hint for a surface.
Definition: SDL_surface.c:230
Sint64
int64_t Sint64
Definition: SDL_stdinc.h:210
SDL_ISPIXELFORMAT_FOURCC
#define SDL_ISPIXELFORMAT_FOURCC(format)
Definition: SDL_pixels.h:167
SDL_SetError
#define SDL_SetError
Definition: SDL_dynapi_overrides.h:30
SDL_BYTESPERPIXEL
#define SDL_BYTESPERPIXEL(X)
Definition: SDL_pixels.h:128
SDL_InvalidateMap
void SDL_InvalidateMap(SDL_BlitMap *map)
Definition: SDL_pixels.c:972
SDL_COPY_NEAREST
#define SDL_COPY_NEAREST
Definition: SDL_blit.h:40
SDL_Rect
A rectangle, with the origin at the upper left.
Definition: SDL_rect.h:65
SDL_MAX_SINT32
#define SDL_MAX_SINT32
A signed 32-bit integer type.
Definition: SDL_stdinc.h:195
SDL_BlitInfo::r
Uint8 r
Definition: SDL_blit.h:70
SDL_COPY_ADD
#define SDL_COPY_ADD
Definition: SDL_blit.h:37
SDL_Color
Definition: SDL_pixels.h:296
SDL_FreeSurface
void SDL_FreeSurface(SDL_Surface *surface)
Definition: SDL_surface.c:1213
SDL_COPY_MOD
#define SDL_COPY_MOD
Definition: SDL_blit.h:38
SDL_FillRect
#define SDL_FillRect
Definition: SDL_dynapi_overrides.h:466
SDL_bool
SDL_bool
Definition: SDL_stdinc.h:162
SDL_BlitInfo::flags
int flags
Definition: SDL_blit.h:68
SDL_COPY_MODULATE_COLOR
#define SDL_COPY_MODULATE_COLOR
Definition: SDL_blit.h:34
SDL_ConvertPixels_RGB_to_YUV
int SDL_ConvertPixels_RGB_to_YUV(int width, int height, Uint32 src_format, const void *src, int src_pitch, Uint32 dst_format, void *dst, int dst_pitch)
Definition: SDL_yuv.c:784
SDL_ALPHA_TRANSPARENT
#define SDL_ALPHA_TRANSPARENT
Definition: SDL_pixels.h:47
SDL_FALSE
@ SDL_FALSE
Definition: SDL_stdinc.h:163
SDL_Unsupported
#define SDL_Unsupported()
Definition: SDL_error.h:53
SDL_FreeBlitMap
void SDL_FreeBlitMap(SDL_BlitMap *map)
Definition: SDL_pixels.c:1077
SDL_malloc
#define SDL_malloc
Definition: SDL_dynapi_overrides.h:374
void
SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char const char SDL_SCANF_FORMAT_STRING const char return SDL_ThreadFunction const char void return Uint32 return Uint32 void
Definition: SDL_dynapi_procs.h:89
flags
GLbitfield flags
Definition: SDL_opengl_glext.h:1480
SDL_SetPixelFormatPalette
#define SDL_SetPixelFormatPalette
Definition: SDL_dynapi_overrides.h:283
SDL_LockSurface
int SDL_LockSurface(SDL_Surface *surface)
Sets up a surface for directly accessing the pixels.
Definition: SDL_surface.c:891
SDL_Surface::format
SDL_PixelFormat * format
Definition: SDL_surface.h:72
i
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
Definition: SDL_x11sym.h:50
SDL_BLENDMODE_MOD
@ SDL_BLENDMODE_MOD
Definition: SDL_blendmode.h:50
SDL_BLENDMODE_ADD
@ SDL_BLENDMODE_ADD
Definition: SDL_blendmode.h:47
SDL_ConvertPixels_YUV_to_RGB
int SDL_ConvertPixels_YUV_to_RGB(int width, int height, Uint32 src_format, const void *src, int src_pitch, Uint32 dst_format, void *dst, int dst_pitch)
Definition: SDL_yuv.c:395
w
GLubyte GLubyte GLubyte GLubyte w
Definition: SDL_opengl_glext.h:731
SDL_InitFormat
int SDL_InitFormat(SDL_PixelFormat *format, Uint32 pixel_format)
Definition: SDL_pixels.c:537