refresh 080b1da3c594fb6ca84009c352cc5fb9cc294c43
[tagua/yd.git] / src / imageeffects_mmx.cpp
blobe14f142f505b30f61551fe83e587b330beba9abd
1 /*
2 Copyright (c) 2006 Paolo Capriotti <p.capriotti@gmail.com>
3 (c) 2006 Maurizio Monge <maurizio.monge@kdemail.net>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9 */
11 #include <math.h>
12 #include <inttypes.h>
13 #include <mmintrin.h>
14 #include <QImage>
17 namespace ImageEffects {
19 union vec4s
21 uint16_t i[4];
22 __m64 v;
25 static inline void blur_mmx(void *px, __m64& v, __m64& alpha)
27 uint64_t z1 = 0ULL;
28 uint64_t z2 = 0ULL;
29 asm(
30 "movd %[pixel], %[t1]\n"
31 "punpcklbw %[t1], %[t2]\n"
32 "psrlw $1, %[t2]\n"
33 "psubw %[accum], %[t2]\n"
34 "pmulhw %[alpha], %[t2]\n"
35 "psllw $1, %[t2]\n"
36 "paddw %[t2], %[accum]\n"
37 "movq %[accum], %[t1]\n"
38 "psrlw $7, %[t1]\n"
39 // "pand %[mask], %[t1]\n"
40 "packuswb %[t1], %[t1]\n"
41 "movd %[t1], %[pixel]\n"
42 : [pixel] "+m"(*(uint32_t*)px)
43 , [accum] "+y"(v)
44 , [t1] "+y"(z1)
45 , [t2] "+y"(z2)
46 : [alpha] "y"(alpha)
47 // , [mask] "y"(0x00ff00ff00ff00ffULL)
51 void expblur_mmx( QImage &img, int radius )
53 if(radius<1)
54 return;
56 /* Calculate the alpha such that 90% of
57 the kernel is within the radius.
58 (Kernel extends to infinity)
60 uint16_t alpha = (uint16_t)((1<<15)*(1.0f-expf(-2.3f/(radius+1.f))));
62 vec4s a;
63 QRgb *ptr = (QRgb *)img.bits();
64 int h = img.height();
65 int w = img.width();
66 int hw = (img.height()-1)*img.width();
67 for(int i=0;i<4;i++)
68 a.i[i] = alpha;
70 for(int row=0;row<h;row++)
72 vec4s z;
73 uint8_t *cptr = (uint8_t*)(ptr+row*w);
74 for(int i=0;i<4;i++)
75 z.i[i] = cptr[i]<<7;
77 for(int index=1; index<w; index++)
78 blur_mmx(&cptr[index*4], z.v, a.v);
80 for(int index=w-2; index>=0; index--)
81 blur_mmx(&cptr[index*4], z.v, a.v);
84 for(int col=0;col<w;col++)
86 vec4s z;
87 uint8_t *cptr = (uint8_t*)(ptr+col);
89 for(int i=0;i<4;i++)
90 z.i[i] = cptr[i]<<7;
92 for(int index=w; index<hw; index+=w)
93 blur_mmx(&cptr[index*4], z.v, a.v);
95 for(int index=hw-w; index>=0; index-=w)
96 blur_mmx(&cptr[index*4], z.v, a.v);
99 asm("emms");
100 return;
103 } //end namespace ImageEffects