1 /*
2 * Copyright 2008, Stephan Aßmus <superstippi@gmx.de>
3 * Copyright 2008, Philippe Saint-Pierre <stpere@gmail.com>
4 * Copyright 2004-2009, Axel Dörfler, axeld@pinc-software.de.
5 * Copyright 2024, Haiku, Inc. All rights reserved.
6 * Distributed under the terms of the MIT License.
7 */
8 #ifndef GENERIC_BLITTER_H
9 #define GENERIC_BLITTER_H
10
11
12 #include <SupportDefs.h>
13
14
15 struct BlitParameters {
16 const uint8* from;
17 uint32 fromWidth;
18 uint16 fromLeft, fromTop;
19 uint16 fromRight, fromBottom;
20
21 uint8* to;
22 uint32 toBytesPerRow;
23 uint16 toLeft, toTop;
24 };
25
26
27 static void
blit8(const BlitParameters & params)28 blit8(const BlitParameters& params)
29 {
30 const uint8* data = params.from;
31 data += (params.fromWidth * params.fromTop + params.fromLeft);
32 uint8* start = (uint8*)(params.to
33 + params.toBytesPerRow * params.toTop
34 + 1 * params.toLeft);
35
36 for (int32 y = params.fromTop; y < params.fromBottom; y++) {
37 const uint8* src = data;
38 uint8* dst = start;
39 for (int32 x = params.fromLeft; x < params.fromRight; x++) {
40 dst[0] = src[0];
41 dst++;
42 src++;
43 }
44
45 data += params.fromWidth;
46 start = (uint8*)((addr_t)start + params.toBytesPerRow);
47 }
48 }
49
50
51 static void
blit15(const BlitParameters & params)52 blit15(const BlitParameters& params)
53 {
54 const uint8* data = params.from;
55 data += (params.fromWidth * params.fromTop + params.fromLeft) * 3;
56 uint16* start = (uint16*)(params.to
57 + params.toBytesPerRow * params.toTop
58 + 2 * params.toLeft);
59
60 for (int32 y = params.fromTop; y < params.fromBottom; y++) {
61 const uint8* src = data;
62 uint16* dst = start;
63 for (int32 x = params.fromLeft; x < params.fromRight; x++) {
64 dst[0] = ((src[2] >> 3) << 10)
65 | ((src[1] >> 3) << 5)
66 | ((src[0] >> 3));
67
68 dst++;
69 src += 3;
70 }
71
72 data += params.fromWidth * 3;
73 start = (uint16*)((addr_t)start + params.toBytesPerRow);
74 }
75 }
76
77
78 static void
blit16(const BlitParameters & params)79 blit16(const BlitParameters& params)
80 {
81 const uint8* data = params.from;
82 data += (params.fromWidth * params.fromTop + params.fromLeft) * 3;
83 uint16* start = (uint16*)(params.to
84 + params.toBytesPerRow * params.toTop
85 + 2 * params.toLeft);
86
87 for (int32 y = params.fromTop; y < params.fromBottom; y++) {
88 const uint8* src = data;
89 uint16* dst = start;
90 for (int32 x = params.fromLeft; x < params.fromRight; x++) {
91 dst[0] = ((src[2] >> 3) << 11)
92 | ((src[1] >> 2) << 5)
93 | ((src[0] >> 3));
94
95 dst++;
96 src += 3;
97 }
98
99 data += params.fromWidth * 3;
100 start = (uint16*)((addr_t)start + params.toBytesPerRow);
101 }
102 }
103
104
105 static void
blit24(const BlitParameters & params)106 blit24(const BlitParameters& params)
107 {
108 const uint8* data = params.from;
109 data += (params.fromWidth * params.fromTop + params.fromLeft) * 3;
110 uint8* start = (uint8*)(params.to
111 + params.toBytesPerRow * params.toTop
112 + 3 * params.toLeft);
113
114 for (int32 y = params.fromTop; y < params.fromBottom; y++) {
115 const uint8* src = data;
116 uint8* dst = start;
117 for (int32 x = params.fromLeft; x < params.fromRight; x++) {
118 dst[0] = src[0];
119 dst[1] = src[1];
120 dst[2] = src[2];
121 dst += 3;
122 src += 3;
123 }
124
125 data += params.fromWidth * 3;
126 start = (uint8*)((addr_t)start + params.toBytesPerRow);
127 }
128 }
129
130
131 static void
blit32(const BlitParameters & params)132 blit32(const BlitParameters& params)
133 {
134 const uint8* data = params.from;
135 data += (params.fromWidth * params.fromTop + params.fromLeft) * 3;
136 uint32* start = (uint32*)(params.to
137 + params.toBytesPerRow * params.toTop
138 + 4 * params.toLeft);
139
140 for (int32 y = params.fromTop; y < params.fromBottom; y++) {
141 const uint8* src = data;
142 uint32* dst = start;
143 for (int32 x = params.fromLeft; x < params.fromRight; x++) {
144 dst[0] = (src[2] << 16) | (src[1] << 8) | (src[0]);
145 dst++;
146 src += 3;
147 }
148
149 data += params.fromWidth * 3;
150 start = (uint32*)((addr_t)start + params.toBytesPerRow);
151 }
152 }
153
154
155 static void
blit(const BlitParameters & params,int32 depth)156 blit(const BlitParameters& params, int32 depth)
157 {
158 switch (depth) {
159 case 8:
160 blit8(params);
161 return;
162 case 15:
163 blit15(params);
164 return;
165 case 16:
166 blit16(params);
167 return;
168 case 24:
169 blit24(params);
170 return;
171 case 32:
172 blit32(params);
173 return;
174 }
175 }
176
177
178 #endif /* GENERIC_BLITTER_H */
179