SDL 2.0
SDL_surface.c
Go to the documentation of this file.
1/*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2019 Sam Lantinga <slouken@libsdl.org>
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20*/
21#include "../SDL_internal.h"
22
23#include "SDL_video.h"
24#include "SDL_sysvideo.h"
25#include "SDL_blit.h"
26#include "SDL_RLEaccel_c.h"
27#include "SDL_pixels_c.h"
28#include "SDL_yuv_c.h"
29
30
31/* Check to make sure we can safely check multiplication of surface w and pitch and it won't overflow size_t */
32SDL_COMPILE_TIME_ASSERT(surface_size_assumptions,
33 sizeof(int) == sizeof(Sint32) && sizeof(size_t) >= sizeof(Sint32));
34
35/* Public routines */
36
37/*
38 * Calculate the pad-aligned scanline width of a surface
39 */
40static int
42{
43 int pitch;
44
45 /* Surface should be 4-byte aligned for speed */
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}
60
61/*
62 * Create an empty RGB surface of the appropriate depth using the given
63 * enum SDL_PIXELFORMAT_* format
64 */
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
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 }
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... */
119 return NULL;
120 }
121
122 surface->pixels = SDL_SIMDAlloc((size_t)size);
123 if (!surface->pixels) {
126 return NULL;
127 }
128 surface->flags |= SDL_SIMD_ALIGNED;
129 /* This is important for bitmaps */
130 SDL_memset(surface->pixels, 0, surface->h * surface->pitch);
131 }
132
133 /* Allocate an empty mapping */
134 surface->map = SDL_AllocBlitMap();
135 if (!surface->map) {
137 return NULL;
138 }
139
140 /* By default surface with an alpha mask are set up for blending */
141 if (surface->format->Amask) {
143 }
144
145 /* The surface is ready to go */
146 surface->refcount = 1;
147 return surface;
148}
149
150/*
151 * Create an empty RGB surface of the appropriate depth
152 */
155 int width, int height, int depth,
156 Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask)
157{
159
160 /* Get the pixel format */
161 format = SDL_MasksToPixelFormatEnum(depth, Rmask, Gmask, Bmask, Amask);
163 SDL_SetError("Unknown pixel format");
164 return NULL;
165 }
166
168}
169
170/*
171 * Create an RGB surface from an existing memory buffer
172 */
175 int width, int height, int depth, int pitch,
176 Uint32 Rmask, Uint32 Gmask, Uint32 Bmask,
177 Uint32 Amask)
178{
180
181 surface = SDL_CreateRGBSurface(0, 0, 0, depth, Rmask, Gmask, Bmask, Amask);
182 if (surface != NULL) {
183 surface->flags |= SDL_PREALLOC;
184 surface->pixels = pixels;
185 surface->w = width;
186 surface->h = height;
187 surface->pitch = pitch;
189 }
190 return surface;
191}
192
193/*
194 * Create an RGB surface from an existing memory buffer using the given given
195 * enum SDL_PIXELFORMAT_* format
196 */
199 int width, int height, int depth, int pitch,
201{
203
205 if (surface != NULL) {
206 surface->flags |= SDL_PREALLOC;
207 surface->pixels = pixels;
208 surface->w = width;
209 surface->h = height;
210 surface->pitch = pitch;
212 }
213 return surface;
214}
215
216int
218{
219 if (!surface) {
220 return SDL_SetError("SDL_SetSurfacePalette() passed a NULL surface");
221 }
222 if (SDL_SetPixelFormatPalette(surface->format, palette) < 0) {
223 return -1;
224 }
226
227 return 0;
228}
229
230int
232{
233 int flags;
234
235 if (!surface) {
236 return -1;
237 }
238
239 flags = surface->map->info.flags;
240 if (flag) {
241 surface->map->info.flags |= SDL_COPY_RLE_DESIRED;
242 } else {
243 surface->map->info.flags &= ~SDL_COPY_RLE_DESIRED;
244 }
245 if (surface->map->info.flags != flags) {
247 }
248 return 0;
249}
250
251int
253{
254 int flags;
255
256 if (!surface) {
257 return SDL_InvalidParamError("surface");
258 }
259
260 if (surface->format->palette && key >= ((Uint32) surface->format->palette->ncolors)) {
261 return SDL_InvalidParamError("key");
262 }
263
264 if (flag & SDL_RLEACCEL) {
266 }
267
268 flags = surface->map->info.flags;
269 if (flag) {
270 surface->map->info.flags |= SDL_COPY_COLORKEY;
271 surface->map->info.colorkey = key;
272 } else {
273 surface->map->info.flags &= ~SDL_COPY_COLORKEY;
274 }
275 if (surface->map->info.flags != flags) {
277 }
278
279 return 0;
280}
281
284{
285 if (!surface) {
286 return SDL_FALSE;
287 }
288
289 if (!(surface->map->info.flags & SDL_COPY_COLORKEY)) {
290 return SDL_FALSE;
291 }
292
293 return SDL_TRUE;
294}
295
296int
298{
299 if (!surface) {
300 return SDL_InvalidParamError("surface");
301 }
302
303 if (!(surface->map->info.flags & SDL_COPY_COLORKEY)) {
304 return SDL_SetError("Surface doesn't have a colorkey");
305 }
306
307 if (key) {
308 *key = surface->map->info.colorkey;
309 }
310 return 0;
311}
312
313/* This is a fairly slow function to switch from colorkey to alpha */
314static void
316{
317 int x, y;
318
319 if (!surface) {
320 return;
321 }
322
323 if (!(surface->map->info.flags & SDL_COPY_COLORKEY) ||
324 !surface->format->Amask) {
325 return;
326 }
327
329
330 switch (surface->format->BytesPerPixel) {
331 case 2:
332 {
333 Uint16 *row, *spot;
334 Uint16 ckey = (Uint16) surface->map->info.colorkey;
335 Uint16 mask = (Uint16) (~surface->format->Amask);
336
337 /* Ignore, or not, alpha in colorkey comparison */
338 if (ignore_alpha) {
339 ckey &= mask;
340 row = (Uint16 *) surface->pixels;
341 for (y = surface->h; y--;) {
342 spot = row;
343 for (x = surface->w; x--;) {
344 if ((*spot & mask) == ckey) {
345 *spot &= mask;
346 }
347 ++spot;
348 }
349 row += surface->pitch / 2;
350 }
351 } else {
352 row = (Uint16 *) surface->pixels;
353 for (y = surface->h; y--;) {
354 spot = row;
355 for (x = surface->w; x--;) {
356 if (*spot == ckey) {
357 *spot &= mask;
358 }
359 ++spot;
360 }
361 row += surface->pitch / 2;
362 }
363 }
364 }
365 break;
366 case 3:
367 /* FIXME */
368 break;
369 case 4:
370 {
371 Uint32 *row, *spot;
372 Uint32 ckey = surface->map->info.colorkey;
373 Uint32 mask = ~surface->format->Amask;
374
375 /* Ignore, or not, alpha in colorkey comparison */
376 if (ignore_alpha) {
377 ckey &= mask;
378 row = (Uint32 *) surface->pixels;
379 for (y = surface->h; y--;) {
380 spot = row;
381 for (x = surface->w; x--;) {
382 if ((*spot & mask) == ckey) {
383 *spot &= mask;
384 }
385 ++spot;
386 }
387 row += surface->pitch / 4;
388 }
389 } else {
390 row = (Uint32 *) surface->pixels;
391 for (y = surface->h; y--;) {
392 spot = row;
393 for (x = surface->w; x--;) {
394 if (*spot == ckey) {
395 *spot &= mask;
396 }
397 ++spot;
398 }
399 row += surface->pitch / 4;
400 }
401 }
402 }
403 break;
404 }
405
407
410}
411
412int
414{
415 int flags;
416
417 if (!surface) {
418 return -1;
419 }
420
421 surface->map->info.r = r;
422 surface->map->info.g = g;
423 surface->map->info.b = b;
424
425 flags = surface->map->info.flags;
426 if (r != 0xFF || g != 0xFF || b != 0xFF) {
427 surface->map->info.flags |= SDL_COPY_MODULATE_COLOR;
428 } else {
429 surface->map->info.flags &= ~SDL_COPY_MODULATE_COLOR;
430 }
431 if (surface->map->info.flags != flags) {
433 }
434 return 0;
435}
436
437
438int
440{
441 if (!surface) {
442 return -1;
443 }
444
445 if (r) {
446 *r = surface->map->info.r;
447 }
448 if (g) {
449 *g = surface->map->info.g;
450 }
451 if (b) {
452 *b = surface->map->info.b;
453 }
454 return 0;
455}
456
457int
459{
460 int flags;
461
462 if (!surface) {
463 return -1;
464 }
465
466 surface->map->info.a = alpha;
467
468 flags = surface->map->info.flags;
469 if (alpha != 0xFF) {
470 surface->map->info.flags |= SDL_COPY_MODULATE_ALPHA;
471 } else {
472 surface->map->info.flags &= ~SDL_COPY_MODULATE_ALPHA;
473 }
474 if (surface->map->info.flags != flags) {
476 }
477 return 0;
478}
479
480int
482{
483 if (!surface) {
484 return -1;
485 }
486
487 if (alpha) {
488 *alpha = surface->map->info.a;
489 }
490 return 0;
491}
492
493int
495{
496 int flags, status;
497
498 if (!surface) {
499 return -1;
500 }
501
502 status = 0;
503 flags = surface->map->info.flags;
504 surface->map->info.flags &=
506 switch (blendMode) {
508 break;
510 surface->map->info.flags |= SDL_COPY_BLEND;
511 break;
513 surface->map->info.flags |= SDL_COPY_ADD;
514 break;
516 surface->map->info.flags |= SDL_COPY_MOD;
517 break;
518 default:
519 status = SDL_Unsupported();
520 break;
521 }
522
523 if (surface->map->info.flags != flags) {
525 }
526
527 return status;
528}
529
530int
532{
533 if (!surface) {
534 return -1;
535 }
536
537 if (!blendMode) {
538 return 0;
539 }
540
541 switch (surface->map->
542 info.flags & (SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD)) {
543 case SDL_COPY_BLEND:
545 break;
546 case SDL_COPY_ADD:
548 break;
549 case SDL_COPY_MOD:
551 break;
552 default:
554 break;
555 }
556 return 0;
557}
558
561{
562 SDL_Rect full_rect;
563
564 /* Don't do anything if there's no surface to act on */
565 if (!surface) {
566 return SDL_FALSE;
567 }
568
569 /* Set up the full surface rectangle */
570 full_rect.x = 0;
571 full_rect.y = 0;
572 full_rect.w = surface->w;
573 full_rect.h = surface->h;
574
575 /* Set the clipping rectangle */
576 if (!rect) {
577 surface->clip_rect = full_rect;
578 return SDL_TRUE;
579 }
580 return SDL_IntersectRect(rect, &full_rect, &surface->clip_rect);
581}
582
583void
585{
586 if (surface && rect) {
587 *rect = surface->clip_rect;
588 }
589}
590
591/*
592 * Set up a blit between two surfaces -- split into three parts:
593 * The upper part, SDL_UpperBlit(), performs clipping and rectangle
594 * verification. The lower part is a pointer to a low level
595 * accelerated blitting function.
596 *
597 * These parts are separated out and each used internally by this
598 * library in the optimimum places. They are exported so that if
599 * you know exactly what you are doing, you can optimize your code
600 * by calling the one(s) you need.
601 */
602int
604 SDL_Surface * dst, SDL_Rect * dstrect)
605{
606 /* Check to make sure the blit mapping is valid */
607 if ((src->map->dst != dst) ||
608 (dst->format->palette &&
609 src->map->dst_palette_version != dst->format->palette->version) ||
610 (src->format->palette &&
611 src->map->src_palette_version != src->format->palette->version)) {
612 if (SDL_MapSurface(src, dst) < 0) {
613 return (-1);
614 }
615 /* just here for debugging */
616/* printf */
617/* ("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", */
618/* src, dst->flags, src->map->info.flags, dst, dst->flags, */
619/* dst->map->info.flags, src->map->blit); */
620 }
621 return (src->map->blit(src, srcrect, dst, dstrect));
622}
623
624
625int
627 SDL_Surface * dst, SDL_Rect * dstrect)
628{
629 SDL_Rect fulldst;
630 int srcx, srcy, w, h;
631
632 /* Make sure the surfaces aren't locked */
633 if (!src || !dst) {
634 return SDL_SetError("SDL_UpperBlit: passed a NULL surface");
635 }
636 if (src->locked || dst->locked) {
637 return SDL_SetError("Surfaces must not be locked during blit");
638 }
639
640 /* If the destination rectangle is NULL, use the entire dest surface */
641 if (dstrect == NULL) {
642 fulldst.x = fulldst.y = 0;
643 fulldst.w = dst->w;
644 fulldst.h = dst->h;
645 dstrect = &fulldst;
646 }
647
648 /* clip the source rectangle to the source surface */
649 if (srcrect) {
650 int maxw, maxh;
651
652 srcx = srcrect->x;
653 w = srcrect->w;
654 if (srcx < 0) {
655 w += srcx;
656 dstrect->x -= srcx;
657 srcx = 0;
658 }
659 maxw = src->w - srcx;
660 if (maxw < w)
661 w = maxw;
662
663 srcy = srcrect->y;
664 h = srcrect->h;
665 if (srcy < 0) {
666 h += srcy;
667 dstrect->y -= srcy;
668 srcy = 0;
669 }
670 maxh = src->h - srcy;
671 if (maxh < h)
672 h = maxh;
673
674 } else {
675 srcx = srcy = 0;
676 w = src->w;
677 h = src->h;
678 }
679
680 /* clip the destination rectangle against the clip rectangle */
681 {
682 SDL_Rect *clip = &dst->clip_rect;
683 int dx, dy;
684
685 dx = clip->x - dstrect->x;
686 if (dx > 0) {
687 w -= dx;
688 dstrect->x += dx;
689 srcx += dx;
690 }
691 dx = dstrect->x + w - clip->x - clip->w;
692 if (dx > 0)
693 w -= dx;
694
695 dy = clip->y - dstrect->y;
696 if (dy > 0) {
697 h -= dy;
698 dstrect->y += dy;
699 srcy += dy;
700 }
701 dy = dstrect->y + h - clip->y - clip->h;
702 if (dy > 0)
703 h -= dy;
704 }
705
706 /* Switch back to a fast blit if we were previously stretching */
707 if (src->map->info.flags & SDL_COPY_NEAREST) {
708 src->map->info.flags &= ~SDL_COPY_NEAREST;
710 }
711
712 if (w > 0 && h > 0) {
713 SDL_Rect sr;
714 sr.x = srcx;
715 sr.y = srcy;
716 sr.w = dstrect->w = w;
717 sr.h = dstrect->h = h;
718 return SDL_LowerBlit(src, &sr, dst, dstrect);
719 }
720 dstrect->w = dstrect->h = 0;
721 return 0;
722}
723
724int
726 SDL_Surface * dst, SDL_Rect * dstrect)
727{
728 double src_x0, src_y0, src_x1, src_y1;
729 double dst_x0, dst_y0, dst_x1, dst_y1;
730 SDL_Rect final_src, final_dst;
731 double scaling_w, scaling_h;
732 int src_w, src_h;
733 int dst_w, dst_h;
734
735 /* Make sure the surfaces aren't locked */
736 if (!src || !dst) {
737 return SDL_SetError("SDL_UpperBlitScaled: passed a NULL surface");
738 }
739 if (src->locked || dst->locked) {
740 return SDL_SetError("Surfaces must not be locked during blit");
741 }
742
743 if (NULL == srcrect) {
744 src_w = src->w;
745 src_h = src->h;
746 } else {
747 src_w = srcrect->w;
748 src_h = srcrect->h;
749 }
750
751 if (NULL == dstrect) {
752 dst_w = dst->w;
753 dst_h = dst->h;
754 } else {
755 dst_w = dstrect->w;
756 dst_h = dstrect->h;
757 }
758
759 if (dst_w == src_w && dst_h == src_h) {
760 /* No scaling, defer to regular blit */
761 return SDL_BlitSurface(src, srcrect, dst, dstrect);
762 }
763
764 scaling_w = (double)dst_w / src_w;
765 scaling_h = (double)dst_h / src_h;
766
767 if (NULL == dstrect) {
768 dst_x0 = 0;
769 dst_y0 = 0;
770 dst_x1 = dst_w - 1;
771 dst_y1 = dst_h - 1;
772 } else {
773 dst_x0 = dstrect->x;
774 dst_y0 = dstrect->y;
775 dst_x1 = dst_x0 + dst_w - 1;
776 dst_y1 = dst_y0 + dst_h - 1;
777 }
778
779 if (NULL == srcrect) {
780 src_x0 = 0;
781 src_y0 = 0;
782 src_x1 = src_w - 1;
783 src_y1 = src_h - 1;
784 } else {
785 src_x0 = srcrect->x;
786 src_y0 = srcrect->y;
787 src_x1 = src_x0 + src_w - 1;
788 src_y1 = src_y0 + src_h - 1;
789
790 /* Clip source rectangle to the source surface */
791
792 if (src_x0 < 0) {
793 dst_x0 -= src_x0 * scaling_w;
794 src_x0 = 0;
795 }
796
797 if (src_x1 >= src->w) {
798 dst_x1 -= (src_x1 - src->w + 1) * scaling_w;
799 src_x1 = src->w - 1;
800 }
801
802 if (src_y0 < 0) {
803 dst_y0 -= src_y0 * scaling_h;
804 src_y0 = 0;
805 }
806
807 if (src_y1 >= src->h) {
808 dst_y1 -= (src_y1 - src->h + 1) * scaling_h;
809 src_y1 = src->h - 1;
810 }
811 }
812
813 /* Clip destination rectangle to the clip rectangle */
814
815 /* Translate to clip space for easier calculations */
816 dst_x0 -= dst->clip_rect.x;
817 dst_x1 -= dst->clip_rect.x;
818 dst_y0 -= dst->clip_rect.y;
819 dst_y1 -= dst->clip_rect.y;
820
821 if (dst_x0 < 0) {
822 src_x0 -= dst_x0 / scaling_w;
823 dst_x0 = 0;
824 }
825
826 if (dst_x1 >= dst->clip_rect.w) {
827 src_x1 -= (dst_x1 - dst->clip_rect.w + 1) / scaling_w;
828 dst_x1 = dst->clip_rect.w - 1;
829 }
830
831 if (dst_y0 < 0) {
832 src_y0 -= dst_y0 / scaling_h;
833 dst_y0 = 0;
834 }
835
836 if (dst_y1 >= dst->clip_rect.h) {
837 src_y1 -= (dst_y1 - dst->clip_rect.h + 1) / scaling_h;
838 dst_y1 = dst->clip_rect.h - 1;
839 }
840
841 /* Translate back to surface coordinates */
842 dst_x0 += dst->clip_rect.x;
843 dst_x1 += dst->clip_rect.x;
844 dst_y0 += dst->clip_rect.y;
845 dst_y1 += dst->clip_rect.y;
846
847 final_src.x = (int)SDL_floor(src_x0 + 0.5);
848 final_src.y = (int)SDL_floor(src_y0 + 0.5);
849 final_src.w = (int)SDL_floor(src_x1 + 1 + 0.5) - (int)SDL_floor(src_x0 + 0.5);
850 final_src.h = (int)SDL_floor(src_y1 + 1 + 0.5) - (int)SDL_floor(src_y0 + 0.5);
851
852 final_dst.x = (int)SDL_floor(dst_x0 + 0.5);
853 final_dst.y = (int)SDL_floor(dst_y0 + 0.5);
854 final_dst.w = (int)SDL_floor(dst_x1 - dst_x0 + 1.5);
855 final_dst.h = (int)SDL_floor(dst_y1 - dst_y0 + 1.5);
856
857 if (final_dst.w < 0)
858 final_dst.w = 0;
859 if (final_dst.h < 0)
860 final_dst.h = 0;
861
862 if (dstrect)
863 *dstrect = final_dst;
864
865 if (final_dst.w == 0 || final_dst.h == 0 ||
866 final_src.w <= 0 || final_src.h <= 0) {
867 /* No-op. */
868 return 0;
869 }
870
871 return SDL_LowerBlitScaled(src, &final_src, dst, &final_dst);
872}
873
874/**
875 * This is a semi-private blit function and it performs low-level surface
876 * scaled blitting only.
877 */
878int
880 SDL_Surface * dst, SDL_Rect * dstrect)
881{
882 static const Uint32 complex_copy_flags = (
886 );
887
888 if (!(src->map->info.flags & SDL_COPY_NEAREST)) {
889 src->map->info.flags |= SDL_COPY_NEAREST;
891 }
892
893 if ( !(src->map->info.flags & complex_copy_flags) &&
894 src->format->format == dst->format->format &&
895 !SDL_ISPIXELFORMAT_INDEXED(src->format->format) ) {
896 return SDL_SoftStretch( src, srcrect, dst, dstrect );
897 } else {
898 return SDL_LowerBlit( src, srcrect, dst, dstrect );
899 }
900}
901
902/*
903 * Lock a surface to directly access the pixels
904 */
905int
907{
908 if (!surface->locked) {
909 /* Perform the lock */
910 if (surface->flags & SDL_RLEACCEL) {
912 surface->flags |= SDL_RLEACCEL; /* save accel'd state */
913 }
914 }
915
916 /* Increment the surface lock count, for recursive locks */
917 ++surface->locked;
918
919 /* Ready to go.. */
920 return (0);
921}
922
923/*
924 * Unlock a previously locked surface
925 */
926void
928{
929 /* Only perform an unlock if we are locked */
930 if (!surface->locked || (--surface->locked > 0)) {
931 return;
932 }
933
934 /* Update RLE encoded surface with new data */
935 if ((surface->flags & SDL_RLEACCEL) == SDL_RLEACCEL) {
936 surface->flags &= ~SDL_RLEACCEL; /* stop lying */
938 }
939}
940
941/*
942 * Creates a new surface identical to the existing surface
943 */
946{
947 return SDL_ConvertSurface(surface, surface->format, surface->flags);
948}
949
950/*
951 * Convert a surface into the specified pixel format.
952 */
956{
957 SDL_Surface *convert;
958 Uint32 copy_flags;
959 SDL_Color copy_color;
960 SDL_Rect bounds;
961 int ret;
962
963 if (!surface) {
964 SDL_InvalidParamError("surface");
965 return NULL;
966 }
967 if (!format) {
968 SDL_InvalidParamError("format");
969 return NULL;
970 }
971
972 /* Check for empty destination palette! (results in empty image) */
973 if (format->palette != NULL) {
974 int i;
975 for (i = 0; i < format->palette->ncolors; ++i) {
976 if ((format->palette->colors[i].r != 0xFF) ||
977 (format->palette->colors[i].g != 0xFF) ||
978 (format->palette->colors[i].b != 0xFF))
979 break;
980 }
981 if (i == format->palette->ncolors) {
982 SDL_SetError("Empty destination palette");
983 return (NULL);
984 }
985 }
986
987 /* Create a new surface with the desired format */
988 convert = SDL_CreateRGBSurface(flags, surface->w, surface->h,
989 format->BitsPerPixel, format->Rmask,
990 format->Gmask, format->Bmask,
991 format->Amask);
992 if (convert == NULL) {
993 return (NULL);
994 }
995
996 /* Copy the palette if any */
997 if (format->palette && convert->format->palette) {
998 SDL_memcpy(convert->format->palette->colors,
999 format->palette->colors,
1000 format->palette->ncolors * sizeof(SDL_Color));
1001 convert->format->palette->ncolors = format->palette->ncolors;
1002 }
1003
1004 /* Save the original copy flags */
1005 copy_flags = surface->map->info.flags;
1006 copy_color.r = surface->map->info.r;
1007 copy_color.g = surface->map->info.g;
1008 copy_color.b = surface->map->info.b;
1009 copy_color.a = surface->map->info.a;
1010 surface->map->info.r = 0xFF;
1011 surface->map->info.g = 0xFF;
1012 surface->map->info.b = 0xFF;
1013 surface->map->info.a = 0xFF;
1014 surface->map->info.flags = 0;
1016
1017 /* Copy over the image data */
1018 bounds.x = 0;
1019 bounds.y = 0;
1020 bounds.w = surface->w;
1021 bounds.h = surface->h;
1022 ret = SDL_LowerBlit(surface, &bounds, convert, &bounds);
1023
1024 /* Clean up the original surface, and update converted surface */
1025 convert->map->info.r = copy_color.r;
1026 convert->map->info.g = copy_color.g;
1027 convert->map->info.b = copy_color.b;
1028 convert->map->info.a = copy_color.a;
1029 convert->map->info.flags =
1030 (copy_flags &
1034 surface->map->info.r = copy_color.r;
1035 surface->map->info.g = copy_color.g;
1036 surface->map->info.b = copy_color.b;
1037 surface->map->info.a = copy_color.a;
1038 surface->map->info.flags = copy_flags;
1040
1041 /* SDL_LowerBlit failed, and so the conversion */
1042 if (ret < 0) {
1043 SDL_FreeSurface(convert);
1044 return NULL;
1045 }
1046
1047 if (copy_flags & SDL_COPY_COLORKEY) {
1048 SDL_bool set_colorkey_by_color = SDL_FALSE;
1049 SDL_bool ignore_alpha = SDL_TRUE; /* Ignore, or not, alpha in colorkey comparison */
1050
1051 if (surface->format->palette) {
1052 if (format->palette &&
1053 surface->format->palette->ncolors <= format->palette->ncolors &&
1054 (SDL_memcmp(surface->format->palette->colors, format->palette->colors,
1055 surface->format->palette->ncolors * sizeof(SDL_Color)) == 0)) {
1056 /* The palette is identical, just set the same colorkey */
1057 SDL_SetColorKey(convert, 1, surface->map->info.colorkey);
1058 } else if (format->Amask) {
1059 set_colorkey_by_color = SDL_TRUE;
1060 ignore_alpha = SDL_FALSE;
1061 } else {
1062 set_colorkey_by_color = SDL_TRUE;
1063 }
1064 } else {
1065 set_colorkey_by_color = SDL_TRUE;
1066 }
1067
1068 if (set_colorkey_by_color) {
1069 SDL_Surface *tmp;
1070 SDL_Surface *tmp2;
1071 int converted_colorkey = 0;
1072
1073 /* Create a dummy surface to get the colorkey converted */
1074 tmp = SDL_CreateRGBSurface(0, 1, 1,
1075 surface->format->BitsPerPixel, surface->format->Rmask,
1076 surface->format->Gmask, surface->format->Bmask,
1077 surface->format->Amask);
1078
1079 /* Share the palette, if any */
1080 if (surface->format->palette) {
1082 }
1083
1084 SDL_FillRect(tmp, NULL, surface->map->info.colorkey);
1085
1086 tmp->map->info.flags &= ~SDL_COPY_COLORKEY;
1087
1088 /* Convertion of the colorkey */
1089 tmp2 = SDL_ConvertSurface(tmp, format, 0);
1090
1091 /* Get the converted colorkey */
1092 SDL_memcpy(&converted_colorkey, tmp2->pixels, tmp2->format->BytesPerPixel);
1093
1094 SDL_FreeSurface(tmp);
1095 SDL_FreeSurface(tmp2);
1096
1097 /* Set the converted colorkey on the new surface */
1098 SDL_SetColorKey(convert, 1, converted_colorkey);
1099
1100 /* This is needed when converting for 3D texture upload */
1101 SDL_ConvertColorkeyToAlpha(convert, ignore_alpha);
1102 }
1103 }
1104 SDL_SetClipRect(convert, &surface->clip_rect);
1105
1106 /* Enable alpha blending by default if the new surface has an
1107 * alpha channel or alpha modulation */
1108 if ((surface->format->Amask && format->Amask) ||
1109 (copy_flags & SDL_COPY_MODULATE_ALPHA)) {
1111 }
1112 if ((copy_flags & SDL_COPY_RLE_DESIRED) || (flags & SDL_RLEACCEL)) {
1114 }
1115
1116 /* We're ready to go! */
1117 return (convert);
1118}
1119
1122 Uint32 flags)
1123{
1124 SDL_PixelFormat *fmt;
1125 SDL_Surface *convert = NULL;
1126
1127 fmt = SDL_AllocFormat(pixel_format);
1128 if (fmt) {
1129 convert = SDL_ConvertSurface(surface, fmt, flags);
1130 SDL_FreeFormat(fmt);
1131 }
1132 return convert;
1133}
1134
1135/*
1136 * Create a surface on the stack for quick blit operations
1137 */
1138static SDL_INLINE SDL_bool
1140 void * pixels, int pitch, SDL_Surface * surface,
1141 SDL_PixelFormat * format, SDL_BlitMap * blitmap)
1142{
1143 if (SDL_ISPIXELFORMAT_INDEXED(pixel_format)) {
1144 SDL_SetError("Indexed pixel formats not supported");
1145 return SDL_FALSE;
1146 }
1147 if (SDL_InitFormat(format, pixel_format) < 0) {
1148 return SDL_FALSE;
1149 }
1150
1152 surface->flags = SDL_PREALLOC;
1153 surface->format = format;
1154 surface->pixels = pixels;
1155 surface->w = width;
1156 surface->h = height;
1157 surface->pitch = pitch;
1158 /* We don't actually need to set up the clip rect for our purposes */
1159 /* SDL_SetClipRect(surface, NULL); */
1160
1161 /* Allocate an empty mapping */
1162 SDL_zerop(blitmap);
1163 blitmap->info.r = 0xFF;
1164 blitmap->info.g = 0xFF;
1165 blitmap->info.b = 0xFF;
1166 blitmap->info.a = 0xFF;
1167 surface->map = blitmap;
1168
1169 /* The surface is ready to go */
1170 surface->refcount = 1;
1171 return SDL_TRUE;
1172}
1173
1174/*
1175 * Copy a block of pixels of one format to another format
1176 */
1178 Uint32 src_format, const void * src, int src_pitch,
1179 Uint32 dst_format, void * dst, int dst_pitch)
1180{
1181 SDL_Surface src_surface, dst_surface;
1182 SDL_PixelFormat src_fmt, dst_fmt;
1183 SDL_BlitMap src_blitmap, dst_blitmap;
1184 SDL_Rect rect;
1185 void *nonconst_src = (void *) src;
1186
1187 /* Check to make sure we are blitting somewhere, so we don't crash */
1188 if (!dst) {
1189 return SDL_InvalidParamError("dst");
1190 }
1191 if (!dst_pitch) {
1192 return SDL_InvalidParamError("dst_pitch");
1193 }
1194
1195 if (SDL_ISPIXELFORMAT_FOURCC(src_format) && SDL_ISPIXELFORMAT_FOURCC(dst_format)) {
1196 return SDL_ConvertPixels_YUV_to_YUV(width, height, src_format, src, src_pitch, dst_format, dst, dst_pitch);
1197 } else if (SDL_ISPIXELFORMAT_FOURCC(src_format)) {
1198 return SDL_ConvertPixels_YUV_to_RGB(width, height, src_format, src, src_pitch, dst_format, dst, dst_pitch);
1199 } else if (SDL_ISPIXELFORMAT_FOURCC(dst_format)) {
1200 return SDL_ConvertPixels_RGB_to_YUV(width, height, src_format, src, src_pitch, dst_format, dst, dst_pitch);
1201 }
1202
1203 /* Fast path for same format copy */
1204 if (src_format == dst_format) {
1205 int i;
1206 const int bpp = SDL_BYTESPERPIXEL(src_format);
1207 width *= bpp;
1208 for (i = height; i--;) {
1210 src = (const Uint8*)src + src_pitch;
1211 dst = (Uint8*)dst + dst_pitch;
1212 }
1213 return 0;
1214 }
1215
1216 if (!SDL_CreateSurfaceOnStack(width, height, src_format, nonconst_src,
1217 src_pitch,
1218 &src_surface, &src_fmt, &src_blitmap)) {
1219 return -1;
1220 }
1221 if (!SDL_CreateSurfaceOnStack(width, height, dst_format, dst, dst_pitch,
1222 &dst_surface, &dst_fmt, &dst_blitmap)) {
1223 return -1;
1224 }
1225
1226 /* Set up the rect and go! */
1227 rect.x = 0;
1228 rect.y = 0;
1229 rect.w = width;
1230 rect.h = height;
1231 return SDL_LowerBlit(&src_surface, &rect, &dst_surface, &rect);
1232}
1233
1234/*
1235 * Free a surface created by the above function.
1236 */
1237void
1239{
1240 if (surface == NULL) {
1241 return;
1242 }
1243 if (surface->flags & SDL_DONTFREE) {
1244 return;
1245 }
1247
1248 if (--surface->refcount > 0) {
1249 return;
1250 }
1251 while (surface->locked > 0) {
1253 }
1254 if (surface->flags & SDL_RLEACCEL) {
1256 }
1257 if (surface->format) {
1259 SDL_FreeFormat(surface->format);
1260 surface->format = NULL;
1261 }
1262 if (surface->flags & SDL_PREALLOC) {
1263 /* Don't free */
1264 } else if (surface->flags & SDL_SIMD_ALIGNED) {
1265 /* Free aligned */
1266 SDL_SIMDFree(surface->pixels);
1267 } else {
1268 /* Normal */
1269 SDL_free(surface->pixels);
1270 }
1271 if (surface->map) {
1273 }
1275}
1276
1277/* vi: set ts=4 sw=4 expandtab: */
void SDL_UnRLESurface(SDL_Surface *surface, int recode)
int SDL_RLESurface(SDL_Surface *surface)
SDL_BlendMode
The blend mode used in SDL_RenderCopy() and drawing operations.
Definition: SDL_blendmode.h:41
@ SDL_BLENDMODE_NONE
Definition: SDL_blendmode.h:42
@ SDL_BLENDMODE_ADD
Definition: SDL_blendmode.h:47
@ SDL_BLENDMODE_BLEND
Definition: SDL_blendmode.h:44
@ SDL_BLENDMODE_MOD
Definition: SDL_blendmode.h:50
#define SDL_COPY_RLE_ALPHAKEY
Definition: SDL_blit.h:43
#define SDL_COPY_NEAREST
Definition: SDL_blit.h:40
#define SDL_COPY_RLE_DESIRED
Definition: SDL_blit.h:41
#define SDL_COPY_MODULATE_COLOR
Definition: SDL_blit.h:34
#define SDL_COPY_ADD
Definition: SDL_blit.h:37
#define SDL_COPY_COLORKEY
Definition: SDL_blit.h:39
#define SDL_COPY_MODULATE_ALPHA
Definition: SDL_blit.h:35
#define SDL_COPY_RLE_COLORKEY
Definition: SDL_blit.h:42
#define SDL_COPY_MOD
Definition: SDL_blit.h:38
#define SDL_COPY_BLEND
Definition: SDL_blit.h:36
#define SDL_SetError
#define SDL_memset
#define SDL_SoftStretch
#define SDL_AllocPalette
#define SDL_FreePalette
#define SDL_FreeFormat
#define SDL_floor
#define SDL_SetPixelFormatPalette
#define SDL_SIMDAlloc
#define SDL_AllocFormat
#define SDL_free
#define SDL_memcmp
#define SDL_MasksToPixelFormatEnum
#define SDL_memcpy
#define SDL_SIMDFree
#define SDL_IntersectRect
#define SDL_calloc
#define SDL_FillRect
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
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
#define SDL_Unsupported()
Definition: SDL_error.h:53
#define SDL_InvalidParamError(param)
Definition: SDL_error.h:54
GLint GLint GLint GLint GLint GLint y
Definition: SDL_opengl.h:1574
GLint GLint GLsizei GLsizei GLsizei GLint GLenum GLenum const GLvoid * pixels
Definition: SDL_opengl.h:1572
GLint GLint GLsizei width
Definition: SDL_opengl.h:1572
GLint GLint GLsizei GLsizei GLsizei depth
Definition: SDL_opengl.h:1572
GLdouble GLdouble GLdouble r
Definition: SDL_opengl.h:2079
GLint GLint GLint GLint GLint x
Definition: SDL_opengl.h:1574
GLint GLint GLsizei GLsizei height
Definition: SDL_opengl.h:1572
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: SDL_opengl.h:1572
GLboolean GLboolean GLboolean b
GLenum src
GLenum GLenum dst
GLenum GLenum void * row
GLboolean GLboolean g
GLsizeiptr size
GLbitfield flags
GLfloat GLfloat GLfloat alpha
GLenum GLint GLuint mask
GLfloat GLfloat GLfloat GLfloat h
GLubyte GLubyte GLubyte GLubyte w
int SDL_InitFormat(SDL_PixelFormat *format, Uint32 pixel_format)
Definition: SDL_pixels.c:537
void SDL_FreeBlitMap(SDL_BlitMap *map)
Definition: SDL_pixels.c:1077
void SDL_InvalidateMap(SDL_BlitMap *map)
Definition: SDL_pixels.c:972
SDL_BlitMap * SDL_AllocBlitMap(void)
Definition: SDL_pixels.c:952
int SDL_MapSurface(SDL_Surface *src, SDL_Surface *dst)
Definition: SDL_pixels.c:991
#define SDL_BYTESPERPIXEL(X)
Definition: SDL_pixels.h:128
#define SDL_BITSPERPIXEL(X)
Definition: SDL_pixels.h:127
#define SDL_ISPIXELFORMAT_INDEXED(format)
Definition: SDL_pixels.h:134
@ SDL_PIXELFORMAT_UNKNOWN
Definition: SDL_pixels.h:173
#define SDL_ISPIXELFORMAT_FOURCC(format)
Definition: SDL_pixels.h:167
SDL_bool
Definition: SDL_stdinc.h:162
@ SDL_TRUE
Definition: SDL_stdinc.h:164
@ SDL_FALSE
Definition: SDL_stdinc.h:163
uint32_t Uint32
Definition: SDL_stdinc.h:203
int32_t Sint32
Definition: SDL_stdinc.h:197
#define SDL_zerop(x)
Definition: SDL_stdinc.h:417
#define SDL_MAX_SINT32
A signed 32-bit integer type.
Definition: SDL_stdinc.h:195
uint16_t Uint16
Definition: SDL_stdinc.h:191
uint8_t Uint8
Definition: SDL_stdinc.h:179
int64_t Sint64
Definition: SDL_stdinc.h:210
SDL_Surface * SDL_CreateRGBSurface(Uint32 flags, int width, int height, int depth, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask)
Definition: SDL_surface.c:154
static int SDL_CalculatePitch(Uint32 format, int width)
Definition: SDL_surface.c:41
int SDL_GetSurfaceBlendMode(SDL_Surface *surface, SDL_BlendMode *blendMode)
Get the blend mode used for blit operations.
Definition: SDL_surface.c:531
int SDL_UpperBlitScaled(SDL_Surface *src, const SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect)
Definition: SDL_surface.c:725
static void SDL_ConvertColorkeyToAlpha(SDL_Surface *surface, SDL_bool ignore_alpha)
Definition: SDL_surface.c:315
int SDL_LowerBlit(SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect)
Definition: SDL_surface.c:603
SDL_Surface * SDL_ConvertSurface(SDL_Surface *surface, const SDL_PixelFormat *format, Uint32 flags)
Definition: SDL_surface.c:954
int SDL_SetSurfacePalette(SDL_Surface *surface, SDL_Palette *palette)
Set the palette used by a surface.
Definition: SDL_surface.c:217
SDL_Surface * SDL_DuplicateSurface(SDL_Surface *surface)
Definition: SDL_surface.c:945
SDL_bool SDL_SetClipRect(SDL_Surface *surface, const SDL_Rect *rect)
Definition: SDL_surface.c:560
SDL_bool SDL_HasColorKey(SDL_Surface *surface)
Returns whether the surface has a color key.
Definition: SDL_surface.c:283
int SDL_SetSurfaceRLE(SDL_Surface *surface, int flag)
Sets the RLE acceleration hint for a surface.
Definition: SDL_surface.c:231
SDL_COMPILE_TIME_ASSERT(surface_size_assumptions, sizeof(int)==sizeof(Sint32) &&sizeof(size_t) >=sizeof(Sint32))
int SDL_LockSurface(SDL_Surface *surface)
Sets up a surface for directly accessing the pixels.
Definition: SDL_surface.c:906
int SDL_GetSurfaceAlphaMod(SDL_Surface *surface, Uint8 *alpha)
Get the additional alpha value used in blit operations.
Definition: SDL_surface.c:481
SDL_Surface * SDL_CreateRGBSurfaceFrom(void *pixels, int width, int height, int depth, int pitch, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask)
Definition: SDL_surface.c:174
void SDL_GetClipRect(SDL_Surface *surface, SDL_Rect *rect)
Definition: SDL_surface.c:584
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:1139
int SDL_SetSurfaceColorMod(SDL_Surface *surface, Uint8 r, Uint8 g, Uint8 b)
Set an additional color value used in blit operations.
Definition: SDL_surface.c:413
void SDL_UnlockSurface(SDL_Surface *surface)
Definition: SDL_surface.c:927
int SDL_SetColorKey(SDL_Surface *surface, int flag, Uint32 key)
Sets the color key (transparent pixel) in a blittable surface.
Definition: SDL_surface.c:252
int SDL_GetSurfaceColorMod(SDL_Surface *surface, Uint8 *r, Uint8 *g, Uint8 *b)
Get the additional color value used in blit operations.
Definition: SDL_surface.c:439
int SDL_GetColorKey(SDL_Surface *surface, Uint32 *key)
Gets the color key (transparent pixel) in a blittable surface.
Definition: SDL_surface.c:297
int SDL_SetSurfaceAlphaMod(SDL_Surface *surface, Uint8 alpha)
Set an additional alpha value used in blit operations.
Definition: SDL_surface.c:458
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.
Definition: SDL_surface.c:1177
int SDL_LowerBlitScaled(SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect)
Definition: SDL_surface.c:879
void SDL_FreeSurface(SDL_Surface *surface)
Definition: SDL_surface.c:1238
SDL_Surface * SDL_CreateRGBSurfaceWithFormat(Uint32 flags, int width, int height, int depth, Uint32 format)
Definition: SDL_surface.c:66
SDL_Surface * SDL_ConvertSurfaceFormat(SDL_Surface *surface, Uint32 pixel_format, Uint32 flags)
Definition: SDL_surface.c:1121
int SDL_SetSurfaceBlendMode(SDL_Surface *surface, SDL_BlendMode blendMode)
Set the blend mode used for blit operations.
Definition: SDL_surface.c:494
SDL_Surface * SDL_CreateRGBSurfaceWithFormatFrom(void *pixels, int width, int height, int depth, int pitch, Uint32 format)
Definition: SDL_surface.c:198
int SDL_UpperBlit(SDL_Surface *src, const SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect)
Definition: SDL_surface.c:626
#define SDL_DONTFREE
Definition: SDL_surface.h:55
#define SDL_RLEACCEL
Definition: SDL_surface.h:54
#define SDL_SIMD_ALIGNED
Definition: SDL_surface.h:56
#define SDL_PREALLOC
Definition: SDL_surface.h:53
#define SDL_BlitSurface
Definition: SDL_surface.h:484
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
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
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
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
#define NULL
Definition: begin_code.h:167
#define SDL_INLINE
Definition: begin_code.h:134
EGLSurface surface
Definition: eglext.h:248
GLuint64 key
Definition: gl2ext.h:2192
Uint8 r
Definition: SDL_blit.h:70
Uint8 a
Definition: SDL_blit.h:70
Uint32 colorkey
Definition: SDL_blit.h:69
Uint8 g
Definition: SDL_blit.h:70
Uint8 b
Definition: SDL_blit.h:70
SDL_BlitInfo info
Definition: SDL_blit.h:92
Uint8 r
Definition: SDL_pixels.h:297
Uint8 b
Definition: SDL_pixels.h:299
Uint8 a
Definition: SDL_pixels.h:300
Uint8 g
Definition: SDL_pixels.h:298
SDL_Color * colors
Definition: SDL_pixels.h:307
Uint8 BytesPerPixel
Definition: SDL_pixels.h:320
SDL_Palette * palette
Definition: SDL_pixels.h:318
A rectangle, with the origin at the upper left (integer).
Definition: SDL_rect.h:78
int h
Definition: SDL_rect.h:80
int w
Definition: SDL_rect.h:80
int y
Definition: SDL_rect.h:79
int x
Definition: SDL_rect.h:79
A collection of pixels used in software blitting.
Definition: SDL_surface.h:71
SDL_PixelFormat * format
Definition: SDL_surface.h:73
struct SDL_BlitMap * map
Definition: SDL_surface.h:89
SDL_Rect clip_rect
Definition: SDL_surface.h:86
void * pixels
Definition: SDL_surface.h:76
static SDL_BlendMode blendMode
Definition: testdraw2.c:34
SDL_Rect rect
Definition: testrelative.c:27