1 /*
2    (c) Copyright 2001-2009  The world wide DirectFB Open Source Community (directfb.org)
3    (c) Copyright 2000-2004  Convergence (integrated media) GmbH
4 
5    All rights reserved.
6 
7    Written by Denis Oliver Kropp <dok@directfb.org>,
8               Andreas Hundt <andi@fischlustig.de>,
9               Sven Neumann <neo@directfb.org>,
10               Ville Syrjälä <syrjala@sci.fi> and
11               Claudio Ciccani <klan@users.sf.net>.
12 
13    This library is free software; you can redistribute it and/or
14    modify it under the terms of the GNU Lesser General Public
15    License as published by the Free Software Foundation; either
16    version 2 of the License, or (at your option) any later version.
17 
18    This library is distributed in the hope that it will be useful,
19    but WITHOUT ANY WARRANTY; without even the implied warranty of
20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21    Lesser General Public License for more details.
22 
23    You should have received a copy of the GNU Lesser General Public
24    License along with this library; if not, write to the
25    Free Software Foundation, Inc., 59 Temple Place - Suite 330,
26    Boston, MA 02111-1307, USA.
27 */
28 
29 /*
30  * Example:
31  * #define A_SHIFT 15
32  * #define R_SHIFT 10
33  * #define G_SHIFT 5
34  * #define B_SHIFT 0
35  * #define A_MASK 0x8000
36  * #define R_MASK 0x7c00
37  * #define G_MASK 0x03e0
38  * #define B_MASK 0x001f
39  * #define PIXEL_OUT( a, r, g, b ) PIXEL_ARGB1555( a, r, g, b )
40  * #define EXPAND_Ato8( a ) EXPAND_1to8( a )
41  * #define EXPAND_Rto8( r ) EXPAND_5to8( r )
42  * #define EXPAND_Gto8( g ) EXPAND_5to8( g )
43  * #define EXPAND_Bto8( b ) EXPAND_5to8( b )
44  * #define Sop_PFI_OP_Dacc( op ) Sop_argb1555_##op##_Dacc
45  * #define Sacc_OP_Aop_PFI( op ) Sacc_##op##_Aop_argb1555
46  * #include "template_acc_16.h"
47  */
48 
49 #define RGB_MASK (R_MASK | G_MASK | B_MASK)
50 
51 #if RGB_MASK == 0xffff
52 #define MASK_RGB( p ) (p)
53 #else
54 #define MASK_RGB( p ) ((p) & RGB_MASK)
55 #endif
56 
57 #define PIXEL( x ) PIXEL_OUT( ((x).RGB.a & 0xFF00) ? 0xFF : (x).RGB.a, \
58                               ((x).RGB.r & 0xFF00) ? 0xFF : (x).RGB.r, \
59                               ((x).RGB.g & 0xFF00) ? 0xFF : (x).RGB.g, \
60                               ((x).RGB.b & 0xFF00) ? 0xFF : (x).RGB.b )
61 
62 #define EXPAND( d, s ) do { \
63      (d).RGB.a = EXPAND_Ato8( (s & A_MASK) >> A_SHIFT ); \
64      (d).RGB.r = EXPAND_Rto8( (s & R_MASK) >> R_SHIFT ); \
65      (d).RGB.g = EXPAND_Gto8( (s & G_MASK) >> G_SHIFT ); \
66      (d).RGB.b = EXPAND_Bto8( (s & B_MASK) >> B_SHIFT ); \
67 } while (0)
68 
69 /********************************* Sop_PFI_Sto_Dacc ***************************/
70 
Sop_PFI_OP_Dacc(Sto)71 static void Sop_PFI_OP_Dacc(Sto)( GenefxState *gfxs )
72 {
73      int                l     = gfxs->length+1;
74      int                i     = gfxs->Xphase;
75      int                SperD = gfxs->SperD;
76      u16               *S     = gfxs->Sop[0];
77      int                Ostep = gfxs->Ostep;
78      GenefxAccumulator *D     = gfxs->Dacc;
79 
80      if (Ostep != 1)
81           D_UNIMPLEMENTED();
82 
83      while (--l) {
84           u16 s = S[i>>16];
85 
86           EXPAND( *D, s );
87 
88           ++D;
89           i += SperD;
90      }
91 }
92 
93 /********************************* Sop_PFI_SKto_Dacc **************************/
94 
Sop_PFI_OP_Dacc(SKto)95 static void Sop_PFI_OP_Dacc(SKto)( GenefxState *gfxs )
96 {
97      int                l     = gfxs->length+1;
98      int                i     = gfxs->Xphase;
99      int                SperD = gfxs->SperD;
100      u16               *S     = gfxs->Sop[0];
101      int                Ostep = gfxs->Ostep;
102      GenefxAccumulator *D     = gfxs->Dacc;
103      u16                Skey  = gfxs->Skey;
104 
105      if (Ostep != 1)
106           D_UNIMPLEMENTED();
107 
108      while (--l) {
109           u16 s = S[i>>16];
110 
111           if (MASK_RGB( s ) != Skey)
112                EXPAND( *D, s );
113           else
114                D->RGB.a = 0xF000;
115 
116           ++D;
117           i += SperD;
118      }
119 }
120 
121 /********************************* Sop_PFI_to_Dacc ****************************/
122 
Sop_PFI_OP_Dacc(to)123 static void Sop_PFI_OP_Dacc(to)( GenefxState *gfxs )
124 {
125      int             w, l = gfxs->length;
126      u16               *S = gfxs->Sop[0];
127      GenefxAccumulator *D = gfxs->Dacc;
128      int                Ostep = gfxs->Ostep;
129 
130      if (Ostep != 1) {
131           l++;
132           while (--l) {
133               u16 s = *S;
134 
135               EXPAND( *D, s );
136 
137               S += Ostep;
138 
139               ++D;
140           }
141           return;
142      }
143 
144      if ((long)S & 2) {
145           u16 s = *S++;
146 
147           EXPAND( *D, s );
148 
149           ++D;
150           --l;
151      }
152 
153      w = (l >> 1) +1;
154      while (--w) {
155           u32 s = *(u32 *) S;
156 
157 #ifdef WORDS_BIGENDIAN
158           EXPAND( D[0], s >> 16 );
159           EXPAND( D[1], s );
160 #else
161           EXPAND( D[0], s );
162           EXPAND( D[1], s >> 16);
163 #endif
164 
165           S += 2;
166           D += 2;
167      }
168 
169      if (l & 1) {
170           u16 s = *S;
171 
172           EXPAND( *D, s );
173      }
174 }
175 
176 /********************************* Sop_PFI_Kto_Dacc ***************************/
177 
Sop_PFI_OP_Dacc(Kto)178 static void Sop_PFI_OP_Dacc(Kto)( GenefxState *gfxs )
179 {
180      int                l    = gfxs->length+1;
181      u16               *S    = gfxs->Sop[0];
182      GenefxAccumulator *D    = gfxs->Dacc;
183      u16                Skey = gfxs->Skey;
184      int                Ostep = gfxs->Ostep;
185 
186      while (--l) {
187           u16 s = *S;
188 
189           if (MASK_RGB( s ) != Skey)
190                EXPAND( *D, s );
191           else
192                D->RGB.a = 0xF000;
193 
194           S += Ostep;
195           ++D;
196      }
197 }
198 
199 /********************************* Sacc_to_Aop_PFI ****************************/
200 
Sacc_OP_Aop_PFI(to)201 static void Sacc_OP_Aop_PFI(to)( GenefxState *gfxs )
202 {
203      int             w, l = gfxs->length;
204      GenefxAccumulator *S = gfxs->Sacc;
205      u16               *D = gfxs->Aop[0];
206      int                Dstep = gfxs->Astep;
207 
208      if (Dstep != 1) {
209           l++;
210           while (--l) {
211               if (!(S->RGB.a & 0xF000))
212                    *D = PIXEL( *S );
213 
214               ++S;
215               D += Dstep;
216           }
217           return;
218      }
219 
220      if ((long)D & 2) {
221           if (!(S->RGB.a & 0xF000))
222                *D = PIXEL( *S );
223 
224           ++S;
225           ++D;
226           --l;
227      }
228 
229      w = (l >> 1) +1;
230      while (--w) {
231           u32 *D2 = (u32 *) D;
232 
233           if (!(S[0].RGB.a & 0xF000) && !(S[1].RGB.a & 0xF000)) {
234 #ifdef WORDS_BIGENDIAN
235                *D2 = PIXEL( S[1] ) | PIXEL( S[0] ) << 16;
236 #else
237                *D2 = PIXEL( S[0] ) | PIXEL( S[1] ) << 16;
238 #endif
239           } else {
240                if (!(S[0].RGB.a & 0xF000))
241                     D[0] = PIXEL( S[0] );
242                else if (!(S[1].RGB.a & 0xF000))
243                     D[1] = PIXEL( S[1] );
244           }
245 
246           S += 2;
247           D += 2;
248      }
249 
250      if (l & 1) {
251           if (!(S->RGB.a & 0xF000))
252                *D = PIXEL( *S );
253      }
254 }
255 
256 /********************************* Sacc_Sto_Aop_PFI ***************************/
257 
Sacc_OP_Aop_PFI(Sto)258 static void Sacc_OP_Aop_PFI(Sto)( GenefxState *gfxs )
259 {
260      int             w, l     = gfxs->length;
261      int                i     = gfxs->Xphase;
262      int                SperD = gfxs->SperD;
263      GenefxAccumulator *Sacc  = gfxs->Sacc;
264      u16               *D     = gfxs->Aop[0];
265      int                Dstep = gfxs->Astep;
266 
267      if (Dstep != 1) {
268          l++;
269          while (--l) {
270               GenefxAccumulator *S = &Sacc[i>>16];
271 
272               if (!(S->RGB.a & 0xF000))
273                    *D = PIXEL( *S );
274 
275               D += Dstep;
276               i += SperD;
277          }
278          return;
279      }
280      if ((long)D & 2) {
281           GenefxAccumulator *S = Sacc;
282 
283           if (!(S->RGB.a & 0xF000))
284                *D = PIXEL( *S );
285 
286           ++D;
287           --l;
288           i += SperD;
289      }
290 
291      w = (l >> 1) +1;
292      while (--w) {
293           GenefxAccumulator *S0 = &Sacc[i>>16];
294           GenefxAccumulator *S1 = &Sacc[(i+SperD)>>16];
295           u32               *D2 = (u32 *) D;
296 
297           if (!(S0->RGB.a & 0xF000) && !(S1->RGB.a & 0xF000)) {
298 #ifdef WORDS_BIGENDIAN
299                *D2 = PIXEL( *S1 ) | PIXEL( *S0 ) << 16;
300 #else
301                *D2 = PIXEL( *S0 ) | PIXEL( *S1 ) << 16;
302 #endif
303           } else {
304                if (!(S0->RGB.a & 0xF000))
305                     D[0] = PIXEL( *S0 );
306                else if (!(S1->RGB.a & 0xF000))
307                     D[1] = PIXEL( *S1 );
308           }
309 
310           D += 2;
311           i += SperD << 1;
312      }
313 
314      if (l & 1) {
315           GenefxAccumulator *S = &Sacc[i>>16];
316 
317           if (!(S->RGB.a & 0xF000))
318                *D = PIXEL( *S );
319      }
320 }
321 
322 /********************************* Sacc_toK_Aop_PFI ***************************/
323 
Sacc_OP_Aop_PFI(toK)324 static void Sacc_OP_Aop_PFI(toK)( GenefxState *gfxs )
325 {
326      int                l    = gfxs->length+1;
327      GenefxAccumulator *S    = gfxs->Sacc;
328      u16               *D    = gfxs->Aop[0];
329      u16                Dkey = gfxs->Dkey;
330      int                Dstep = gfxs->Astep;
331 
332      while (--l) {
333           if (!(S->RGB.a & 0xF000) && MASK_RGB( *D ) == Dkey)
334                *D = PIXEL( *S );
335 
336           ++S;
337           D += Dstep;
338      }
339 }
340 
341 /********************************* Sacc_StoK_Aop_PFI **************************/
342 
Sacc_OP_Aop_PFI(StoK)343 static void Sacc_OP_Aop_PFI(StoK)( GenefxState *gfxs )
344 {
345      int                l     = gfxs->length+1;
346      int                i     = gfxs->Xphase;
347      int                SperD = gfxs->SperD;
348      GenefxAccumulator *Sacc  = gfxs->Sacc;
349      u16               *D     = gfxs->Aop[0];
350      u16                Dkey  = gfxs->Dkey;
351      int                Dstep = gfxs->Astep;
352 
353      while (--l) {
354           GenefxAccumulator *S = &Sacc[i>>16];
355 
356           if (!(S->RGB.a & 0xF000) && MASK_RGB( *D ) == Dkey)
357                *D = PIXEL( *S );
358 
359           D += Dstep;
360           i += SperD;
361      }
362 }
363 
364 /********************************* Sop_PFI_TEX_to_Dacc ***************************/
365 
Sop_PFI_OP_Dacc(TEX_to)366 static void Sop_PFI_OP_Dacc(TEX_to)( GenefxState *gfxs )
367 {
368      int                l     = gfxs->length+1;
369      int                s     = gfxs->s;
370      int                t     = gfxs->t;
371      int                SperD = gfxs->SperD;
372      int                TperD = gfxs->TperD;
373      u16               *S     = gfxs->Sop[0];
374      int                Ostep = gfxs->Ostep;
375      GenefxAccumulator *D     = gfxs->Dacc;
376      int                sp2   = gfxs->src_pitch / 2;
377 
378      if (Ostep != 1)
379           D_UNIMPLEMENTED();
380 
381      while (--l) {
382           u16 p = S[(s>>16) + (t>>16) * sp2];
383 
384           EXPAND( *D, p );
385 
386           ++D;
387           s += SperD;
388           t += TperD;
389      }
390 }
391 
392 /********************************* Sop_PFI_TEX_Kto_Dacc ***************************/
393 
Sop_PFI_OP_Dacc(TEX_Kto)394 static void Sop_PFI_OP_Dacc(TEX_Kto)( GenefxState *gfxs )
395 {
396      int                l     = gfxs->length+1;
397      int                s     = gfxs->s;
398      int                t     = gfxs->t;
399      int                SperD = gfxs->SperD;
400      int                TperD = gfxs->TperD;
401      u16               *S     = gfxs->Sop[0];
402      u16                Skey  = gfxs->Skey;
403      int                Ostep = gfxs->Ostep;
404      GenefxAccumulator *D     = gfxs->Dacc;
405      int                sp2   = gfxs->src_pitch / 2;
406 
407      if (Ostep != 1)
408           D_UNIMPLEMENTED();
409 
410      while (--l) {
411           u16 p = S[(s>>16) + (t>>16) * sp2];
412 
413           if ((p & RGB_MASK) != Skey)
414                EXPAND( *D, p );
415           else
416                D->RGB.a = 0xF000;
417 
418           ++D;
419           s += SperD;
420           t += TperD;
421      }
422 }
423 
424 /******************************************************************************/
425 
426 #undef RGB_MASK
427 #undef MASK_RGB
428 #undef PIXEL
429 #undef EXPAND
430 
431 #undef A_SHIFT
432 #undef R_SHIFT
433 #undef G_SHIFT
434 #undef B_SHIFT
435 #undef A_MASK
436 #undef R_MASK
437 #undef G_MASK
438 #undef B_MASK
439 #undef PIXEL_OUT
440 #undef EXPAND_Ato8
441 #undef EXPAND_Rto8
442 #undef EXPAND_Gto8
443 #undef EXPAND_Bto8
444 #undef Sop_PFI_OP_Dacc
445 #undef Sacc_OP_Aop_PFI
446