2 Ordered dithering methods provided for:
11 template<int m, int in_max>
12 int QuantizeFunc(size_t quant_pos, double value)
14 - Quantizes value, assumed to be in range 0..in_max, to range 0..m
15 - quant_pos tells the coordinate into the dithering matrix
17 template<int m, int in_max>
18 int QuantizeFunc(size_t quant_pos, unsigned value)
20 - Quantizes value, assumed to be in range 0..in_max, to range 0..m
21 - quant_pos tells the coordinate into the dithering matrix
23 Copyright (C) 1992,2008 Joel Yliluoma (http://iki.fi/bisqwit/)
26 #define OrderedDitherDecl(n) \
27 static const double flts[n]; \
28 static const int ints[n]; \
31 even = !(maxin % mul), \
32 intmul = even ? 1 : mul };
34 /* macroes for initializing dither tables */
35 #define d(n) (n)/double(mul) - 0.5
36 #define i(n) even ? (n*in_max/mul - (int)in_max/2) \
37 : (n*in_max - (int)mul*in_max/2)
39 template<int m
, int in_max
= 255>
40 struct QuantizeNoDither
43 template<typename IntType
>
44 QuantizeNoDither(IntType v
) : res(v
* m
/ in_max
) { }
45 operator int() const { return res
; }
48 template<int m
, typename Base
>
49 struct QuantizeFuncBase
: private Base
53 QuantizeFuncBase(size_t quant_pos
, double v
) : res(0)
57 const double dither_threshold
= Base::flts
[quant_pos
];
58 res
= (int)(v
* (m
/ double(Base::maxin
)) + dither_threshold
);
63 QuantizeFuncBase(size_t quant_pos
, unsigned char v
) : res(v
)
65 if(m
== Base::maxin
) return;
69 const int dither_threshold
= Base::ints
[quant_pos
];
70 const int intmul
= Base::intmul
;
71 res
= (res
* (m
* intmul
) + dither_threshold
) / (Base::maxin
* intmul
);
76 res
= QuantizeNoDither
<m
, Base::maxin
> (res
);
81 #define QuantizeFuncDecl(name, base) \
82 template<int m, int in_max=255> \
83 struct name: private QuantizeFuncBase<m, base<in_max> > \
85 typedef QuantizeFuncBase<m, base<in_max> > Base; \
86 template<typename A, typename B> name(A a, B b) : Base(a, b) { } \
87 operator int() const { return Base::res; } \
90 /******* Quantizing with 8x8 ordered dithering ********/
91 template<int in_max
> struct OrderedDither_8x8
{ OrderedDitherDecl(8*8) };
93 const double OrderedDither_8x8
<in_max
>::flts
[] /* A table for 8x8 ordered dithering */
94 = { d(1 ), d(49), d(13), d(61), d( 4), d(52), d(16), d(64),
95 d(33), d(17), d(45), d(29), d(36), d(20), d(48), d(32),
96 d(9 ), d(57), d( 5), d(53), d(12), d(60), d( 8), d(56),
97 d(41), d(25), d(37), d(21), d(44), d(28), d(40), d(24),
98 d(3 ), d(51), d(15), d(63), d( 2), d(50), d(14), d(62),
99 d(35), d(19), d(47), d(31), d(34), d(18), d(46), d(30),
100 d(11), d(59), d( 7), d(55), d(10), d(58), d( 6), d(54),
101 d(43), d(27), d(39), d(23), d(42), d(26), d(38), d(22) };
103 const int OrderedDither_8x8
<in_max
>::ints
[]
104 = { i(1 ), i(49), i(13), i(61), i( 4), i(52), i(16), i(64),
105 i(33), i(17), i(45), i(29), i(36), i(20), i(48), i(32),
106 i(9 ), i(57), i( 5), i(53), i(12), i(60), i( 8), i(56),
107 i(41), i(25), i(37), i(21), i(44), i(28), i(40), i(24),
108 i(3 ), i(51), i(15), i(63), i( 2), i(50), i(14), i(62),
109 i(35), i(19), i(47), i(31), i(34), i(18), i(46), i(30),
110 i(11), i(59), i( 7), i(55), i(10), i(58), i( 6), i(54),
111 i(43), i(27), i(39), i(23), i(42), i(26), i(38), i(22) };
112 QuantizeFuncDecl(Quantize8x8
, OrderedDither_8x8
);
115 /******* Quantizing with 4x4 ordered dithering ********/
116 template<int in_max
> struct OrderedDither_4x4
{ OrderedDitherDecl(4*4) };
118 const double OrderedDither_4x4
<in_max
>::flts
[] /* A table for 4x4 ordered dithering */
119 = { d( 1), d( 9), d( 3), d(11),
120 d(13), d( 5), d(15), d( 7),
121 d( 4), d(12), d( 2), d(10),
122 d(16), d( 8), d(14), d( 6) };
124 const int OrderedDither_4x4
<in_max
>::ints
[]
125 = { i( 1), i( 9), i( 3), i(11),
126 i(13), i( 5), i(15), i( 7),
127 i( 4), i(12), i( 2), i(10),
128 i(16), i( 8), i(14), i( 6) };
129 QuantizeFuncDecl(Quantize4x4
, OrderedDither_4x4
);
131 /******* Quantizing with 3x3 ordered dithering ********/
132 template<int in_max
> struct OrderedDither_3x3
{ OrderedDitherDecl(3*3) };
134 const double OrderedDither_3x3
<in_max
>::flts
[] /* A table for 3x3 ordered dithering */
135 = { d(1), d(7), d(3),
139 const int OrderedDither_3x3
<in_max
>::ints
[]
140 = { i(1), i(7), i(3),
143 QuantizeFuncDecl(Quantize3x3
, OrderedDither_3x3
);
145 /******* Quantizing with 4x2 ordered dithering ********/
146 template<int in_max
> struct OrderedDither_4x2
{ OrderedDitherDecl(4*2) };
148 const double OrderedDither_4x2
<in_max
>::flts
[] /* A table for 4x2 ordered dithering */
149 = { d(1), d(5), d(2), d(6),
150 d(7), d(3), d(8), d(4) };
152 const int OrderedDither_4x2
<in_max
>::ints
[]
153 = { i(1), i(5), i(2), i(6),
154 i(7), i(3), i(8), i(4) };
155 QuantizeFuncDecl(Quantize4x2
, OrderedDither_4x2
);
157 /******* Quantizing with 3x2 ordered dithering ********/
158 template<int in_max
> struct OrderedDither_3x2
{ OrderedDitherDecl(3*2) };
160 const double OrderedDither_3x2
<in_max
>::flts
[] /* A table for 3x2 ordered dithering */
161 = { d(1), d(5), d(3),
164 const int OrderedDither_3x2
<in_max
>::ints
[]
165 = { i(1), i(5), i(3),
167 QuantizeFuncDecl(Quantize3x2
, OrderedDither_3x2
);
169 /******* Quantizing with 2x2 ordered dithering ********/
170 template<int in_max
> struct OrderedDither_2x2
{ OrderedDitherDecl(2*2) };
172 const double OrderedDither_2x2
<in_max
>::flts
[] /* A table for 2x2 ordered dithering */
176 const int OrderedDither_2x2
<in_max
>::ints
[]
179 QuantizeFuncDecl(Quantize2x2
, OrderedDither_2x2
);
182 #undef OrderedDitherDecl
183 #undef QuantizeFuncDecl