FreeBASIC  0.91.0
gfx_put_blend.c
Go to the documentation of this file.
1 /* BLEND drawing method for PUT statement */
2 
3 #include "fb_gfx.h"
4 
5 
6 extern void fb_hPutTrans1C(unsigned char *src, unsigned char *dest, int w, int h, int src_pitch, int dest_pitch, int alpha, BLENDER *blender, void *param);
7 extern void fb_hPutTrans(unsigned char *src, unsigned char *dest, int w, int h, int src_pitch, int dest_pitch, int alpha, BLENDER *blender, void *param);
8 
9 #ifdef HOST_X86
10 
11 #include "x86/fb_gfx_mmx.h"
12 
13 extern void fb_hPutTrans1MMX(unsigned char *src, unsigned char *dest, int w, int h, int src_pitch, int dest_pitch, int alpha, BLENDER *blender, void *param);
14 extern void fb_hPutBlend2MMX(unsigned char *src, unsigned char *dest, int w, int h, int src_pitch, int dest_pitch, int alpha, BLENDER *blender, void *param);
15 extern void fb_hPutBlend4MMX(unsigned char *src, unsigned char *dest, int w, int h, int src_pitch, int dest_pitch, int alpha, BLENDER *blender, void *param);
16 
17 #endif
18 
19 
20 /*:::::*/
21 static void fb_hPutBlend2C(unsigned char *src, unsigned char *dest, int w, int h, int src_pitch, int dest_pitch, int alpha, BLENDER *blender, void *param)
22 {
23  unsigned short *s = (unsigned short *)src, *d;
24  unsigned int sc, dc, drb, dg, srb, sg, dt, st;
25  int x;
26 
27  alpha = (alpha + 7) >> 3;
28  src_pitch = (src_pitch >> 1) - w;
29  for (; h; h--) {
30  d = (unsigned short *)dest;
31  if (w & 1) {
32  sc = *s++;
33  if (sc != 0xF81F) {
34  dc = *(unsigned short *)d;
35  srb = sc & MASK_RB_16;
36  sg = sc & MASK_G_16;
37  drb = dc & MASK_RB_16;
38  dg = dc & MASK_G_16;
39  srb = ((srb - drb) * alpha) >> 5;
40  sg = ((sg - dg) * alpha) >> 5;
41  *(unsigned short *)d = ((drb + srb) & MASK_RB_16) | ((dg + sg) & MASK_G_16);
42  }
43  d++;
44  }
45  for (x = w >> 1; x; x--) {
46  sc = *(unsigned int *)s;
47  if (sc != 0xF81FF81F) {
48  dc = *(unsigned int *)d;
49  if ((sc & 0xFFFF) == 0xF81F) {
50  sc &= 0xFFFF0000;
51  sc |= (dc & 0xFFFF);
52  }
53  if ((sc & 0xFFFF0000) == 0xF81F0000) {
54  sc &= 0xFFFF;
55  sc |= (dc & 0xFFFF0000);
56  }
57  st = sc & (MASK_RB_16 | (MASK_G_16 << 16));
58  sc &= (MASK_G_16 | (MASK_RB_16 << 16));
59  dt = dc & (MASK_RB_16 | (MASK_G_16 << 16));
60  dc &= (MASK_G_16 | (MASK_RB_16 << 16));
61  dc = ((((sc >> 5) - (dc >> 5)) * alpha) + dc) & (MASK_G_16 | (MASK_RB_16 << 16));
62  sc = ((((st - dt) * alpha) >> 5) + dt) & (MASK_RB_16 | (MASK_G_16 << 16));
63  *(unsigned int *)d = dc | sc;
64  }
65  s += 2;
66  d += 2;
67  }
68  s += src_pitch;
69  dest += dest_pitch;
70  }
71 }
72 
73 
74 /*:::::*/
75 static void fb_hPutBlend4C(unsigned char *src, unsigned char *dest, int w, int h, int src_pitch, int dest_pitch, int alpha, BLENDER *blender, void *param)
76 {
77  unsigned int *s = (unsigned int *)src;
78  unsigned int *d, sc, dc, drb, dga, srb, sga;
79  int x;
80 
81  alpha++;
82  src_pitch = (src_pitch >> 2) - w;
83  for (; h; h--) {
84  d = (unsigned int *)dest;
85  for (x = w; x; x--) {
86  sc = *s++;
87  if ((sc & 0xFFFFFF) != 0xFF00FF) {
88  dc = *d;
89  srb = sc & MASK_RB_32;
90  sga = sc & MASK_GA_32;
91  drb = dc & MASK_RB_32;
92  dga = dc & MASK_GA_32;
93  srb = ((srb - drb) * alpha) >> 8;
94  sga = ((sga - dga) >> 8) * alpha;
95  *d = ((drb + srb) & MASK_RB_32) | ((dga + sga) & MASK_GA_32);
96  }
97  d++;
98  }
99  s += src_pitch;
100  dest += dest_pitch;
101  }
102 }
103 
104 
105 /*:::::*/
106 void fb_hPutBlend(unsigned char *src, unsigned char *dest, int w, int h, int src_pitch, int dest_pitch, int alpha, BLENDER *blender, void *param)
107 {
108  static PUTTER *all_putters[] = {
110 #ifdef HOST_X86
111  fb_hPutTrans1MMX, fb_hPutBlend2MMX, NULL, fb_hPutBlend4MMX,
112 #endif
113  };
114  PUTTER *putter;
116 
117  if (alpha == 0) {
118  return;
119  }
120 
121  context = fb_hGetContext();
122 
123  if (!context->putter[PUT_MODE_BLEND]) {
124 #ifdef HOST_X86
125  if (__fb_gfx->flags & HAS_MMX)
126  context->putter[PUT_MODE_BLEND] = &all_putters[4];
127  else
128 #endif
129  context->putter[PUT_MODE_BLEND] = &all_putters[0];
130  }
131  putter = context->putter[PUT_MODE_BLEND][context->target_bpp - 1];
132  alpha &= 0xFF;
133 
134  putter(src, dest, w, h, src_pitch, dest_pitch, alpha, blender, param);
135 }