zenilib  0.5.3.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
SDL_surface.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2013 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_config.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 
29 
30 /* Public routines */
31 /*
32  * Create an empty RGB surface of the appropriate depth
33  */
36  int width, int height, int depth,
37  Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask)
38 {
40  Uint32 format;
41 
42  /* The flags are no longer used, make the compiler happy */
43  (void)flags;
44 
45  /* Get the pixel format */
46  format = SDL_MasksToPixelFormatEnum(depth, Rmask, Gmask, Bmask, Amask);
47  if (format == SDL_PIXELFORMAT_UNKNOWN) {
48  SDL_SetError("Unknown pixel format");
49  return NULL;
50  }
51 
52  /* Allocate the surface */
53  surface = (SDL_Surface *) SDL_calloc(1, sizeof(*surface));
54  if (surface == NULL) {
56  return NULL;
57  }
58 
59  surface->format = SDL_AllocFormat(format);
60  if (!surface->format) {
61  SDL_FreeSurface(surface);
62  return NULL;
63  }
64  surface->w = width;
65  surface->h = height;
66  surface->pitch = SDL_CalculatePitch(surface);
67  SDL_SetClipRect(surface, NULL);
68 
69  if (SDL_ISPIXELFORMAT_INDEXED(surface->format->format)) {
70  SDL_Palette *palette =
71  SDL_AllocPalette((1 << surface->format->BitsPerPixel));
72  if (!palette) {
73  SDL_FreeSurface(surface);
74  return NULL;
75  }
76  if (palette->ncolors == 2) {
77  /* Create a black and white bitmap palette */
78  palette->colors[0].r = 0xFF;
79  palette->colors[0].g = 0xFF;
80  palette->colors[0].b = 0xFF;
81  palette->colors[1].r = 0x00;
82  palette->colors[1].g = 0x00;
83  palette->colors[1].b = 0x00;
84  }
85  SDL_SetSurfacePalette(surface, palette);
86  SDL_FreePalette(palette);
87  }
88 
89  /* Get the pixels */
90  if (surface->w && surface->h) {
91  surface->pixels = SDL_malloc(surface->h * surface->pitch);
92  if (!surface->pixels) {
93  SDL_FreeSurface(surface);
95  return NULL;
96  }
97  /* This is important for bitmaps */
98  SDL_memset(surface->pixels, 0, surface->h * surface->pitch);
99  }
100 
101  /* Allocate an empty mapping */
102  surface->map = SDL_AllocBlitMap();
103  if (!surface->map) {
104  SDL_FreeSurface(surface);
105  return NULL;
106  }
107 
108  /* By default surface with an alpha mask are set up for blending */
109  if (Amask) {
111  }
112 
113  /* The surface is ready to go */
114  surface->refcount = 1;
115  return surface;
116 }
117 
118 /*
119  * Create an RGB surface from an existing memory buffer
120  */
121 SDL_Surface *
123  int width, int height, int depth, int pitch,
124  Uint32 Rmask, Uint32 Gmask, Uint32 Bmask,
125  Uint32 Amask)
126 {
128 
129  surface =
130  SDL_CreateRGBSurface(0, 0, 0, depth, Rmask, Gmask, Bmask, Amask);
131  if (surface != NULL) {
132  surface->flags |= SDL_PREALLOC;
133  surface->pixels = pixels;
134  surface->w = width;
135  surface->h = height;
136  surface->pitch = pitch;
137  SDL_SetClipRect(surface, NULL);
138  }
139  return surface;
140 }
141 
142 int
144 {
145  if (!surface) {
146  return SDL_SetError("SDL_SetSurfacePalette() passed a NULL surface");
147  }
148  return SDL_SetPixelFormatPalette(surface->format, palette);
149 }
150 
151 int
153 {
154  int flags;
155 
156  if (!surface) {
157  return -1;
158  }
159 
160  flags = surface->map->info.flags;
161  if (flag) {
162  surface->map->info.flags |= SDL_COPY_RLE_DESIRED;
163  } else {
164  surface->map->info.flags &= ~SDL_COPY_RLE_DESIRED;
165  }
166  if (surface->map->info.flags != flags) {
167  SDL_InvalidateMap(surface->map);
168  }
169  return 0;
170 }
171 
172 int
174 {
175  int flags;
176 
177  if (!surface) {
178  return SDL_InvalidParamError("surface");
179  }
180 
181  if (surface->format->palette && key >= ((Uint32) surface->format->palette->ncolors)) {
182  return SDL_InvalidParamError("key");
183  }
184 
185  if (flag & SDL_RLEACCEL) {
186  SDL_SetSurfaceRLE(surface, 1);
187  }
188 
189  flags = surface->map->info.flags;
190  if (flag) {
191  surface->map->info.flags |= SDL_COPY_COLORKEY;
192  surface->map->info.colorkey = key;
193  if (surface->format->palette) {
194  surface->format->palette->colors[surface->map->info.colorkey].a = SDL_ALPHA_TRANSPARENT;
195  ++surface->format->palette->version;
196  if (!surface->format->palette->version) {
197  surface->format->palette->version = 1;
198  }
199  }
200  } else {
201  if (surface->format->palette) {
202  surface->format->palette->colors[surface->map->info.colorkey].a = SDL_ALPHA_OPAQUE;
203  ++surface->format->palette->version;
204  if (!surface->format->palette->version) {
205  surface->format->palette->version = 1;
206  }
207  }
208  surface->map->info.flags &= ~SDL_COPY_COLORKEY;
209  }
210  if (surface->map->info.flags != flags) {
211  SDL_InvalidateMap(surface->map);
212  }
213 
214  return 0;
215 }
216 
217 int
219 {
220  if (!surface) {
221  return -1;
222  }
223 
224  if (!(surface->map->info.flags & SDL_COPY_COLORKEY)) {
225  return -1;
226  }
227 
228  if (key) {
229  *key = surface->map->info.colorkey;
230  }
231  return 0;
232 }
233 
234 /* This is a fairly slow function to switch from colorkey to alpha */
235 static void
237 {
238  int x, y;
239 
240  if (!surface) {
241  return;
242  }
243 
244  if (!(surface->map->info.flags & SDL_COPY_COLORKEY) ||
245  !surface->format->Amask) {
246  return;
247  }
248 
249  SDL_LockSurface(surface);
250 
251  switch (surface->format->BytesPerPixel) {
252  case 2:
253  {
254  Uint16 *row, *spot;
255  Uint16 ckey = (Uint16) surface->map->info.colorkey;
256  Uint16 mask = (Uint16) (~surface->format->Amask);
257 
258  /* Ignore alpha in colorkey comparison */
259  ckey &= mask;
260  row = (Uint16 *) surface->pixels;
261  for (y = surface->h; y--;) {
262  spot = row;
263  for (x = surface->w; x--;) {
264  if ((*spot & mask) == ckey) {
265  *spot &= mask;
266  }
267  ++spot;
268  }
269  row += surface->pitch / 2;
270  }
271  }
272  break;
273  case 3:
274  /* FIXME */
275  break;
276  case 4:
277  {
278  Uint32 *row, *spot;
279  Uint32 ckey = surface->map->info.colorkey;
280  Uint32 mask = ~surface->format->Amask;
281 
282  /* Ignore alpha in colorkey comparison */
283  ckey &= mask;
284  row = (Uint32 *) surface->pixels;
285  for (y = surface->h; y--;) {
286  spot = row;
287  for (x = surface->w; x--;) {
288  if ((*spot & mask) == ckey) {
289  *spot &= mask;
290  }
291  ++spot;
292  }
293  row += surface->pitch / 4;
294  }
295  }
296  break;
297  }
298 
299  SDL_UnlockSurface(surface);
300 
301  SDL_SetColorKey(surface, 0, 0);
303 }
304 
305 int
307 {
308  int flags;
309 
310  if (!surface) {
311  return -1;
312  }
313 
314  surface->map->info.r = r;
315  surface->map->info.g = g;
316  surface->map->info.b = b;
317 
318  flags = surface->map->info.flags;
319  if (r != 0xFF || g != 0xFF || b != 0xFF) {
320  surface->map->info.flags |= SDL_COPY_MODULATE_COLOR;
321  } else {
322  surface->map->info.flags &= ~SDL_COPY_MODULATE_COLOR;
323  }
324  if (surface->map->info.flags != flags) {
325  SDL_InvalidateMap(surface->map);
326  }
327  return 0;
328 }
329 
330 
331 int
333 {
334  if (!surface) {
335  return -1;
336  }
337 
338  if (r) {
339  *r = surface->map->info.r;
340  }
341  if (g) {
342  *g = surface->map->info.g;
343  }
344  if (b) {
345  *b = surface->map->info.b;
346  }
347  return 0;
348 }
349 
350 int
352 {
353  int flags;
354 
355  if (!surface) {
356  return -1;
357  }
358 
359  surface->map->info.a = alpha;
360 
361  flags = surface->map->info.flags;
362  if (alpha != 0xFF) {
363  surface->map->info.flags |= SDL_COPY_MODULATE_ALPHA;
364  } else {
365  surface->map->info.flags &= ~SDL_COPY_MODULATE_ALPHA;
366  }
367  if (surface->map->info.flags != flags) {
368  SDL_InvalidateMap(surface->map);
369  }
370  return 0;
371 }
372 
373 int
375 {
376  if (!surface) {
377  return -1;
378  }
379 
380  if (alpha) {
381  *alpha = surface->map->info.a;
382  }
383  return 0;
384 }
385 
386 int
388 {
389  int flags, status;
390 
391  if (!surface) {
392  return -1;
393  }
394 
395  status = 0;
396  flags = surface->map->info.flags;
397  surface->map->info.flags &=
399  switch (blendMode) {
400  case SDL_BLENDMODE_NONE:
401  break;
402  case SDL_BLENDMODE_BLEND:
403  surface->map->info.flags |= SDL_COPY_BLEND;
404  break;
405  case SDL_BLENDMODE_ADD:
406  surface->map->info.flags |= SDL_COPY_ADD;
407  break;
408  case SDL_BLENDMODE_MOD:
409  surface->map->info.flags |= SDL_COPY_MOD;
410  break;
411  default:
412  status = SDL_Unsupported();
413  break;
414  }
415 
416  if (surface->map->info.flags != flags) {
417  SDL_InvalidateMap(surface->map);
418  }
419 
420  return status;
421 }
422 
423 int
425 {
426  if (!surface) {
427  return -1;
428  }
429 
430  if (!blendMode) {
431  return 0;
432  }
433 
434  switch (surface->map->
435  info.flags & (SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD)) {
436  case SDL_COPY_BLEND:
437  *blendMode = SDL_BLENDMODE_BLEND;
438  break;
439  case SDL_COPY_ADD:
440  *blendMode = SDL_BLENDMODE_ADD;
441  break;
442  case SDL_COPY_MOD:
443  *blendMode = SDL_BLENDMODE_MOD;
444  break;
445  default:
446  *blendMode = SDL_BLENDMODE_NONE;
447  break;
448  }
449  return 0;
450 }
451 
452 SDL_bool
454 {
455  SDL_Rect full_rect;
456 
457  /* Don't do anything if there's no surface to act on */
458  if (!surface) {
459  return SDL_FALSE;
460  }
461 
462  /* Set up the full surface rectangle */
463  full_rect.x = 0;
464  full_rect.y = 0;
465  full_rect.w = surface->w;
466  full_rect.h = surface->h;
467 
468  /* Set the clipping rectangle */
469  if (!rect) {
470  surface->clip_rect = full_rect;
471  return SDL_TRUE;
472  }
473  return SDL_IntersectRect(rect, &full_rect, &surface->clip_rect);
474 }
475 
476 void
478 {
479  if (surface && rect) {
480  *rect = surface->clip_rect;
481  }
482 }
483 
484 /*
485  * Set up a blit between two surfaces -- split into three parts:
486  * The upper part, SDL_UpperBlit(), performs clipping and rectangle
487  * verification. The lower part is a pointer to a low level
488  * accelerated blitting function.
489  *
490  * These parts are separated out and each used internally by this
491  * library in the optimimum places. They are exported so that if
492  * you know exactly what you are doing, you can optimize your code
493  * by calling the one(s) you need.
494  */
495 int
497  SDL_Surface * dst, SDL_Rect * dstrect)
498 {
499  /* Check to make sure the blit mapping is valid */
500  if ((src->map->dst != dst) ||
501  (dst->format->palette &&
502  src->map->dst_palette_version != dst->format->palette->version) ||
503  (src->format->palette &&
504  src->map->src_palette_version != src->format->palette->version)) {
505  if (SDL_MapSurface(src, dst) < 0) {
506  return (-1);
507  }
508  /* just here for debugging */
509 /* printf */
510 /* ("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", */
511 /* src, dst->flags, src->map->info.flags, dst, dst->flags, */
512 /* dst->map->info.flags, src->map->blit); */
513  }
514  return (src->map->blit(src, srcrect, dst, dstrect));
515 }
516 
517 
518 int
520  SDL_Surface * dst, SDL_Rect * dstrect)
521 {
522  SDL_Rect fulldst;
523  int srcx, srcy, w, h;
524 
525  /* Make sure the surfaces aren't locked */
526  if (!src || !dst) {
527  return SDL_SetError("SDL_UpperBlit: passed a NULL surface");
528  }
529  if (src->locked || dst->locked) {
530  return SDL_SetError("Surfaces must not be locked during blit");
531  }
532 
533  /* If the destination rectangle is NULL, use the entire dest surface */
534  if (dstrect == NULL) {
535  fulldst.x = fulldst.y = 0;
536  fulldst.w = dst->w;
537  fulldst.h = dst->h;
538  dstrect = &fulldst;
539  }
540 
541  /* clip the source rectangle to the source surface */
542  if (srcrect) {
543  int maxw, maxh;
544 
545  srcx = srcrect->x;
546  w = srcrect->w;
547  if (srcx < 0) {
548  w += srcx;
549  dstrect->x -= srcx;
550  srcx = 0;
551  }
552  maxw = src->w - srcx;
553  if (maxw < w)
554  w = maxw;
555 
556  srcy = srcrect->y;
557  h = srcrect->h;
558  if (srcy < 0) {
559  h += srcy;
560  dstrect->y -= srcy;
561  srcy = 0;
562  }
563  maxh = src->h - srcy;
564  if (maxh < h)
565  h = maxh;
566 
567  } else {
568  srcx = srcy = 0;
569  w = src->w;
570  h = src->h;
571  }
572 
573  /* clip the destination rectangle against the clip rectangle */
574  {
575  SDL_Rect *clip = &dst->clip_rect;
576  int dx, dy;
577 
578  dx = clip->x - dstrect->x;
579  if (dx > 0) {
580  w -= dx;
581  dstrect->x += dx;
582  srcx += dx;
583  }
584  dx = dstrect->x + w - clip->x - clip->w;
585  if (dx > 0)
586  w -= dx;
587 
588  dy = clip->y - dstrect->y;
589  if (dy > 0) {
590  h -= dy;
591  dstrect->y += dy;
592  srcy += dy;
593  }
594  dy = dstrect->y + h - clip->y - clip->h;
595  if (dy > 0)
596  h -= dy;
597  }
598 
599  if (w > 0 && h > 0) {
600  SDL_Rect sr;
601  sr.x = srcx;
602  sr.y = srcy;
603  sr.w = dstrect->w = w;
604  sr.h = dstrect->h = h;
605  return SDL_LowerBlit(src, &sr, dst, dstrect);
606  }
607  dstrect->w = dstrect->h = 0;
608  return 0;
609 }
610 
611 int
613  SDL_Surface * dst, SDL_Rect * dstrect)
614 {
615  SDL_Rect final_src, final_dst, fulldst;
616 
617  /* Make sure the surfaces aren't locked */
618  if (!src || !dst) {
619  return SDL_SetError("SDL_UpperBlitScaled: 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  final_src.x = srcrect->x;
638  final_src.w = srcrect->w;
639  if (final_src.x < 0) {
640  final_src.w += final_src.x;
641  final_src.x = 0;
642  }
643  maxw = src->w - final_src.x;
644  if (maxw < final_src.w)
645  final_src.w = maxw;
646 
647  final_src.y = srcrect->y;
648  final_src.h = srcrect->h;
649  if (final_src.y < 0) {
650  final_src.h += final_src.y;
651  final_src.y = 0;
652  }
653  maxh = src->h - final_src.y;
654  if (maxh < final_src.h)
655  final_src.h = maxh;
656 
657  } else {
658  final_src.x = final_src.y = 0;
659  final_src.w = src->w;
660  final_src.h = src->h;
661  }
662 
663  /* clip the destination rectangle against the clip rectangle */
664  if (dstrect) {
665  int maxw, maxh;
666 
667  final_dst.x = dstrect->x;
668  final_dst.w = dstrect->w;
669  if (final_dst.x < 0) {
670  final_dst.w += final_dst.x;
671  final_dst.x = 0;
672  }
673  maxw = dst->w - final_dst.x;
674  if (maxw < final_dst.w)
675  final_dst.w = maxw;
676 
677  final_dst.y = dstrect->y;
678  final_dst.h = dstrect->h;
679  if (final_dst.y < 0) {
680  final_dst.h += final_dst.y;
681  final_dst.y = 0;
682  }
683  maxh = dst->h - final_dst.y;
684  if (maxh < final_dst.h)
685  final_dst.h = maxh;
686  } else {
687  final_dst.x = final_dst.y = 0;
688  final_dst.w = dst->w;
689  final_dst.h = dst->h;
690  }
691 
692  if (final_dst.w > 0 && final_dst.h > 0) {
693  return SDL_LowerBlitScaled(src, &final_src, dst, &final_dst);
694  }
695 
696  return 0;
697 }
698 
703 int
705  SDL_Surface * dst, SDL_Rect * dstrect)
706 {
707  static const Uint32 complex_copy_flags = (
711  );
712 
713  /* Save off the original dst width, height */
714  int dstW = dstrect->w;
715  int dstH = dstrect->h;
716  SDL_Rect full_rect;
717  SDL_Rect final_dst = *dstrect;
718  SDL_Rect final_src = *srcrect;
719 
720  /* Clip the dst surface to the dstrect */
721  full_rect.x = 0;
722  full_rect.y = 0;
723  full_rect.w = dst->w;
724  full_rect.h = dst->h;
725  if (!SDL_IntersectRect(&final_dst, &full_rect, &final_dst)) {
726  return 0;
727  }
728 
729  /* Did the dst width change? */
730  if ( dstW != final_dst.w ) {
731  /* scale the src width appropriately */
732  final_src.w = final_src.w * dst->clip_rect.w / dstW;
733  }
734 
735  /* Did the dst height change? */
736  if ( dstH != final_dst.h ) {
737  /* scale the src width appropriately */
738  final_src.h = final_src.h * dst->clip_rect.h / dstH;
739  }
740 
741  /* Clip the src surface to the srcrect */
742  full_rect.x = 0;
743  full_rect.y = 0;
744  full_rect.w = src->w;
745  full_rect.h = src->h;
746  if (!SDL_IntersectRect(&final_src, &full_rect, &final_src)) {
747  return 0;
748  }
749 
750  src->map->info.flags |= SDL_COPY_NEAREST;
751 
752  if ( !(src->map->info.flags & complex_copy_flags) &&
753  src->format->format == dst->format->format &&
755  return SDL_SoftStretch( src, &final_src, dst, &final_dst );
756  } else {
757  return SDL_LowerBlit( src, &final_src, dst, &final_dst );
758  }
759 }
760 
761 /*
762  * Lock a surface to directly access the pixels
763  */
764 int
766 {
767  if (!surface->locked) {
768  /* Perform the lock */
769  if (surface->flags & SDL_RLEACCEL) {
770  SDL_UnRLESurface(surface, 1);
771  surface->flags |= SDL_RLEACCEL; /* save accel'd state */
772  }
773  }
774 
775  /* Increment the surface lock count, for recursive locks */
776  ++surface->locked;
777 
778  /* Ready to go.. */
779  return (0);
780 }
781 
782 /*
783  * Unlock a previously locked surface
784  */
785 void
787 {
788  /* Only perform an unlock if we are locked */
789  if (!surface->locked || (--surface->locked > 0)) {
790  return;
791  }
792 
793  /* Update RLE encoded surface with new data */
794  if ((surface->flags & SDL_RLEACCEL) == SDL_RLEACCEL) {
795  surface->flags &= ~SDL_RLEACCEL; /* stop lying */
796  SDL_RLESurface(surface);
797  }
798 }
799 
800 /*
801  * Convert a surface into the specified pixel format.
802  */
803 SDL_Surface *
805  Uint32 flags)
806 {
807  SDL_Surface *convert;
808  Uint32 copy_flags;
809  SDL_Color copy_color;
810  SDL_Rect bounds;
811 
812  /* Check for empty destination palette! (results in empty image) */
813  if (format->palette != NULL) {
814  int i;
815  for (i = 0; i < format->palette->ncolors; ++i) {
816  if ((format->palette->colors[i].r != 0xFF) ||
817  (format->palette->colors[i].g != 0xFF) ||
818  (format->palette->colors[i].b != 0xFF))
819  break;
820  }
821  if (i == format->palette->ncolors) {
822  SDL_SetError("Empty destination palette");
823  return (NULL);
824  }
825  }
826 
827  /* Create a new surface with the desired format */
828  convert = SDL_CreateRGBSurface(flags, surface->w, surface->h,
829  format->BitsPerPixel, format->Rmask,
830  format->Gmask, format->Bmask,
831  format->Amask);
832  if (convert == NULL) {
833  return (NULL);
834  }
835 
836  /* Copy the palette if any */
837  if (format->palette && convert->format->palette) {
838  SDL_memcpy(convert->format->palette->colors,
839  format->palette->colors,
840  format->palette->ncolors * sizeof(SDL_Color));
841  convert->format->palette->ncolors = format->palette->ncolors;
842  }
843 
844  /* Save the original copy flags */
845  copy_flags = surface->map->info.flags;
846  copy_color.r = surface->map->info.r;
847  copy_color.g = surface->map->info.g;
848  copy_color.b = surface->map->info.b;
849  copy_color.a = surface->map->info.a;
850  surface->map->info.r = 0xFF;
851  surface->map->info.g = 0xFF;
852  surface->map->info.b = 0xFF;
853  surface->map->info.a = 0xFF;
854  surface->map->info.flags = 0;
855  SDL_InvalidateMap(surface->map);
856 
857  /* Copy over the image data */
858  bounds.x = 0;
859  bounds.y = 0;
860  bounds.w = surface->w;
861  bounds.h = surface->h;
862  SDL_LowerBlit(surface, &bounds, convert, &bounds);
863 
864  /* Clean up the original surface, and update converted surface */
865  convert->map->info.r = copy_color.r;
866  convert->map->info.g = copy_color.g;
867  convert->map->info.b = copy_color.b;
868  convert->map->info.a = copy_color.a;
869  convert->map->info.flags =
870  (copy_flags &
874  surface->map->info.r = copy_color.r;
875  surface->map->info.g = copy_color.g;
876  surface->map->info.b = copy_color.b;
877  surface->map->info.a = copy_color.a;
878  surface->map->info.flags = copy_flags;
879  SDL_InvalidateMap(surface->map);
880  if (copy_flags & SDL_COPY_COLORKEY) {
881  SDL_bool set_colorkey_by_color = SDL_FALSE;
882 
883  if (surface->format->palette) {
884  if (format->palette &&
885  surface->format->palette->ncolors <= format->palette->ncolors &&
886  (SDL_memcmp(surface->format->palette->colors, format->palette->colors,
887  surface->format->palette->ncolors * sizeof(SDL_Color)) == 0)) {
888  /* The palette is identical, just set the same colorkey */
889  SDL_SetColorKey(convert, 1, surface->map->info.colorkey);
890  } else if (format->Amask) {
891  /* The alpha was set in the destination from the palette */
892  } else {
893  set_colorkey_by_color = SDL_TRUE;
894  }
895  } else {
896  set_colorkey_by_color = SDL_TRUE;
897  }
898 
899  if (set_colorkey_by_color) {
900  /* Set the colorkey by color, which needs to be unique */
901  Uint8 keyR, keyG, keyB, keyA;
902 
903  SDL_GetRGBA(surface->map->info.colorkey, surface->format, &keyR,
904  &keyG, &keyB, &keyA);
905  SDL_SetColorKey(convert, 1,
906  SDL_MapRGBA(convert->format, keyR, keyG, keyB, keyA));
907  /* This is needed when converting for 3D texture upload */
909  }
910  }
911  SDL_SetClipRect(convert, &surface->clip_rect);
912 
913  /* Enable alpha blending by default if the new surface has an
914  * alpha channel or alpha modulation */
915  if ((surface->format->Amask && format->Amask) ||
916  (copy_flags & (SDL_COPY_COLORKEY|SDL_COPY_MODULATE_ALPHA))) {
918  }
919  if ((copy_flags & SDL_COPY_RLE_DESIRED) || (flags & SDL_RLEACCEL)) {
920  SDL_SetSurfaceRLE(convert, SDL_RLEACCEL);
921  }
922 
923  /* We're ready to go! */
924  return (convert);
925 }
926 
927 SDL_Surface *
929  Uint32 flags)
930 {
931  SDL_PixelFormat *fmt;
932  SDL_Surface *convert = NULL;
933 
934  fmt = SDL_AllocFormat(pixel_format);
935  if (fmt) {
936  convert = SDL_ConvertSurface(surface, fmt, flags);
937  SDL_FreeFormat(fmt);
938  }
939  return convert;
940 }
941 
942 /*
943  * Create a surface on the stack for quick blit operations
944  */
945 static __inline__ SDL_bool
947  void * pixels, int pitch, SDL_Surface * surface,
948  SDL_PixelFormat * format, SDL_BlitMap * blitmap)
949 {
950  if (SDL_ISPIXELFORMAT_INDEXED(pixel_format)) {
951  SDL_SetError("Indexed pixel formats not supported");
952  return SDL_FALSE;
953  }
954  if (SDL_InitFormat(format, pixel_format) < 0) {
955  return SDL_FALSE;
956  }
957 
958  SDL_zerop(surface);
959  surface->flags = SDL_PREALLOC;
960  surface->format = format;
961  surface->pixels = pixels;
962  surface->w = width;
963  surface->h = height;
964  surface->pitch = pitch;
965  /* We don't actually need to set up the clip rect for our purposes */
966  /* SDL_SetClipRect(surface, NULL); */
967 
968  /* Allocate an empty mapping */
969  SDL_zerop(blitmap);
970  blitmap->info.r = 0xFF;
971  blitmap->info.g = 0xFF;
972  blitmap->info.b = 0xFF;
973  blitmap->info.a = 0xFF;
974  surface->map = blitmap;
975 
976  /* The surface is ready to go */
977  surface->refcount = 1;
978  return SDL_TRUE;
979 }
980 
981 /*
982  * Copy a block of pixels of one format to another format
983  */
985  Uint32 src_format, const void * src, int src_pitch,
986  Uint32 dst_format, void * dst, int dst_pitch)
987 {
988  SDL_Surface src_surface, dst_surface;
989  SDL_PixelFormat src_fmt, dst_fmt;
990  SDL_BlitMap src_blitmap, dst_blitmap;
991  SDL_Rect rect;
992  void *nonconst_src = (void *) src;
993 
994  /* Check to make sure we are bliting somewhere, so we don't crash */
995  if (!dst) {
996  return SDL_InvalidParamError("dst");
997  }
998  if (!dst_pitch) {
999  return SDL_InvalidParamError("dst_pitch");
1000  }
1001 
1002  /* Fast path for same format copy */
1003  if (src_format == dst_format) {
1004  int bpp;
1005 
1006  if (SDL_ISPIXELFORMAT_FOURCC(src_format)) {
1007  switch (src_format) {
1008  case SDL_PIXELFORMAT_YV12:
1009  case SDL_PIXELFORMAT_IYUV:
1010  case SDL_PIXELFORMAT_YUY2:
1011  case SDL_PIXELFORMAT_UYVY:
1012  case SDL_PIXELFORMAT_YVYU:
1013  bpp = 2;
1014  break;
1015  default:
1016  return SDL_SetError("Unknown FOURCC pixel format");
1017  }
1018  } else {
1019  bpp = SDL_BYTESPERPIXEL(src_format);
1020  }
1021  width *= bpp;
1022 
1023  while (height-- > 0) {
1024  SDL_memcpy(dst, src, width);
1025  src = (Uint8*)src + src_pitch;
1026  dst = (Uint8*)dst + dst_pitch;
1027  }
1028  return 0;
1029  }
1030 
1031  if (!SDL_CreateSurfaceOnStack(width, height, src_format, nonconst_src,
1032  src_pitch,
1033  &src_surface, &src_fmt, &src_blitmap)) {
1034  return -1;
1035  }
1036  if (!SDL_CreateSurfaceOnStack(width, height, dst_format, dst, dst_pitch,
1037  &dst_surface, &dst_fmt, &dst_blitmap)) {
1038  return -1;
1039  }
1040 
1041  /* Set up the rect and go! */
1042  rect.x = 0;
1043  rect.y = 0;
1044  rect.w = width;
1045  rect.h = height;
1046  return SDL_LowerBlit(&src_surface, &rect, &dst_surface, &rect);
1047 }
1048 
1049 /*
1050  * Free a surface created by the above function.
1051  */
1052 void
1054 {
1055  if (surface == NULL) {
1056  return;
1057  }
1058  if (surface->flags & SDL_DONTFREE) {
1059  return;
1060  }
1061  if (--surface->refcount > 0) {
1062  return;
1063  }
1064  while (surface->locked > 0) {
1065  SDL_UnlockSurface(surface);
1066  }
1067  if (surface->flags & SDL_RLEACCEL) {
1068  SDL_UnRLESurface(surface, 0);
1069  }
1070  if (surface->format) {
1071  SDL_SetSurfacePalette(surface, NULL);
1072  SDL_FreeFormat(surface->format);
1073  surface->format = NULL;
1074  }
1075  if (surface->map != NULL) {
1076  SDL_FreeBlitMap(surface->map);
1077  surface->map = NULL;
1078  }
1079  if (!(surface->flags & SDL_PREALLOC)) {
1080  SDL_free(surface->pixels);
1081  }
1082  SDL_free(surface);
1083 }
1084 
1085 /* vi: set ts=4 sw=4 expandtab: */
Uint8 r
Definition: SDL_blit.h:70
#define SDL_COPY_MODULATE_COLOR
Definition: SDL_blit.h:34
#define __inline__
Definition: begin_code.h:119
DECLSPEC void SDLCALL SDL_FreeSurface(SDL_Surface *surface)
Definition: SDL_surface.c:1053
DECLSPEC int SDLCALL SDL_SetSurfaceColorMod(SDL_Surface *surface, Uint8 r, Uint8 g, Uint8 b)
Set an additional color value used in blit operations.
Definition: SDL_surface.c:306
Uint32 version
Definition: SDL_pixels.h:265
DECLSPEC SDL_Surface *SDLCALL SDL_CreateRGBSurface(Uint32 flags, int width, int height, int depth, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask)
Definition: SDL_surface.c:35
Uint8 b
Definition: SDL_blit.h:70
DECLSPEC int SDLCALL SDL_SetSurfaceAlphaMod(SDL_Surface *surface, Uint8 alpha)
Set an additional alpha value used in blit operations.
Definition: SDL_surface.c:351
GLfloat GLfloat GLfloat GLfloat h
Definition: glew.h:7294
#define SDL_COPY_COLORKEY
Definition: SDL_blit.h:39
GLvoid **typedef void(GLAPIENTRY *PFNGLGETVERTEXATTRIBDVPROC)(GLuint
Definition: glew.h:1824
DECLSPEC void *SDLCALL SDL_calloc(size_t nmemb, size_t size)
DECLSPEC void SDLCALL SDL_FreeFormat(SDL_PixelFormat *format)
Free an SDL_PixelFormat structure.
Definition: SDL_pixels.c:584
SDL_blit blit
Definition: SDL_blit.h:89
Uint8 g
Definition: SDL_pixels.h:255
SDL_BlendMode
The blend mode used in SDL_RenderCopy() and drawing operations.
Definition: SDL_blendmode.h:40
DECLSPEC int SDLCALL SDL_SetPixelFormatPalette(SDL_PixelFormat *format, SDL_Palette *palette)
Set the palette for a pixel format structure.
Definition: SDL_pixels.c:646
DECLSPEC int SDLCALL 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:984
GLboolean GLboolean g
Definition: glew.h:8736
#define NULL
Definition: ftobjs.h:61
#define SDL_ISPIXELFORMAT_INDEXED(format)
Definition: SDL_pixels.h:129
Uint8 BytesPerPixel
Definition: SDL_pixels.h:277
SDL_bool
Definition: SDL_stdinc.h:116
Uint8 g
Definition: SDL_blit.h:70
DECLSPEC int SDLCALL SDL_SetSurfaceBlendMode(SDL_Surface *surface, SDL_BlendMode blendMode)
Set the blend mode used for blit operations.
Definition: SDL_surface.c:387
#define SDL_COPY_MOD
Definition: SDL_blit.h:38
EGLSurface EGLint x
Definition: eglext.h:293
EGLSurface surface
Definition: eglext.h:74
A collection of pixels used in software blitting.
Definition: SDL_surface.h:69
DECLSPEC void SDLCALL SDL_free(void *mem)
DECLSPEC SDL_bool SDLCALL SDL_SetClipRect(SDL_Surface *surface, const SDL_Rect *rect)
Definition: SDL_surface.c:453
#define SDL_DONTFREE
Definition: SDL_surface.h:55
DECLSPEC int SDLCALL SDL_SetSurfacePalette(SDL_Surface *surface, SDL_Palette *palette)
Set the palette used by a surface.
Definition: SDL_surface.c:143
DECLSPEC void SDLCALL SDL_FreePalette(SDL_Palette *palette)
Free a palette created with SDL_AllocPalette().
Definition: SDL_pixels.c:701
void SDL_UnRLESurface(SDL_Surface *surface, int recode)
EGLSurface EGLint EGLint EGLint EGLint height
Definition: eglext.h:293
static void SDL_ConvertColorkeyToAlpha(SDL_Surface *surface)
Definition: SDL_surface.c:236
DECLSPEC Uint32 SDLCALL SDL_MasksToPixelFormatEnum(int bpp, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask)
Convert a bpp and RGBA masks to an enumerated pixel format.
Definition: SDL_pixels.c:291
#define SDL_BYTESPERPIXEL(X)
Definition: SDL_pixels.h:123
Uint32 dst_palette_version
Definition: SDL_blit.h:95
Uint8 b
Definition: SDL_pixels.h:256
DECLSPEC int SDLCALL SDL_memcmp(const void *s1, const void *s2, size_t len)
Definition: SDL_string.c:370
#define SDL_COPY_RLE_COLORKEY
Definition: SDL_blit.h:42
#define SDL_InvalidParamError(param)
Definition: SDL_error.h:54
DECLSPEC int SDLCALL SDL_UpperBlit(SDL_Surface *src, const SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect)
Definition: SDL_surface.c:519
DECLSPEC int SDLCALL SDL_GetColorKey(SDL_Surface *surface, Uint32 *key)
Gets the color key (transparent pixel) in a blittable surface.
Definition: SDL_surface.c:218
DECLSPEC void SDLCALL SDL_GetClipRect(SDL_Surface *surface, SDL_Rect *rect)
Definition: SDL_surface.c:477
#define SDL_COPY_ADD
Definition: SDL_blit.h:37
Uint32 colorkey
Definition: SDL_blit.h:69
DECLSPEC Uint32 SDLCALL SDL_MapRGBA(const SDL_PixelFormat *format, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
Maps an RGBA quadruple to a pixel value for a given pixel format.
Definition: SDL_pixels.c:812
Uint32 flags
Definition: SDL_surface.h:71
Uint32 src_palette_version
Definition: SDL_blit.h:96
#define SDL_COPY_RLE_DESIRED
Definition: SDL_blit.h:41
void SDL_InvalidateMap(SDL_BlitMap *map)
Definition: SDL_pixels.c:972
uint32_t Uint32
An unsigned 32-bit integer type.
Definition: SDL_stdinc.h:145
#define SDL_COPY_NEAREST
Definition: SDL_blit.h:40
DECLSPEC void SDLCALL SDL_UnlockSurface(SDL_Surface *surface)
Definition: SDL_surface.c:786
#define SDL_ALPHA_TRANSPARENT
Definition: SDL_pixels.h:44
struct SDL_BlitMap * map
Definition: SDL_surface.h:88
GLenum GLenum GLvoid * row
Definition: glew.h:4447
DECLSPEC SDL_PixelFormat *SDLCALL SDL_AllocFormat(Uint32 pixel_format)
Create an SDL_PixelFormat structure from a pixel format enum.
Definition: SDL_pixels.c:486
Uint8 r
Definition: SDL_pixels.h:254
GLenum GLenum dst
Definition: glew.h:2396
DECLSPEC SDL_bool SDLCALL SDL_IntersectRect(const SDL_Rect *A, const SDL_Rect *B, SDL_Rect *result)
Calculate the intersection of two rectangles.
Definition: SDL_rect.c:75
for(;;)
int SDL_MapSurface(SDL_Surface *src, SDL_Surface *dst)
Definition: SDL_pixels.c:991
void * pixels
Definition: SDL_surface.h:75
EGLSurface EGLint EGLint EGLint width
Definition: eglext.h:293
DECLSPEC int SDLCALL SDL_GetSurfaceColorMod(SDL_Surface *surface, Uint8 *r, Uint8 *g, Uint8 *b)
Get the additional color value used in blit operations.
Definition: SDL_surface.c:332
Uint8 a
Definition: SDL_pixels.h:257
Uint8 BitsPerPixel
Definition: SDL_pixels.h:276
DECLSPEC void *SDLCALL SDL_memset(void *dst, int c, size_t len)
Definition: SDL_string.c:261
GLint GLenum GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl2ext.h:845
DECLSPEC int SDLCALL SDL_SetError(const char *fmt,...)
Definition: SDL_error.c:53
DECLSPEC void *SDLCALL SDL_malloc(size_t size)
GLint GLenum GLsizei GLsizei GLsizei depth
Definition: gl2ext.h:845
int x
Definition: SDL_rect.h:65
DECLSPEC SDL_Surface *SDLCALL SDL_ConvertSurface(SDL_Surface *src, const SDL_PixelFormat *fmt, Uint32 flags)
Definition: SDL_surface.c:804
GLclampf GLclampf GLclampf alpha
Definition: glew.h:1506
int w
Definition: SDL_rect.h:66
DECLSPEC SDL_Surface *SDLCALL SDL_CreateRGBSurfaceFrom(void *pixels, int width, int height, int depth, int pitch, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask)
Definition: SDL_surface.c:122
int SDL_InitFormat(SDL_PixelFormat *format, Uint32 pixel_format)
Definition: SDL_pixels.c:519
SDL_Rect clip_rect
Definition: SDL_surface.h:85
DECLSPEC int SDLCALL SDL_UpperBlitScaled(SDL_Surface *src, const SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect)
Definition: SDL_surface.c:612
DECLSPEC SDL_Surface *SDLCALL SDL_ConvertSurfaceFormat(SDL_Surface *src, Uint32 pixel_format, Uint32 flags)
Definition: SDL_surface.c:928
int SDL_RLESurface(SDL_Surface *surface)
DECLSPEC int SDLCALL SDL_LowerBlit(SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect)
Definition: SDL_surface.c:496
SDL_Surface * dst
Definition: SDL_blit.h:87
DECLSPEC int SDLCALL SDL_SetColorKey(SDL_Surface *surface, int flag, Uint32 key)
Sets the color key (transparent pixel) in a blittable surface.
Definition: SDL_surface.c:173
EGLSurface EGLint EGLint y
Definition: eglext.h:293
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
SDL_Color * colors
Definition: SDL_pixels.h:264
SDL_PixelFormat * format
Definition: SDL_surface.h:72
GLint GLenum GLsizei GLsizei GLsizei GLint GLenum GLenum const GLvoid * pixels
Definition: gl2ext.h:845
DECLSPEC void SDLCALL SDL_GetRGBA(Uint32 pixel, const SDL_PixelFormat *format, Uint8 *r, Uint8 *g, Uint8 *b, Uint8 *a)
Get the RGBA components from a pixel of the specified format.
Definition: SDL_pixels.c:849
DECLSPEC void *SDLCALL SDL_memcpy(void *dst, const void *src, size_t len)
Definition: SDL_string.c:293
GLenum GLsizei GLsizei GLsizei GLsizei GLbitfield flags
Definition: glew.h:2767
DECLSPEC SDL_Palette *SDLCALL SDL_AllocPalette(int ncolors)
Create a palette structure with the specified number of color entries.
Definition: SDL_pixels.c:615
#define SDL_COPY_MODULATE_ALPHA
Definition: SDL_blit.h:35
int h
Definition: SDL_rect.h:66
uint8_t Uint8
An unsigned 8-bit integer type.
Definition: SDL_stdinc.h:129
#define SDL_COPY_RLE_ALPHAKEY
Definition: SDL_blit.h:43
GLint GLint GLint GLint GLint GLint GLint GLbitfield mask
Definition: gl2ext.h:961
#define SDL_zerop(x)
Definition: SDL_stdinc.h:255
SDL_BlitMap * SDL_AllocBlitMap(void)
Definition: SDL_pixels.c:952
DECLSPEC int SDLCALL SDL_LowerBlitScaled(SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect)
Definition: SDL_surface.c:704
GLdouble GLdouble GLdouble r
Definition: glew.h:1392
GLdouble GLdouble GLdouble b
Definition: glew.h:8383
GLint GLint GLint GLint GLint w
Definition: gl2ext.h:1215
uint16_t Uint16
An unsigned 16-bit integer type.
Definition: SDL_stdinc.h:137
int SDL_CalculatePitch(SDL_Surface *surface)
Definition: SDL_pixels.c:746
DECLSPEC int SDLCALL SDL_GetSurfaceAlphaMod(SDL_Surface *surface, Uint8 *alpha)
Get the additional alpha value used in blit operations.
Definition: SDL_surface.c:374
SDL_Palette * palette
Definition: SDL_pixels.h:275
#define SDL_ISPIXELFORMAT_FOURCC(format)
Definition: SDL_pixels.h:143
GLenum src
Definition: glew.h:2396
int i
Definition: pngrutil.c:1377
#define SDL_ALPHA_OPAQUE
Definition: SDL_pixels.h:43
void SDL_FreeBlitMap(SDL_BlitMap *map)
Definition: SDL_pixels.c:1077
DECLSPEC int SDLCALL SDL_LockSurface(SDL_Surface *surface)
Sets up a surface for directly accessing the pixels.
Definition: SDL_surface.c:765
int y
Definition: SDL_rect.h:65
#define SDL_Unsupported()
Definition: SDL_error.h:53
#define SDL_COPY_BLEND
Definition: SDL_blit.h:36
SDL_BlitInfo info
Definition: SDL_blit.h:91
#define SDL_PREALLOC
Definition: SDL_surface.h:53
A rectangle, with the origin at the upper left.
Definition: SDL_rect.h:63
static __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:946
#define SDL_RLEACCEL
Definition: SDL_surface.h:54
DECLSPEC int SDLCALL SDL_SetSurfaceRLE(SDL_Surface *surface, int flag)
Sets the RLE acceleration hint for a surface.
Definition: SDL_surface.c:152
DECLSPEC int SDLCALL SDL_SoftStretch(SDL_Surface *src, const SDL_Rect *srcrect, SDL_Surface *dst, const SDL_Rect *dstrect)
Perform a fast, low quality, stretch blit between two surfaces of the same pixel format.
Definition: SDL_stretch.c:203
DECLSPEC int SDLCALL SDL_GetSurfaceBlendMode(SDL_Surface *surface, SDL_BlendMode *blendMode)
Get the blend mode used for blit operations.
Definition: SDL_surface.c:424
Uint8 a
Definition: SDL_blit.h:70