2 * Copyright (c) 2007-2013, Czirkos Zoltan http://code.google.com/p/gdash/
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 #ifndef _GD_pixbufmanip_hqx
17 #define _GD_pixbufmanip_hqx
23 #include "gfx/pixbufmanip.hpp"
24 #include "gfx/pixbuf.hpp"
26 #define Ymask 0x00FF0000
27 #define Umask 0x0000FF00
28 #define Vmask 0x000000FF
29 #define trY 0x00300000
30 #define trU 0x00000700
31 #define trV 0x00000006
33 // These masks are used to mask out two bytes from an guint32
35 // When interpolating, all r g b and a values must be interpolated.
36 // These enable the interpolation functions to do two multiplications
38 #define MASK_24 0xFF00FF00
39 #define MASK_13 0x00FF00FF
42 inline guint32
RGBtoYUV(guint32 c
) {
43 guint32 r
, g
, b
, y
, u
, v
;
44 r
= (c
& Pixbuf::rmask
) >> Pixbuf::rshift
;
45 g
= (c
& Pixbuf::gmask
) >> Pixbuf::gshift
;
46 b
= (c
& Pixbuf::bmask
) >> Pixbuf::bshift
;
47 // y = (guint32)(0.299*r + 0.587*g + 0.114*b);
48 // u = (guint32)(-0.169*r - 0.331*g + 0.5*b) + 128;
49 // v = (guint32)(0.5*r - 0.419*g - 0.081*b) + 128;
50 // changed to fixed point math
51 y
= (77*r
+ 150*g
+ 29*b
)>>8;
52 u
= (32768 + -43*r
- 85*g
+ 128*b
)>>8;
53 v
= (32768 + 128*r
- 107*g
- 21*b
)>>8;
54 return (y
<< 16) + (u
<< 8) + v
;
57 /* Test if there is difference in color */
58 inline int Diff(guint32 w1
, guint32 w2
)
60 guint32 YUV1
= RGBtoYUV(w1
);
61 guint32 YUV2
= RGBtoYUV(w2
);
62 return ( abs((YUV1
& Ymask
) - (YUV2
& Ymask
)) > trY
)
63 || ( abs((YUV1
& Umask
) - (YUV2
& Umask
)) > trU
)
64 || ( abs((YUV1
& Vmask
) - (YUV2
& Vmask
)) > trV
);
67 /* Interpolate functions */
68 inline void Interp1(guint32
* pc
, guint32 c1
, guint32 c2
)
75 *pc
= ((((c1
& MASK_24
)/4 * 3 + (c2
& MASK_24
)/4)) & MASK_24
)
76 + ((((c1
& MASK_13
)/4 * 3 + (c2
& MASK_13
)/4)) & MASK_13
);
79 inline void Interp2(guint32
* pc
, guint32 c1
, guint32 c2
, guint32 c3
)
81 //*pc = (c1*2+c2+c3)/4;
82 *pc
= ((((c1
& MASK_24
)/4 * 2 + (c2
& MASK_24
)/4 + (c3
& MASK_24
)/4)) & MASK_24
)
83 + ((((c1
& MASK_13
)/4 * 2 + (c2
& MASK_13
)/4 + (c3
& MASK_13
)/4)) & MASK_13
);
86 inline void Interp3(guint32
* pc
, guint32 c1
, guint32 c2
)
93 *pc
= ((((c1
& MASK_24
)/8 * 7 + (c2
& MASK_24
)/8)) & MASK_24
) +
94 ((((c1
& MASK_13
)/8 * 7 + (c2
& MASK_13
)/8)) & MASK_13
);
97 inline void Interp4(guint32
* pc
, guint32 c1
, guint32 c2
, guint32 c3
)
99 //*pc = (c1*2+(c2+c3)*7)/16;
100 *pc
= ((((c1
& MASK_24
)/16 * 2 + (c2
& MASK_24
)/16 * 7 + (c3
& MASK_24
)/16 * 7)) & MASK_24
) +
101 ((((c1
& MASK_13
)/16 * 2 + (c2
& MASK_13
)/16 * 7 + (c3
& MASK_13
)/16 * 7)) & MASK_13
);
104 inline void Interp5(guint32
* pc
, guint32 c1
, guint32 c2
)
111 *pc
= ((((c1
& MASK_24
)/2 + (c2
& MASK_24
)/2)) & MASK_24
) +
112 ((((c1
& MASK_13
)/2 + (c2
& MASK_13
)/2)) & MASK_13
);
115 inline void Interp6(guint32
* pc
, guint32 c1
, guint32 c2
, guint32 c3
)
117 //*pc = (c1*5+c2*2+c3)/8;
118 *pc
= ((((c1
& MASK_24
)/8 * 5 + (c2
& MASK_24
)/8 * 2 + (c3
& MASK_24
)/8)) & MASK_24
) +
119 ((((c1
& MASK_13
)/8 * 5 + (c2
& MASK_13
)/8 * 2 + (c3
& MASK_13
)/8)) & MASK_13
);
122 inline void Interp7(guint32
* pc
, guint32 c1
, guint32 c2
, guint32 c3
)
124 //*pc = (c1*6+c2+c3)/8;
125 *pc
= ((((c1
& MASK_24
)/8 * 6 + (c2
& MASK_24
)/8 + (c3
& MASK_24
)/8)) & MASK_24
) +
126 ((((c1
& MASK_13
)/8 * 6 + (c2
& MASK_13
)/8 + (c3
& MASK_13
)/8)) & MASK_13
);
129 inline void Interp8(guint32
* pc
, guint32 c1
, guint32 c2
)
131 //*pc = (c1*5+c2*3)/8;
136 *pc
= ((((c1
& MASK_24
)/8 * 5 + (c2
& MASK_24
)/8 * 3)) & MASK_24
) +
137 ((((c1
& MASK_13
)/8 * 5 + (c2
& MASK_13
)/8 * 3)) & MASK_13
);
140 inline void Interp9(guint32
* pc
, guint32 c1
, guint32 c2
, guint32 c3
)
142 //*pc = (c1*2+(c2+c3)*3)/8;
143 *pc
= ((((c1
& MASK_24
)/8 * 2 + (c2
& MASK_24
)/8 * 3 + (c3
& MASK_24
)/8 * 3)) & MASK_24
) +
144 ((((c1
& MASK_13
)/8 * 2 + (c2
& MASK_13
)/8 * 3 + (c3
& MASK_13
)/8 * 3)) & MASK_13
);
147 inline void Interp10(guint32
* pc
, guint32 c1
, guint32 c2
, guint32 c3
)
149 //*pc = (c1*14+c2+c3)/16;
150 *pc
= ((((c1
& MASK_24
)/16 * 14 + (c2
& MASK_24
)/16 + (c3
& MASK_24
)/16)) & MASK_24
) +
151 ((((c1
& MASK_13
)/16 * 14 + (c2
& MASK_13
)/16 + (c3
& MASK_13
)/16)) & MASK_13
);