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