src/render/software/SDL_blendpoint.c
author Philipp Wiesemann <philipp.wiesemann@arcor.de>
Wed, 29 Oct 2014 20:20:47 +0100
changeset 9201 21d9f9babb30
parent 8149 681eb46b8ac4
child 9619 b94b6d0bff0f
permissions -rw-r--r--
Fixed bug 2647 - Memory leak in SDL_AddHintCallback function - SDL_hints.c

Nitz

Variable entry going out of scope leaks the storage it points to, at:

/* Need to add a hint entry for this watcher */
hint = (SDL_Hint *)SDL_malloc(sizeof(*hint));
if (!hint) {
return;
}

Patch is attached.
     1 /*
     2   Simple DirectMedia Layer
     3   Copyright (C) 1997-2014 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 #if !SDL_RENDER_DISABLED
    24 
    25 #include "SDL_draw.h"
    26 #include "SDL_blendpoint.h"
    27 
    28 
    29 static int
    30 SDL_BlendPoint_RGB555(SDL_Surface * dst, int x, int y, SDL_BlendMode blendMode, Uint8 r,
    31                       Uint8 g, Uint8 b, Uint8 a)
    32 {
    33     unsigned inva = 0xff - a;
    34 
    35     switch (blendMode) {
    36     case SDL_BLENDMODE_BLEND:
    37         DRAW_SETPIXELXY_BLEND_RGB555(x, y);
    38         break;
    39     case SDL_BLENDMODE_ADD:
    40         DRAW_SETPIXELXY_ADD_RGB555(x, y);
    41         break;
    42     case SDL_BLENDMODE_MOD:
    43         DRAW_SETPIXELXY_MOD_RGB555(x, y);
    44         break;
    45     default:
    46         DRAW_SETPIXELXY_RGB555(x, y);
    47         break;
    48     }
    49     return 0;
    50 }
    51 
    52 static int
    53 SDL_BlendPoint_RGB565(SDL_Surface * dst, int x, int y, SDL_BlendMode blendMode, Uint8 r,
    54                       Uint8 g, Uint8 b, Uint8 a)
    55 {
    56     unsigned inva = 0xff - a;
    57 
    58     switch (blendMode) {
    59     case SDL_BLENDMODE_BLEND:
    60         DRAW_SETPIXELXY_BLEND_RGB565(x, y);
    61         break;
    62     case SDL_BLENDMODE_ADD:
    63         DRAW_SETPIXELXY_ADD_RGB565(x, y);
    64         break;
    65     case SDL_BLENDMODE_MOD:
    66         DRAW_SETPIXELXY_MOD_RGB565(x, y);
    67         break;
    68     default:
    69         DRAW_SETPIXELXY_RGB565(x, y);
    70         break;
    71     }
    72     return 0;
    73 }
    74 
    75 static int
    76 SDL_BlendPoint_RGB888(SDL_Surface * dst, int x, int y, SDL_BlendMode blendMode, Uint8 r,
    77                       Uint8 g, Uint8 b, Uint8 a)
    78 {
    79     unsigned inva = 0xff - a;
    80 
    81     switch (blendMode) {
    82     case SDL_BLENDMODE_BLEND:
    83         DRAW_SETPIXELXY_BLEND_RGB888(x, y);
    84         break;
    85     case SDL_BLENDMODE_ADD:
    86         DRAW_SETPIXELXY_ADD_RGB888(x, y);
    87         break;
    88     case SDL_BLENDMODE_MOD:
    89         DRAW_SETPIXELXY_MOD_RGB888(x, y);
    90         break;
    91     default:
    92         DRAW_SETPIXELXY_RGB888(x, y);
    93         break;
    94     }
    95     return 0;
    96 }
    97 
    98 static int
    99 SDL_BlendPoint_ARGB8888(SDL_Surface * dst, int x, int y, SDL_BlendMode blendMode,
   100                         Uint8 r, Uint8 g, Uint8 b, Uint8 a)
   101 {
   102     unsigned inva = 0xff - a;
   103 
   104     switch (blendMode) {
   105     case SDL_BLENDMODE_BLEND:
   106         DRAW_SETPIXELXY_BLEND_ARGB8888(x, y);
   107         break;
   108     case SDL_BLENDMODE_ADD:
   109         DRAW_SETPIXELXY_ADD_ARGB8888(x, y);
   110         break;
   111     case SDL_BLENDMODE_MOD:
   112         DRAW_SETPIXELXY_MOD_ARGB8888(x, y);
   113         break;
   114     default:
   115         DRAW_SETPIXELXY_ARGB8888(x, y);
   116         break;
   117     }
   118     return 0;
   119 }
   120 
   121 static int
   122 SDL_BlendPoint_RGB(SDL_Surface * dst, int x, int y, SDL_BlendMode blendMode, Uint8 r,
   123                    Uint8 g, Uint8 b, Uint8 a)
   124 {
   125     SDL_PixelFormat *fmt = dst->format;
   126     unsigned inva = 0xff - a;
   127 
   128     switch (fmt->BytesPerPixel) {
   129     case 2:
   130         switch (blendMode) {
   131         case SDL_BLENDMODE_BLEND:
   132             DRAW_SETPIXELXY2_BLEND_RGB(x, y);
   133             break;
   134         case SDL_BLENDMODE_ADD:
   135             DRAW_SETPIXELXY2_ADD_RGB(x, y);
   136             break;
   137         case SDL_BLENDMODE_MOD:
   138             DRAW_SETPIXELXY2_MOD_RGB(x, y);
   139             break;
   140         default:
   141             DRAW_SETPIXELXY2_RGB(x, y);
   142             break;
   143         }
   144         return 0;
   145     case 4:
   146         switch (blendMode) {
   147         case SDL_BLENDMODE_BLEND:
   148             DRAW_SETPIXELXY4_BLEND_RGB(x, y);
   149             break;
   150         case SDL_BLENDMODE_ADD:
   151             DRAW_SETPIXELXY4_ADD_RGB(x, y);
   152             break;
   153         case SDL_BLENDMODE_MOD:
   154             DRAW_SETPIXELXY4_MOD_RGB(x, y);
   155             break;
   156         default:
   157             DRAW_SETPIXELXY4_RGB(x, y);
   158             break;
   159         }
   160         return 0;
   161     default:
   162         return SDL_Unsupported();
   163     }
   164 }
   165 
   166 static int
   167 SDL_BlendPoint_RGBA(SDL_Surface * dst, int x, int y, SDL_BlendMode blendMode, Uint8 r,
   168                     Uint8 g, Uint8 b, Uint8 a)
   169 {
   170     SDL_PixelFormat *fmt = dst->format;
   171     unsigned inva = 0xff - a;
   172 
   173     switch (fmt->BytesPerPixel) {
   174     case 4:
   175         switch (blendMode) {
   176         case SDL_BLENDMODE_BLEND:
   177             DRAW_SETPIXELXY4_BLEND_RGBA(x, y);
   178             break;
   179         case SDL_BLENDMODE_ADD:
   180             DRAW_SETPIXELXY4_ADD_RGBA(x, y);
   181             break;
   182         case SDL_BLENDMODE_MOD:
   183             DRAW_SETPIXELXY4_MOD_RGBA(x, y);
   184             break;
   185         default:
   186             DRAW_SETPIXELXY4_RGBA(x, y);
   187             break;
   188         }
   189         return 0;
   190     default:
   191         return SDL_Unsupported();
   192     }
   193 }
   194 
   195 int
   196 SDL_BlendPoint(SDL_Surface * dst, int x, int y, SDL_BlendMode blendMode, Uint8 r,
   197                Uint8 g, Uint8 b, Uint8 a)
   198 {
   199     if (!dst) {
   200         return SDL_SetError("Passed NULL destination surface");
   201     }
   202 
   203     /* This function doesn't work on surfaces < 8 bpp */
   204     if (dst->format->BitsPerPixel < 8) {
   205         return SDL_SetError("SDL_BlendPoint(): Unsupported surface format");
   206     }
   207 
   208     /* Perform clipping */
   209     if (x < dst->clip_rect.x || y < dst->clip_rect.y ||
   210         x >= (dst->clip_rect.x + dst->clip_rect.w) ||
   211         y >= (dst->clip_rect.y + dst->clip_rect.h)) {
   212         return 0;
   213     }
   214 
   215     if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) {
   216         r = DRAW_MUL(r, a);
   217         g = DRAW_MUL(g, a);
   218         b = DRAW_MUL(b, a);
   219     }
   220 
   221     switch (dst->format->BitsPerPixel) {
   222     case 15:
   223         switch (dst->format->Rmask) {
   224         case 0x7C00:
   225             return SDL_BlendPoint_RGB555(dst, x, y, blendMode, r, g, b, a);
   226         }
   227         break;
   228     case 16:
   229         switch (dst->format->Rmask) {
   230         case 0xF800:
   231             return SDL_BlendPoint_RGB565(dst, x, y, blendMode, r, g, b, a);
   232         }
   233         break;
   234     case 32:
   235         switch (dst->format->Rmask) {
   236         case 0x00FF0000:
   237             if (!dst->format->Amask) {
   238                 return SDL_BlendPoint_RGB888(dst, x, y, blendMode, r, g, b,
   239                                              a);
   240             } else {
   241                 return SDL_BlendPoint_ARGB8888(dst, x, y, blendMode, r, g, b,
   242                                                a);
   243             }
   244             break;
   245         }
   246         break;
   247     default:
   248         break;
   249     }
   250 
   251     if (!dst->format->Amask) {
   252         return SDL_BlendPoint_RGB(dst, x, y, blendMode, r, g, b, a);
   253     } else {
   254         return SDL_BlendPoint_RGBA(dst, x, y, blendMode, r, g, b, a);
   255     }
   256 }
   257 
   258 int
   259 SDL_BlendPoints(SDL_Surface * dst, const SDL_Point * points, int count,
   260                 SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
   261 {
   262     int minx, miny;
   263     int maxx, maxy;
   264     int i;
   265     int x, y;
   266     int (*func)(SDL_Surface * dst, int x, int y,
   267                 SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) = NULL;
   268     int status = 0;
   269 
   270     if (!dst) {
   271         return SDL_SetError("Passed NULL destination surface");
   272     }
   273 
   274     /* This function doesn't work on surfaces < 8 bpp */
   275     if (dst->format->BitsPerPixel < 8) {
   276         return SDL_SetError("SDL_BlendPoints(): Unsupported surface format");
   277     }
   278 
   279     if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) {
   280         r = DRAW_MUL(r, a);
   281         g = DRAW_MUL(g, a);
   282         b = DRAW_MUL(b, a);
   283     }
   284 
   285     /* FIXME: Does this function pointer slow things down significantly? */
   286     switch (dst->format->BitsPerPixel) {
   287     case 15:
   288         switch (dst->format->Rmask) {
   289         case 0x7C00:
   290             func = SDL_BlendPoint_RGB555;
   291             break;
   292         }
   293         break;
   294     case 16:
   295         switch (dst->format->Rmask) {
   296         case 0xF800:
   297             func = SDL_BlendPoint_RGB565;
   298             break;
   299         }
   300         break;
   301     case 32:
   302         switch (dst->format->Rmask) {
   303         case 0x00FF0000:
   304             if (!dst->format->Amask) {
   305                 func = SDL_BlendPoint_RGB888;
   306             } else {
   307                 func = SDL_BlendPoint_ARGB8888;
   308             }
   309             break;
   310         }
   311         break;
   312     default:
   313         break;
   314     }
   315 
   316     if (!func) {
   317         if (!dst->format->Amask) {
   318             func = SDL_BlendPoint_RGB;
   319         } else {
   320             func = SDL_BlendPoint_RGBA;
   321         }
   322     }
   323 
   324     minx = dst->clip_rect.x;
   325     maxx = dst->clip_rect.x + dst->clip_rect.w - 1;
   326     miny = dst->clip_rect.y;
   327     maxy = dst->clip_rect.y + dst->clip_rect.h - 1;
   328 
   329     for (i = 0; i < count; ++i) {
   330         x = points[i].x;
   331         y = points[i].y;
   332 
   333         if (x < minx || x > maxx || y < miny || y > maxy) {
   334             continue;
   335         }
   336         status = func(dst, x, y, blendMode, r, g, b, a);
   337     }
   338     return status;
   339 }
   340 
   341 #endif /* !SDL_RENDER_DISABLED */
   342 
   343 /* vi: set ts=4 sw=4 expandtab: */