change SDL 1.2 to SDL 2.0
[platform/upstream/SDL.git] / src / video / SDL_blit_slow.c
1 /*
2   Simple DirectMedia Layer
3   Copyright (C) 1997-2016 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_blit.h"
25 #include "SDL_blit_slow.h"
26
27 /* The ONE TRUE BLITTER
28  * This puppy has to handle all the unoptimized cases - yes, it's slow.
29  */
30 void
31 SDL_Blit_Slow(SDL_BlitInfo * info)
32 {
33     const int flags = info->flags;
34     const Uint32 modulateR = info->r;
35     const Uint32 modulateG = info->g;
36     const Uint32 modulateB = info->b;
37     const Uint32 modulateA = info->a;
38     Uint32 srcpixel;
39     Uint32 srcR, srcG, srcB, srcA;
40     Uint32 dstpixel;
41     Uint32 dstR, dstG, dstB, dstA;
42     int srcy, srcx;
43     int posy, posx;
44     int incy, incx;
45     SDL_PixelFormat *src_fmt = info->src_fmt;
46     SDL_PixelFormat *dst_fmt = info->dst_fmt;
47     int srcbpp = src_fmt->BytesPerPixel;
48     int dstbpp = dst_fmt->BytesPerPixel;
49
50     srcy = 0;
51     posy = 0;
52     incy = (info->src_h << 16) / info->dst_h;
53     incx = (info->src_w << 16) / info->dst_w;
54
55     while (info->dst_h--) {
56         Uint8 *src = 0;
57         Uint8 *dst = (Uint8 *) info->dst;
58         int n = info->dst_w;
59         srcx = -1;
60         posx = 0x10000L;
61         while (posy >= 0x10000L) {
62             ++srcy;
63             posy -= 0x10000L;
64         }
65         while (n--) {
66             if (posx >= 0x10000L) {
67                 while (posx >= 0x10000L) {
68                     ++srcx;
69                     posx -= 0x10000L;
70                 }
71                 src =
72                     (info->src + (srcy * info->src_pitch) + (srcx * srcbpp));
73             }
74             if (src_fmt->Amask) {
75                 DISEMBLE_RGBA(src, srcbpp, src_fmt, srcpixel, srcR, srcG,
76                               srcB, srcA);
77             } else {
78                 DISEMBLE_RGB(src, srcbpp, src_fmt, srcpixel, srcR, srcG,
79                              srcB);
80                 srcA = 0xFF;
81             }
82             if (flags & SDL_COPY_COLORKEY) {
83                 /* srcpixel isn't set for 24 bpp */
84                 if (srcbpp == 3) {
85                     srcpixel = (srcR << src_fmt->Rshift) |
86                         (srcG << src_fmt->Gshift) | (srcB << src_fmt->Bshift);
87                 }
88                 if (srcpixel == info->colorkey) {
89                     posx += incx;
90                     dst += dstbpp;
91                     continue;
92                 }
93             }
94             if (dst_fmt->Amask) {
95                 DISEMBLE_RGBA(dst, dstbpp, dst_fmt, dstpixel, dstR, dstG,
96                               dstB, dstA);
97             } else {
98                 DISEMBLE_RGB(dst, dstbpp, dst_fmt, dstpixel, dstR, dstG,
99                              dstB);
100                 dstA = 0xFF;
101             }
102
103             if (flags & SDL_COPY_MODULATE_COLOR) {
104                 srcR = (srcR * modulateR) / 255;
105                 srcG = (srcG * modulateG) / 255;
106                 srcB = (srcB * modulateB) / 255;
107             }
108             if (flags & SDL_COPY_MODULATE_ALPHA) {
109                 srcA = (srcA * modulateA) / 255;
110             }
111             if (flags & (SDL_COPY_BLEND | SDL_COPY_ADD)) {
112                 /* This goes away if we ever use premultiplied alpha */
113                 if (srcA < 255) {
114                     srcR = (srcR * srcA) / 255;
115                     srcG = (srcG * srcA) / 255;
116                     srcB = (srcB * srcA) / 255;
117                 }
118             }
119             switch (flags & (SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD)) {
120             case 0:
121                 dstR = srcR;
122                 dstG = srcG;
123                 dstB = srcB;
124                 dstA = srcA;
125                 break;
126             case SDL_COPY_BLEND:
127                 dstR = srcR + ((255 - srcA) * dstR) / 255;
128                 dstG = srcG + ((255 - srcA) * dstG) / 255;
129                 dstB = srcB + ((255 - srcA) * dstB) / 255;
130                 break;
131             case SDL_COPY_ADD:
132                 dstR = srcR + dstR;
133                 if (dstR > 255)
134                     dstR = 255;
135                 dstG = srcG + dstG;
136                 if (dstG > 255)
137                     dstG = 255;
138                 dstB = srcB + dstB;
139                 if (dstB > 255)
140                     dstB = 255;
141                 break;
142             case SDL_COPY_MOD:
143                 dstR = (srcR * dstR) / 255;
144                 dstG = (srcG * dstG) / 255;
145                 dstB = (srcB * dstB) / 255;
146                 break;
147             }
148             if (dst_fmt->Amask) {
149                 ASSEMBLE_RGBA(dst, dstbpp, dst_fmt, dstR, dstG, dstB, dstA);
150             } else {
151                 ASSEMBLE_RGB(dst, dstbpp, dst_fmt, dstR, dstG, dstB);
152             }
153             posx += incx;
154             dst += dstbpp;
155         }
156         posy += incy;
157         info->dst += info->dst_pitch;
158     }
159 }
160
161 /* vi: set ts=4 sw=4 expandtab: */