Glide Plugin GLES2 port from mupen64plus-ae, but with special FrameSkip code
[mupen64plus-pandora.git] / source / gles2glide64 / src / GlideHQ / TextureFilters_hq2x.cpp
1 /*
2 Copyright (C) 2003 Rice1964
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
17
18 */
19
20 /* Copyright (C) 2007 Hiroshi Morii <koolsmoky(at)users.sourceforge.net>
21  * Modified for the Texture Filtering library
22  */
23
24 /* 2007 Mudlord - Added hq2xS lq2xS filters */
25
26 #include "TextureFilters.h"
27
28 /************************************************************************/
29 /* hq2x filters                                                         */
30 /************************************************************************/
31
32 /***************************************************************************/
33 /* Basic types */
34
35 /***************************************************************************/
36 /* interpolation */
37
38 //static unsigned interp_bits_per_pixel;
39
40 #if !_16BPP_HACK
41 #define INTERP_16_MASK_1_3(v) ((v)&0x0F0F)
42 #define INTERP_16_MASK_SHIFT_2_4(v) (((v)&0xF0F0)>>4)
43 #define INTERP_16_MASK_SHIFTBACK_2_4(v) ((INTERP_16_MASK_1_3(v))<<4)
44
45 static uint16 hq2x_interp_16_521(uint16 p1, uint16 p2, uint16 p3)
46 {
47   return INTERP_16_MASK_1_3((INTERP_16_MASK_1_3(p1)*5 + INTERP_16_MASK_1_3(p2)*2 + INTERP_16_MASK_1_3(p3)*1) / 8)
48     | INTERP_16_MASK_SHIFTBACK_2_4((INTERP_16_MASK_SHIFT_2_4(p1)*5 + INTERP_16_MASK_SHIFT_2_4(p2)*2 + INTERP_16_MASK_SHIFT_2_4(p3)*1) / 8);
49 }
50
51 static uint16 hq2x_interp_16_332(uint16 p1, uint16 p2, uint16 p3)
52 {
53   return INTERP_16_MASK_1_3((INTERP_16_MASK_1_3(p1)*3 + INTERP_16_MASK_1_3(p2)*3 + INTERP_16_MASK_1_3(p3)*2) / 8)
54     | INTERP_16_MASK_SHIFTBACK_2_4((INTERP_16_MASK_SHIFT_2_4(p1)*3 + INTERP_16_MASK_SHIFT_2_4(p2)*3 + INTERP_16_MASK_SHIFT_2_4(p3)*2) / 8);
55 }
56
57 static uint16 hq2x_interp_16_611(uint16 p1, uint16 p2, uint16 p3)
58 {
59   return INTERP_16_MASK_1_3((INTERP_16_MASK_1_3(p1)*6 + INTERP_16_MASK_1_3(p2) + INTERP_16_MASK_1_3(p3)) / 8)
60     | INTERP_16_MASK_SHIFTBACK_2_4((INTERP_16_MASK_SHIFT_2_4(p1)*6 + INTERP_16_MASK_SHIFT_2_4(p2) + INTERP_16_MASK_SHIFT_2_4(p3)) / 8);
61 }
62
63 static uint16 hq2x_interp_16_71(uint16 p1, uint16 p2)
64 {
65   return INTERP_16_MASK_1_3((INTERP_16_MASK_1_3(p1)*7 + INTERP_16_MASK_1_3(p2)) / 8)
66     | INTERP_16_MASK_SHIFTBACK_2_4((INTERP_16_MASK_SHIFT_2_4(p1)*7 + INTERP_16_MASK_SHIFT_2_4(p2)) / 8);
67 }
68
69 static uint16 hq2x_interp_16_211(uint16 p1, uint16 p2, uint16 p3)
70 {
71   return INTERP_16_MASK_1_3((INTERP_16_MASK_1_3(p1)*2 + INTERP_16_MASK_1_3(p2) + INTERP_16_MASK_1_3(p3)) / 4)
72     | INTERP_16_MASK_SHIFTBACK_2_4((INTERP_16_MASK_SHIFT_2_4(p1)*2 + INTERP_16_MASK_SHIFT_2_4(p2) + INTERP_16_MASK_SHIFT_2_4(p3)) / 4);
73 }
74
75 static uint16 hq2x_interp_16_772(uint16 p1, uint16 p2, uint16 p3)
76 {
77   return INTERP_16_MASK_1_3(((INTERP_16_MASK_1_3(p1) + INTERP_16_MASK_1_3(p2))*7 + INTERP_16_MASK_1_3(p3)*2) / 16)
78     | INTERP_16_MASK_SHIFTBACK_2_4(((INTERP_16_MASK_SHIFT_2_4(p1) + INTERP_16_MASK_SHIFT_2_4(p2))*7 + INTERP_16_MASK_SHIFT_2_4(p3)*2) / 16);
79 }
80
81 static uint16 hq2x_interp_16_11(uint16 p1, uint16 p2)
82 {
83   return INTERP_16_MASK_1_3((INTERP_16_MASK_1_3(p1) + INTERP_16_MASK_1_3(p2)) / 2)
84     | INTERP_16_MASK_SHIFTBACK_2_4((INTERP_16_MASK_SHIFT_2_4(p1) + INTERP_16_MASK_SHIFT_2_4(p2)) / 2);
85 }
86
87 static uint16 hq2x_interp_16_31(uint16 p1, uint16 p2)
88 {
89   return INTERP_16_MASK_1_3((INTERP_16_MASK_1_3(p1)*3 + INTERP_16_MASK_1_3(p2)) / 4)
90     | INTERP_16_MASK_SHIFTBACK_2_4((INTERP_16_MASK_SHIFT_2_4(p1)*3 + INTERP_16_MASK_SHIFT_2_4(p2)) / 4);
91 }
92
93 static uint16 hq2x_interp_16_1411(uint16 p1, uint16 p2, uint16 p3)
94 {
95   return INTERP_16_MASK_1_3((INTERP_16_MASK_1_3(p1)*14 + INTERP_16_MASK_1_3(p2) + INTERP_16_MASK_1_3(p3)) / 16)
96     | INTERP_16_MASK_SHIFTBACK_2_4((INTERP_16_MASK_SHIFT_2_4(p1)*14 + INTERP_16_MASK_SHIFT_2_4(p2) + INTERP_16_MASK_SHIFT_2_4(p3)) / 16);
97 }
98
99 static uint16 hq2x_interp_16_431(uint16 p1, uint16 p2, uint16 p3)
100 {
101   return INTERP_16_MASK_1_3((INTERP_16_MASK_1_3(p1)*4 + INTERP_16_MASK_1_3(p2)*3 + INTERP_16_MASK_1_3(p3)) / 8)
102     | INTERP_16_MASK_SHIFTBACK_2_4((INTERP_16_MASK_SHIFT_2_4(p1)*4 + INTERP_16_MASK_SHIFT_2_4(p2)*3 + INTERP_16_MASK_SHIFT_2_4(p3)) / 8);
103 }
104
105 static uint16 hq2x_interp_16_53(uint16 p1, uint16 p2)
106 {
107   return INTERP_16_MASK_1_3((INTERP_16_MASK_1_3(p1)*5 + INTERP_16_MASK_1_3(p2)*3) / 8)
108     | INTERP_16_MASK_SHIFTBACK_2_4((INTERP_16_MASK_SHIFT_2_4(p1)*5 + INTERP_16_MASK_SHIFT_2_4(p2)*3) / 8);
109 }
110
111 static uint16 hq2x_interp_16_151(uint16 p1, uint16 p2)
112 {
113   return INTERP_16_MASK_1_3((INTERP_16_MASK_1_3(p1)*15 + INTERP_16_MASK_1_3(p2)) / 16)
114     | INTERP_16_MASK_SHIFTBACK_2_4((INTERP_16_MASK_SHIFT_2_4(p1)*15 + INTERP_16_MASK_SHIFT_2_4(p2)) / 16);
115 }
116
117 static uint16 hq2x_interp_16_97(uint16 p1, uint16 p2)
118 {
119   return INTERP_16_MASK_1_3((INTERP_16_MASK_1_3(p1)*9 + INTERP_16_MASK_1_3(p2)*7) / 16)
120     | INTERP_16_MASK_SHIFTBACK_2_4((INTERP_16_MASK_SHIFT_2_4(p1)*9 + INTERP_16_MASK_SHIFT_2_4(p2)*7) / 16);
121 }
122 #endif /* !_16BPP_HACK */
123
124 #define INTERP_32_MASK_1_3(v) ((v)&0x00FF00FF)
125 #define INTERP_32_MASK_SHIFT_2_4(v) (((v)&0xFF00FF00)>>8)
126 #define INTERP_32_MASK_SHIFTBACK_2_4(v) (((INTERP_32_MASK_1_3(v))<<8))
127
128 static uint32 hq2x_interp_32_521(uint32 p1, uint32 p2, uint32 p3)
129 {
130   return INTERP_32_MASK_1_3((INTERP_32_MASK_1_3(p1)*5 + INTERP_32_MASK_1_3(p2)*2 + INTERP_32_MASK_1_3(p3)*1) / 8)
131     | INTERP_32_MASK_SHIFTBACK_2_4((INTERP_32_MASK_SHIFT_2_4(p1)*5 + INTERP_32_MASK_SHIFT_2_4(p2)*2 + INTERP_32_MASK_SHIFT_2_4(p3)*1) / 8);
132 }
133
134 static uint32 hq2x_interp_32_332(uint32 p1, uint32 p2, uint32 p3)
135 {
136   return INTERP_32_MASK_1_3((INTERP_32_MASK_1_3(p1)*3 + INTERP_32_MASK_1_3(p2)*3 + INTERP_32_MASK_1_3(p3)*2) / 8)
137     | INTERP_32_MASK_SHIFTBACK_2_4((INTERP_32_MASK_SHIFT_2_4(p1)*3 + INTERP_32_MASK_SHIFT_2_4(p2)*3 + INTERP_32_MASK_SHIFT_2_4(p3)*2) / 8);
138 }
139
140 static uint32 hq2x_interp_32_211(uint32 p1, uint32 p2, uint32 p3)
141 {
142   return INTERP_32_MASK_1_3((INTERP_32_MASK_1_3(p1)*2 + INTERP_32_MASK_1_3(p2) + INTERP_32_MASK_1_3(p3)) / 4)
143     | INTERP_32_MASK_SHIFTBACK_2_4((INTERP_32_MASK_SHIFT_2_4(p1)*2 + INTERP_32_MASK_SHIFT_2_4(p2) + INTERP_32_MASK_SHIFT_2_4(p3)) / 4);
144 }
145
146 static uint32 hq2x_interp_32_611(uint32 p1, uint32 p2, uint32 p3)
147 {
148   return INTERP_32_MASK_1_3((INTERP_32_MASK_1_3(p1)*6 + INTERP_32_MASK_1_3(p2) + INTERP_32_MASK_1_3(p3)) / 8)
149     | INTERP_32_MASK_SHIFTBACK_2_4((INTERP_32_MASK_SHIFT_2_4(p1)*6 + INTERP_32_MASK_SHIFT_2_4(p2) + INTERP_32_MASK_SHIFT_2_4(p3)) / 8);
150 }
151
152 static uint32 hq2x_interp_32_31(uint32 p1, uint32 p2)
153 {
154   return INTERP_32_MASK_1_3((INTERP_32_MASK_1_3(p1)*3 + INTERP_32_MASK_1_3(p2)) / 4)
155     | INTERP_32_MASK_SHIFTBACK_2_4((INTERP_32_MASK_SHIFT_2_4(p1)*3 + INTERP_32_MASK_SHIFT_2_4(p2)) / 4);
156 }
157
158 static uint32 hq2x_interp_32_1411(uint32 p1, uint32 p2, uint32 p3)
159 {
160   return INTERP_32_MASK_1_3((INTERP_32_MASK_1_3(p1)*14 + INTERP_32_MASK_1_3(p2) + INTERP_32_MASK_1_3(p3)) / 16)
161     | INTERP_32_MASK_SHIFTBACK_2_4((INTERP_32_MASK_SHIFT_2_4(p1)*14 + INTERP_32_MASK_SHIFT_2_4(p2) + INTERP_32_MASK_SHIFT_2_4(p3)) / 16);
162 }
163
164 /***************************************************************************/
165 /* diff */
166
167 #define INTERP_Y_LIMIT (0x30*4)
168 #define INTERP_U_LIMIT (0x07*4)
169 #define INTERP_V_LIMIT (0x06*8)
170
171 #if !_16BPP_HACK
172 static int hq2x_interp_16_diff(uint16 p1, uint16 p2)
173 {
174   int r, g, b;
175   int y, u, v;
176
177   if (p1 == p2)
178     return 0;
179
180   b = (int)((p1 & 0x000F) - (p2 & 0x000F));
181   g = (int)((p1 & 0x00F0) - (p2 & 0x00F0)) >> 4;
182   r = (int)((p1 & 0x0F00) - (p2 & 0x0F00)) >> 8;
183
184   y = r + g + b;
185   u = r - b;
186   v = -r + 2*g - b;
187
188   if (y < -INTERP_Y_LIMIT || y > INTERP_Y_LIMIT)
189     return 1;
190
191   if (u < -INTERP_U_LIMIT || u > INTERP_U_LIMIT)
192     return 1;
193
194   if (v < -INTERP_V_LIMIT || v > INTERP_V_LIMIT)
195     return 1;
196
197   return 0;
198 }
199 #endif /* !_16BPP_HACK */
200
201 static int hq2x_interp_32_diff(uint32 p1, uint32 p2)
202 {
203   int r, g, b;
204   int y, u, v;
205
206   if ((p1 & 0xF8F8F8) == (p2 & 0xF8F8F8))
207     return 0;
208
209   b = (int)((p1 & 0xFF) - (p2 & 0xFF));
210   g = (int)((p1 & 0xFF00) - (p2 & 0xFF00)) >> 8;
211   r = (int)((p1 & 0xFF0000) - (p2 & 0xFF0000)) >> 16;
212
213   y = r + g + b;
214   u = r - b;
215   v = -r + 2*g - b;
216
217   if (y < -INTERP_Y_LIMIT || y > INTERP_Y_LIMIT)
218     return 1;
219
220   if (u < -INTERP_U_LIMIT || u > INTERP_U_LIMIT)
221     return 1;
222
223   if (v < -INTERP_V_LIMIT || v > INTERP_V_LIMIT)
224     return 1;
225
226   return 0;
227 }
228
229 /*static void interp_set(unsigned bits_per_pixel)
230 {
231    interp_bits_per_pixel = bits_per_pixel;
232 }*/
233
234 #if !_16BPP_HACK
235 static void hq2x_16_def(uint16* dst0, uint16* dst1, const uint16* src0, const uint16* src1, const uint16* src2, unsigned count)
236 {
237   unsigned i;
238
239   for(i=0;i<count;++i) {
240     unsigned char mask;
241
242     uint16 c[9];
243
244     c[1] = src0[0];
245     c[4] = src1[0];
246     c[7] = src2[0];
247
248     if (i>0) {
249       c[0] = src0[-1];
250       c[3] = src1[-1];
251       c[6] = src2[-1];
252     } else {
253       c[0] = c[1];
254       c[3] = c[4];
255       c[6] = c[7];
256     }
257
258     if (i<count-1) {
259       c[2] = src0[1];
260       c[5] = src1[1];
261       c[8] = src2[1];
262     } else {
263       c[2] = c[1];
264       c[5] = c[4];
265       c[8] = c[7];
266     }
267
268     mask = 0;
269
270     if (hq2x_interp_16_diff(c[0], c[4]))
271       mask |= 1 << 0;
272     if (hq2x_interp_16_diff(c[1], c[4]))
273       mask |= 1 << 1;
274     if (hq2x_interp_16_diff(c[2], c[4]))
275       mask |= 1 << 2;
276     if (hq2x_interp_16_diff(c[3], c[4]))
277       mask |= 1 << 3;
278     if (hq2x_interp_16_diff(c[5], c[4]))
279       mask |= 1 << 4;
280     if (hq2x_interp_16_diff(c[6], c[4]))
281       mask |= 1 << 5;
282     if (hq2x_interp_16_diff(c[7], c[4]))
283       mask |= 1 << 6;
284     if (hq2x_interp_16_diff(c[8], c[4]))
285       mask |= 1 << 7;
286
287 #define P0 dst0[0]
288 #define P1 dst0[1]
289 #define P2 dst1[0]
290 #define P3 dst1[1]
291 #define HQ2X_MUR hq2x_interp_16_diff(c[1], c[5])
292 #define HQ2X_MDR hq2x_interp_16_diff(c[5], c[7])
293 #define HQ2X_MDL hq2x_interp_16_diff(c[7], c[3])
294 #define HQ2X_MUL hq2x_interp_16_diff(c[3], c[1])
295 #define IC(p0) c[p0]
296 #define I11(p0,p1) hq2x_interp_16_11(c[p0], c[p1])
297 #define I211(p0,p1,p2) hq2x_interp_16_211(c[p0], c[p1], c[p2])
298 #define I31(p0,p1) hq2x_interp_16_31(c[p0], c[p1])
299 #define I332(p0,p1,p2) hq2x_interp_16_332(c[p0], c[p1], c[p2])
300 #define I431(p0,p1,p2) hq2x_interp_16_431(c[p0], c[p1], c[p2])
301 #define I521(p0,p1,p2) hq2x_interp_16_521(c[p0], c[p1], c[p2])
302 #define I53(p0,p1) hq2x_interp_16_53(c[p0], c[p1])
303 #define I611(p0,p1,p2) hq2x_interp_16_611(c[p0], c[p1], c[p2])
304 #define I71(p0,p1) hq2x_interp_16_71(c[p0], c[p1])
305 #define I772(p0,p1,p2) hq2x_interp_16_772(c[p0], c[p1], c[p2])
306 #define I97(p0,p1) hq2x_interp_16_97(c[p0], c[p1])
307 #define I1411(p0,p1,p2) hq2x_interp_16_1411(c[p0], c[p1], c[p2])
308 #define I151(p0,p1) hq2x_interp_16_151(c[p0], c[p1])
309
310     switch (mask) {
311 #include "TextureFilters_hq2x.h"
312     }
313
314 #undef P0
315 #undef P1
316 #undef P2
317 #undef P3
318 #undef HQ2X_MUR
319 #undef HQ2X_MDR
320 #undef HQ2X_MDL
321 #undef HQ2X_MUL
322 #undef IC
323 #undef I11
324 #undef I211
325 #undef I31
326 #undef I332
327 #undef I431
328 #undef I521
329 #undef I53
330 #undef I611
331 #undef I71
332 #undef I772
333 #undef I97
334 #undef I1411
335 #undef I151
336
337     src0 += 1;
338     src1 += 1;
339     src2 += 1;
340     dst0 += 2;
341     dst1 += 2;
342   }
343 }
344
345 static void hq2xS_16_def(uint16* dst0, uint16* dst1, const uint16* src0, const uint16* src1, const uint16* src2, unsigned count)
346 {
347   unsigned i;
348
349   for(i=0;i<count;++i) {
350     unsigned char mask;
351
352     uint16 c[9];
353
354     c[1] = src0[0];
355     c[4] = src1[0];
356     c[7] = src2[0];
357
358     if (i>0) {
359       c[0] = src0[-1];
360       c[3] = src1[-1];
361       c[6] = src2[-1];
362     } else {
363       c[0] = c[1];
364       c[3] = c[4];
365       c[6] = c[7];
366     }
367
368     if (i<count-1) {
369       c[2] = src0[1];
370       c[5] = src1[1];
371       c[8] = src2[1];
372     } else {
373       c[2] = c[1];
374       c[5] = c[4];
375       c[8] = c[7];
376     }
377
378     mask = 0;
379
380     // hq2xS dynamic edge detection:
381     // simply comparing the center color against its surroundings will give bad results in many cases,
382     // so, instead, compare the center color relative to the max difference in brightness of this 3x3 block
383     int brightArray[9];
384     int maxBright = 0, minBright = 999999;
385     for(int j = 0 ; j < 9 ; j++) {
386       int r,g,b;
387       if (interp_bits_per_pixel == 16) {
388         b = (int)((c[j] & 0x1F)) << 3;
389         g = (int)((c[j] & 0x7E0)) >> 3;
390         r = (int)((c[j] & 0xF800)) >> 8;
391       } else {
392         b = (int)((c[j] & 0x1F)) << 3;
393         g = (int)((c[j] & 0x3E0)) >> 2;
394         r = (int)((c[j] & 0x7C00)) >> 7;
395       }
396       const int bright = r+r+r + g+g+g + b+b;
397       if(bright > maxBright) maxBright = bright;
398       if(bright < minBright) minBright = bright;
399
400       brightArray[j] = bright;
401     }
402     int diffBright = ((maxBright - minBright) * 7) >> 4;
403     if(diffBright > 7) {
404 #define ABS(x) ((x) < 0 ? -(x) : (x))
405
406       const int centerBright = brightArray[4];
407       if(ABS(brightArray[0] - centerBright) > diffBright)
408         mask |= 1 << 0;
409       if(ABS(brightArray[1] - centerBright) > diffBright)
410         mask |= 1 << 1;
411       if(ABS(brightArray[2] - centerBright) > diffBright)
412         mask |= 1 << 2;
413       if(ABS(brightArray[3] - centerBright) > diffBright)
414         mask |= 1 << 3;
415       if(ABS(brightArray[5] - centerBright) > diffBright)
416         mask |= 1 << 4;
417       if(ABS(brightArray[6] - centerBright) > diffBright)
418         mask |= 1 << 5;
419       if(ABS(brightArray[7] - centerBright) > diffBright)
420         mask |= 1 << 6;
421       if(ABS(brightArray[8] - centerBright) > diffBright)
422         mask |= 1 << 7;
423     }
424
425 #define P0 dst0[0]
426 #define P1 dst0[1]
427 #define P2 dst1[0]
428 #define P3 dst1[1]
429 #define HQ2X_MUR false
430 #define HQ2X_MDR false
431 #define HQ2X_MDL false
432 #define HQ2X_MUL false
433 #define IC(p0) c[p0]
434 #define I11(p0,p1) hq2x_interp_16_11(c[p0], c[p1])
435 #define I211(p0,p1,p2) hq2x_interp_16_211(c[p0], c[p1], c[p2])
436 #define I31(p0,p1) hq2x_interp_16_31(c[p0], c[p1])
437 #define I332(p0,p1,p2) hq2x_interp_16_332(c[p0], c[p1], c[p2])
438 #define I431(p0,p1,p2) hq2x_interp_16_431(c[p0], c[p1], c[p2])
439 #define I521(p0,p1,p2) hq2x_interp_16_521(c[p0], c[p1], c[p2])
440 #define I53(p0,p1) hq2x_interp_16_53(c[p0], c[p1])
441 #define I611(p0,p1,p2) hq2x_interp_16_611(c[p0], c[p1], c[p2])
442 #define I71(p0,p1) hq2x_interp_16_71(c[p0], c[p1])
443 #define I772(p0,p1,p2) hq2x_interp_16_772(c[p0], c[p1], c[p2])
444 #define I97(p0,p1) hq2x_interp_16_97(c[p0], c[p1])
445 #define I1411(p0,p1,p2) hq2x_interp_16_1411(c[p0], c[p1], c[p2])
446 #define I151(p0,p1) hq2x_interp_16_151(c[p0], c[p1])
447
448     switch (mask) {
449 #include "TextureFilters_hq2x.h"
450     }
451
452 #undef P0
453 #undef P1
454 #undef P2
455 #undef P3
456 #undef HQ2X_MUR
457 #undef HQ2X_MDR
458 #undef HQ2X_MDL
459 #undef HQ2X_MUL
460 #undef IC
461 #undef I11
462 #undef I211
463 #undef I31
464 #undef I332
465 #undef I431
466 #undef I521
467 #undef I53
468 #undef I611
469 #undef I71
470 #undef I772
471 #undef I97
472 #undef I1411
473 #undef I151
474
475     src0 += 1;
476     src1 += 1;
477     src2 += 1;
478     dst0 += 2;
479     dst1 += 2;
480   }
481 }
482 #endif /* !_16BPP_HACK */
483
484 static void hq2x_32_def(uint32* dst0, uint32* dst1, const uint32* src0, const uint32* src1, const uint32* src2, unsigned count)
485 {
486   unsigned i;
487
488   for(i=0;i<count;++i) {
489     unsigned char mask;
490
491     uint32 c[9];
492
493     c[1] = src0[0];
494     c[4] = src1[0];
495     c[7] = src2[0];
496
497     if (i>0) {
498       c[0] = src0[-1];
499       c[3] = src1[-1];
500       c[6] = src2[-1];
501     } else {
502       c[0] = src0[0];
503       c[3] = src1[0];
504       c[6] = src2[0];
505     }
506
507     if (i<count-1) {
508       c[2] = src0[1];
509       c[5] = src1[1];
510       c[8] = src2[1];
511     } else {
512       c[2] = src0[0];
513       c[5] = src1[0];
514       c[8] = src2[0];
515     }
516
517     mask = 0;
518
519     if (hq2x_interp_32_diff(c[0], c[4]))
520       mask |= 1 << 0;
521     if (hq2x_interp_32_diff(c[1], c[4]))
522       mask |= 1 << 1;
523     if (hq2x_interp_32_diff(c[2], c[4]))
524       mask |= 1 << 2;
525     if (hq2x_interp_32_diff(c[3], c[4]))
526       mask |= 1 << 3;
527     if (hq2x_interp_32_diff(c[5], c[4]))
528       mask |= 1 << 4;
529     if (hq2x_interp_32_diff(c[6], c[4]))
530       mask |= 1 << 5;
531     if (hq2x_interp_32_diff(c[7], c[4]))
532       mask |= 1 << 6;
533     if (hq2x_interp_32_diff(c[8], c[4]))
534       mask |= 1 << 7;
535
536 #define P0 dst0[0]
537 #define P1 dst0[1]
538 #define P2 dst1[0]
539 #define P3 dst1[1]
540 #define HQ2X_MUR hq2x_interp_32_diff(c[1], c[5])
541 #define HQ2X_MDR hq2x_interp_32_diff(c[5], c[7])
542 #define HQ2X_MDL hq2x_interp_32_diff(c[7], c[3])
543 #define HQ2X_MUL hq2x_interp_32_diff(c[3], c[1])
544 #define IC(p0) c[p0]
545 #define I211(p0,p1,p2) hq2x_interp_32_211(c[p0], c[p1], c[p2])
546 #define I31(p0,p1) hq2x_interp_32_31(c[p0], c[p1])
547 #define I332(p0,p1,p2) hq2x_interp_32_332(c[p0], c[p1], c[p2])
548 #define I521(p0,p1,p2) hq2x_interp_32_521(c[p0], c[p1], c[p2])
549 #define I611(p0,p1,p2) hq2x_interp_32_611(c[p0], c[p1], c[p2])
550 #define I1411(p0,p1,p2) hq2x_interp_32_1411(c[p0], c[p1], c[p2])
551
552     switch (mask) {
553 #include "TextureFilters_hq2x.h"
554     }
555
556 #undef P0
557 #undef P1
558 #undef P2
559 #undef P3
560 #undef HQ2X_MUR
561 #undef HQ2X_MDR
562 #undef HQ2X_MDL
563 #undef HQ2X_MUL
564 #undef IC
565 #undef I211
566 #undef I31
567 #undef I332
568 #undef I521
569 #undef I611
570 #undef I1411
571
572     src0 += 1;
573     src1 += 1;
574     src2 += 1;
575     dst0 += 2;
576     dst1 += 2;
577   }
578 }
579
580 static void hq2xS_32_def(uint32* dst0, uint32* dst1, const uint32* src0, const uint32* src1, const uint32* src2, unsigned count)
581 {
582   unsigned i;
583
584   for(i=0;i<count;++i) {
585     unsigned char mask;
586
587     uint32 c[9];
588
589     c[1] = src0[0];
590     c[4] = src1[0];
591     c[7] = src2[0];
592
593     if (i>0) {
594       c[0] = src0[-1];
595       c[3] = src1[-1];
596       c[6] = src2[-1];
597     } else {
598       c[0] = src0[0];
599       c[3] = src1[0];
600       c[6] = src2[0];
601     }
602
603     if (i<count-1) {
604       c[2] = src0[1];
605       c[5] = src1[1];
606       c[8] = src2[1];
607     } else {
608       c[2] = src0[0];
609       c[5] = src1[0];
610       c[8] = src2[0];
611     }
612     
613     mask = 0;
614     // hq2xS dynamic edge detection:
615     // simply comparing the center color against its surroundings will give bad results in many cases,
616     // so, instead, compare the center color relative to the max difference in brightness of this 3x3 block
617     int brightArray[9];
618     int maxBright = 0, minBright = 999999;
619     for(int j = 0 ; j < 9 ; j++) {
620       const int b = (int)((c[j] & 0xF8));
621       const int g = (int)((c[j] & 0xF800)) >> 8;
622       const int r = (int)((c[j] & 0xF80000)) >> 16;
623       const int bright = r+r+r + g+g+g + b+b;
624       if(bright > maxBright) maxBright = bright;
625       if(bright < minBright) minBright = bright;
626
627       brightArray[j] = bright;
628     }
629     int diffBright = ((maxBright - minBright) * 7) >> 4;
630     if(diffBright > 7) {
631 #define ABS(x) ((x) < 0 ? -(x) : (x))
632
633       const int centerBright = brightArray[4];
634       if(ABS(brightArray[0] - centerBright) > diffBright)
635         mask |= 1 << 0;
636       if(ABS(brightArray[1] - centerBright) > diffBright)
637         mask |= 1 << 1;
638       if(ABS(brightArray[2] - centerBright) > diffBright)
639         mask |= 1 << 2;
640       if(ABS(brightArray[3] - centerBright) > diffBright)
641         mask |= 1 << 3;
642       if(ABS(brightArray[5] - centerBright) > diffBright)
643         mask |= 1 << 4;
644       if(ABS(brightArray[6] - centerBright) > diffBright)
645         mask |= 1 << 5;
646       if(ABS(brightArray[7] - centerBright) > diffBright)
647         mask |= 1 << 6;
648       if(ABS(brightArray[8] - centerBright) > diffBright)
649         mask |= 1 << 7;
650     }
651 #define P0 dst0[0]
652 #define P1 dst0[1]
653 #define P2 dst1[0]
654 #define P3 dst1[1]
655 #define HQ2X_MUR false
656 #define HQ2X_MDR false
657 #define HQ2X_MDL false
658 #define HQ2X_MUL false
659 #define IC(p0) c[p0]
660 #define I211(p0,p1,p2) hq2x_interp_32_211(c[p0], c[p1], c[p2])
661 #define I31(p0,p1) hq2x_interp_32_31(c[p0], c[p1])
662 #define I332(p0,p1,p2) hq2x_interp_32_332(c[p0], c[p1], c[p2])
663 #define I521(p0,p1,p2) hq2x_interp_32_521(c[p0], c[p1], c[p2])
664 #define I611(p0,p1,p2) hq2x_interp_32_611(c[p0], c[p1], c[p2])
665 #define I1411(p0,p1,p2) hq2x_interp_32_1411(c[p0], c[p1], c[p2])
666
667     switch (mask) {
668 #include "TextureFilters_hq2x.h"
669     }
670
671 #undef P0
672 #undef P1
673 #undef P2
674 #undef P3
675 #undef HQ2X_MUR
676 #undef HQ2X_MDR
677 #undef HQ2X_MDL
678 #undef HQ2X_MUL
679 #undef IC
680 #undef I211
681 #undef I31
682 #undef I332
683 #undef I521
684 #undef I611
685 #undef I1411
686
687     src0 += 1;
688     src1 += 1;
689     src2 += 1;
690     dst0 += 2;
691     dst1 += 2;
692   }
693 }
694
695 /***************************************************************************/
696 /* LQ2x C implementation */
697
698 /*
699 * This effect is derived from the hq2x effect made by Maxim Stepin
700 */
701
702 #if !_16BPP_HACK
703 static void lq2x_16_def(uint16* dst0, uint16* dst1, const uint16* src0, const uint16* src1, const uint16* src2, unsigned count)
704 {
705   unsigned i;
706
707   for(i=0;i<count;++i) {
708     unsigned char mask;
709
710     uint16 c[9];
711
712     c[1] = src0[0];
713     c[4] = src1[0];
714     c[7] = src2[0];
715
716     if (i>0) {
717       c[0] = src0[-1];
718       c[3] = src1[-1];
719       c[6] = src2[-1];
720     } else {
721       c[0] = c[1];
722       c[3] = c[4];
723       c[6] = c[7];
724     }
725
726     if (i<count-1) {
727       c[2] = src0[1];
728       c[5] = src1[1];
729       c[8] = src2[1];
730     } else {
731       c[2] = c[1];
732       c[5] = c[4];
733       c[8] = c[7];
734     }
735
736     mask = 0;
737
738     if (c[0] != c[4])
739       mask |= 1 << 0;
740     if (c[1] != c[4])
741       mask |= 1 << 1;
742     if (c[2] != c[4])
743       mask |= 1 << 2;
744     if (c[3] != c[4])
745       mask |= 1 << 3;
746     if (c[5] != c[4])
747       mask |= 1 << 4;
748     if (c[6] != c[4])
749       mask |= 1 << 5;
750     if (c[7] != c[4])
751       mask |= 1 << 6;
752     if (c[8] != c[4])
753       mask |= 1 << 7;
754
755 #define P0 dst0[0]
756 #define P1 dst0[1]
757 #define P2 dst1[0]
758 #define P3 dst1[1]
759 #define HQ2X_MUR (c[1] != c[5])
760 #define HQ2X_MDR (c[5] != c[7])
761 #define HQ2X_MDL (c[7] != c[3])
762 #define HQ2X_MUL (c[3] != c[1])
763 #define IC(p0) c[p0]
764 #define I11(p0,p1) hq2x_interp_16_11(c[p0], c[p1])
765 #define I211(p0,p1,p2) hq2x_interp_16_211(c[p0], c[p1], c[p2])
766 #define I31(p0,p1) hq2x_interp_16_31(c[p0], c[p1])
767 #define I332(p0,p1,p2) hq2x_interp_16_332(c[p0], c[p1], c[p2])
768 #define I431(p0,p1,p2) hq2x_interp_16_431(c[p0], c[p1], c[p2])
769 #define I521(p0,p1,p2) hq2x_interp_16_521(c[p0], c[p1], c[p2])
770 #define I53(p0,p1) hq2x_interp_16_53(c[p0], c[p1])
771 #define I611(p0,p1,p2) hq2x_interp_16_611(c[p0], c[p1], c[p2])
772 #define I71(p0,p1) hq2x_interp_16_71(c[p0], c[p1])
773 #define I772(p0,p1,p2) hq2x_interp_16_772(c[p0], c[p1], c[p2])
774 #define I97(p0,p1) hq2x_interp_16_97(c[p0], c[p1])
775 #define I1411(p0,p1,p2) hq2x_interp_16_1411(c[p0], c[p1], c[p2])
776 #define I151(p0,p1) hq2x_interp_16_151(c[p0], c[p1])
777
778     switch (mask) {
779 #include "TextureFilters_lq2x.h"
780     }
781
782 #undef P0
783 #undef P1
784 #undef P2
785 #undef P3
786 #undef HQ2X_MUR
787 #undef HQ2X_MDR
788 #undef HQ2X_MDL
789 #undef HQ2X_MUL
790 #undef IC
791 #undef I11
792 #undef I211
793 #undef I31
794 #undef I332
795 #undef I431
796 #undef I521
797 #undef I53
798 #undef I611
799 #undef I71
800 #undef I772
801 #undef I97
802 #undef I1411
803 #undef I151
804
805     src0 += 1;
806     src1 += 1;
807     src2 += 1;
808     dst0 += 2;
809     dst1 += 2;
810   }
811 }
812
813 static void lq2xS_16_def(uint16* dst0, uint16* dst1, const uint16* src0, const uint16* src1, const uint16* src2, unsigned count)
814 {
815   unsigned i;
816
817   for(i=0;i<count;++i) {
818     unsigned char mask;
819
820     uint16 c[9];
821
822     c[1] = src0[0];
823     c[4] = src1[0];
824     c[7] = src2[0];
825
826     if (i>0) {
827       c[0] = src0[-1];
828       c[3] = src1[-1];
829       c[6] = src2[-1];
830     } else {
831       c[0] = c[1];
832       c[3] = c[4];
833       c[6] = c[7];
834     }
835
836     if (i<count-1) {
837       c[2] = src0[1];
838       c[5] = src1[1];
839       c[8] = src2[1];
840     } else {
841       c[2] = c[1];
842       c[5] = c[4];
843       c[8] = c[7];
844     }
845
846     // hq2xS dynamic edge detection:
847     // simply comparing the center color against its surroundings will give bad results in many cases,
848     // so, instead, compare the center color relative to the max difference in brightness of this 3x3 block
849     int brightArray[9];
850     int maxBright = 0, minBright = 999999;
851     for(int j = 0 ; j < 9 ; j++) {
852       const int b = (int)((c[j] & 0xF8));
853       const int g = (int)((c[j] & 0xF800)) >> 8;
854       const int r = (int)((c[j] & 0xF80000)) >> 16;
855       const int bright = r+r+r + g+g+g + b+b;
856       if(bright > maxBright) maxBright = bright;
857       if(bright < minBright) minBright = bright;
858
859       brightArray[j] = bright;
860     }
861     int diffBright = ((maxBright - minBright) * 7) >> 4;
862     if(diffBright > 7) {
863 #define ABS(x) ((x) < 0 ? -(x) : (x))
864
865       const int centerBright = brightArray[4];
866       if(ABS(brightArray[0] - centerBright) > diffBright)
867         mask |= 1 << 0;
868       if(ABS(brightArray[1] - centerBright) > diffBright)
869         mask |= 1 << 1;
870       if(ABS(brightArray[2] - centerBright) > diffBright)
871         mask |= 1 << 2;
872       if(ABS(brightArray[3] - centerBright) > diffBright)
873         mask |= 1 << 3;
874       if(ABS(brightArray[5] - centerBright) > diffBright)
875         mask |= 1 << 4;
876       if(ABS(brightArray[6] - centerBright) > diffBright)
877         mask |= 1 << 5;
878       if(ABS(brightArray[7] - centerBright) > diffBright)
879         mask |= 1 << 6;
880       if(ABS(brightArray[8] - centerBright) > diffBright)
881         mask |= 1 << 7;
882     }
883
884 #define P0 dst0[0]
885 #define P1 dst0[1]
886 #define P2 dst1[0]
887 #define P3 dst1[1]
888 #define HQ2X_MUR false
889 #define HQ2X_MDR false
890 #define HQ2X_MDL false
891 #define HQ2X_MUL false
892 #define IC(p0) c[p0]
893 #define I11(p0,p1) hq2x_interp_16_11(c[p0], c[p1])
894 #define I211(p0,p1,p2) hq2x_interp_16_211(c[p0], c[p1], c[p2])
895 #define I31(p0,p1) hq2x_interp_16_31(c[p0], c[p1])
896 #define I332(p0,p1,p2) hq2x_interp_16_332(c[p0], c[p1], c[p2])
897 #define I431(p0,p1,p2) hq2x_interp_16_431(c[p0], c[p1], c[p2])
898 #define I521(p0,p1,p2) hq2x_interp_16_521(c[p0], c[p1], c[p2])
899 #define I53(p0,p1) hq2x_interp_16_53(c[p0], c[p1])
900 #define I611(p0,p1,p2) hq2x_interp_16_611(c[p0], c[p1], c[p2])
901 #define I71(p0,p1) hq2x_interp_16_71(c[p0], c[p1])
902 #define I772(p0,p1,p2) hq2x_interp_16_772(c[p0], c[p1], c[p2])
903 #define I97(p0,p1) hq2x_interp_16_97(c[p0], c[p1])
904 #define I1411(p0,p1,p2) hq2x_interp_16_1411(c[p0], c[p1], c[p2])
905 #define I151(p0,p1) hq2x_interp_16_151(c[p0], c[p1])
906
907     switch (mask) {
908 #include "TextureFilters_lq2x.h"
909     }
910
911 #undef P0
912 #undef P1
913 #undef P2
914 #undef P3
915 #undef HQ2X_MUR
916 #undef HQ2X_MDR
917 #undef HQ2X_MDL
918 #undef HQ2X_MUL
919 #undef IC
920 #undef I11
921 #undef I211
922 #undef I31
923 #undef I332
924 #undef I431
925 #undef I521
926 #undef I53
927 #undef I611
928 #undef I71
929 #undef I772
930 #undef I97
931 #undef I1411
932 #undef I151
933
934     src0 += 1;
935     src1 += 1;
936     src2 += 1;
937     dst0 += 2;
938     dst1 += 2;
939   }
940 }
941 #endif /* !_16BPP_HACK */
942
943 static void lq2x_32_def(uint32* dst0, uint32* dst1, const uint32* src0, const uint32* src1, const uint32* src2, unsigned count)
944 {
945   unsigned i;
946
947   for(i=0;i<count;++i) {
948     unsigned char mask;
949
950     uint32 c[9];
951
952     c[1] = src0[0];
953     c[4] = src1[0];
954     c[7] = src2[0];
955
956     if (i>0) {
957       c[0] = src0[-1];
958       c[3] = src1[-1];
959       c[6] = src2[-1];
960     } else {
961       c[0] = c[1];
962       c[3] = c[4];
963       c[6] = c[7];
964     }
965
966     if (i<count-1) {
967       c[2] = src0[1];
968       c[5] = src1[1];
969       c[8] = src2[1];
970     } else {
971       c[2] = c[1];
972       c[5] = c[4];
973       c[8] = c[7];
974     }
975
976     mask = 0;
977
978     if (c[0] != c[4])
979       mask |= 1 << 0;
980     if (c[1] != c[4])
981       mask |= 1 << 1;
982     if (c[2] != c[4])
983       mask |= 1 << 2;
984     if (c[3] != c[4])
985       mask |= 1 << 3;
986     if (c[5] != c[4])
987       mask |= 1 << 4;
988     if (c[6] != c[4])
989       mask |= 1 << 5;
990     if (c[7] != c[4])
991       mask |= 1 << 6;
992     if (c[8] != c[4])
993       mask |= 1 << 7;
994
995 #define P0 dst0[0]
996 #define P1 dst0[1]
997 #define P2 dst1[0]
998 #define P3 dst1[1]
999 #define HQ2X_MUR (c[1] != c[5])
1000 #define HQ2X_MDR (c[5] != c[7])
1001 #define HQ2X_MDL (c[7] != c[3])
1002 #define HQ2X_MUL (c[3] != c[1])
1003 #define IC(p0) c[p0]
1004 #define I211(p0,p1,p2) hq2x_interp_32_211(c[p0], c[p1], c[p2])
1005 #define I31(p0,p1) hq2x_interp_32_31(c[p0], c[p1])
1006 #define I332(p0,p1,p2) hq2x_interp_32_332(c[p0], c[p1], c[p2])
1007 #define I521(p0,p1,p2) hq2x_interp_32_521(c[p0], c[p1], c[p2])
1008 #define I611(p0,p1,p2) hq2x_interp_32_611(c[p0], c[p1], c[p2])
1009 #define I1411(p0,p1,p2) hq2x_interp_32_1411(c[p0], c[p1], c[p2])
1010
1011     switch (mask) {
1012 #include "TextureFilters_lq2x.h"
1013     }
1014
1015 #undef P0
1016 #undef P1
1017 #undef P2
1018 #undef P3
1019 #undef HQ2X_MUR
1020 #undef HQ2X_MDR
1021 #undef HQ2X_MDL
1022 #undef HQ2X_MUL
1023 #undef IC
1024 #undef I211
1025 #undef I31
1026 #undef I332
1027 #undef I521
1028 #undef I611
1029 #undef I1411
1030
1031     src0 += 1;
1032     src1 += 1;
1033     src2 += 1;
1034     dst0 += 2;
1035     dst1 += 2;
1036   }
1037 }
1038
1039 static void lq2xS_32_def(uint32* dst0, uint32* dst1, const uint32* src0, const uint32* src1, const uint32* src2, unsigned count)
1040 {
1041   unsigned i;
1042
1043   for(i=0;i<count;++i) {
1044     unsigned char mask = 0;
1045
1046     uint32 c[9];
1047
1048     c[1] = src0[0];
1049     c[4] = src1[0];
1050     c[7] = src2[0];
1051
1052     if (i>0) {
1053       c[0] = src0[-1];
1054       c[3] = src1[-1];
1055       c[6] = src2[-1];
1056     } else {
1057       c[0] = c[1];
1058       c[3] = c[4];
1059       c[6] = c[7];
1060     }
1061
1062     if (i<count-1) {
1063       c[2] = src0[1];
1064       c[5] = src1[1];
1065       c[8] = src2[1];
1066     } else {
1067       c[2] = c[1];
1068       c[5] = c[4];
1069       c[8] = c[7];
1070     }
1071
1072     // hq2xS dynamic edge detection:
1073     // simply comparing the center color against its surroundings will give bad results in many cases,
1074     // so, instead, compare the center color relative to the max difference in brightness of this 3x3 block
1075     int brightArray[9];
1076     int maxBright = 0, minBright = 999999;
1077     for(int j = 0 ; j < 9 ; j++) {
1078       const int b = (int)((c[j] & 0xF8));
1079       const int g = (int)((c[j] & 0xF800)) >> 8;
1080       const int r = (int)((c[j] & 0xF80000)) >> 16;
1081       const int bright = r+r+r + g+g+g + b+b;
1082       if(bright > maxBright) maxBright = bright;
1083       if(bright < minBright) minBright = bright;
1084
1085       brightArray[j] = bright;
1086     }
1087     int diffBright = ((maxBright - minBright) * 7) >> 4;
1088     if(diffBright > 7) {
1089 #define ABS(x) ((x) < 0 ? -(x) : (x))
1090
1091       const int centerBright = brightArray[4];
1092       if(ABS(brightArray[0] - centerBright) > diffBright)
1093         mask |= 1 << 0;
1094       if(ABS(brightArray[1] - centerBright) > diffBright)
1095         mask |= 1 << 1;
1096       if(ABS(brightArray[2] - centerBright) > diffBright)
1097         mask |= 1 << 2;
1098       if(ABS(brightArray[3] - centerBright) > diffBright)
1099         mask |= 1 << 3;
1100       if(ABS(brightArray[5] - centerBright) > diffBright)
1101         mask |= 1 << 4;
1102       if(ABS(brightArray[6] - centerBright) > diffBright)
1103         mask |= 1 << 5;
1104       if(ABS(brightArray[7] - centerBright) > diffBright)
1105         mask |= 1 << 6;
1106       if(ABS(brightArray[8] - centerBright) > diffBright)
1107         mask |= 1 << 7;
1108     }
1109
1110 #define P0 dst0[0]
1111 #define P1 dst0[1]
1112 #define P2 dst1[0]
1113 #define P3 dst1[1]
1114 #define HQ2X_MUR false
1115 #define HQ2X_MDR false
1116 #define HQ2X_MDL false
1117 #define HQ2X_MUL false
1118 #define IC(p0) c[p0]
1119 #define I211(p0,p1,p2) hq2x_interp_32_211(c[p0], c[p1], c[p2])
1120 #define I31(p0,p1) hq2x_interp_32_31(c[p0], c[p1])
1121 #define I332(p0,p1,p2) hq2x_interp_32_332(c[p0], c[p1], c[p2])
1122 #define I521(p0,p1,p2) hq2x_interp_32_521(c[p0], c[p1], c[p2])
1123 #define I611(p0,p1,p2) hq2x_interp_32_611(c[p0], c[p1], c[p2])
1124 #define I1411(p0,p1,p2) hq2x_interp_32_1411(c[p0], c[p1], c[p2])
1125
1126     switch (mask) {
1127 #include "TextureFilters_lq2x.h"
1128     }
1129
1130 #undef P0
1131 #undef P1
1132 #undef P2
1133 #undef P3
1134 #undef HQ2X_MUR
1135 #undef HQ2X_MDR
1136 #undef HQ2X_MDL
1137 #undef HQ2X_MUL
1138 #undef IC
1139 #undef I211
1140 #undef I31
1141 #undef I332
1142 #undef I521
1143 #undef I611
1144 #undef I1411
1145
1146     src0 += 1;
1147     src1 += 1;
1148     src2 += 1;
1149     dst0 += 2;
1150     dst1 += 2;
1151   }
1152 }
1153
1154 #if !_16BPP_HACK
1155 void hq2x_16(uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height)
1156 {
1157   uint16 *dst0 = (uint16 *)dstPtr;
1158   uint16 *dst1 = dst0 + (dstPitch >> 1);
1159
1160   uint16 *src0 = (uint16 *)srcPtr;
1161   uint16 *src1 = src0 + (srcPitch >> 1);
1162   uint16 *src2 = src1 + (srcPitch >> 1);
1163
1164   int count;
1165
1166   hq2x_16_def(dst0, dst1, src0, src0, src1, width);
1167   if( height == 1 ) return;
1168
1169   count = height;
1170
1171   count -= 2;
1172   while(count>0) {
1173     dst0 += dstPitch;
1174     dst1 += dstPitch;
1175     hq2x_16_def(dst0, dst1, src0, src1, src2, width);
1176     src0 = src1;
1177     src1 = src2;
1178     src2 += srcPitch >> 1;
1179     --count;
1180   }
1181   dst0 += dstPitch;
1182   dst1 += dstPitch;
1183   hq2x_16_def(dst0, dst1, src0, src1, src1, width);
1184 }
1185
1186
1187 void hq2xS_16(u8 *srcPtr, u32 srcPitch, u8 * /* deltaPtr */,
1188               u8 *dstPtr, u32 dstPitch, int width, int height)
1189 {
1190   u16 *dst0 = (u16 *)dstPtr;
1191   u16 *dst1 = dst0 + (dstPitch >> 1);
1192   
1193   u16 *src0 = (u16 *)srcPtr;
1194   u16 *src1 = src0 + (srcPitch >> 1);
1195   u16 *src2 = src1 + (srcPitch >> 1);
1196   
1197   hq2xS_16_def(dst0, dst1, src0, src0, src1, width);
1198   
1199   int count = height;
1200   
1201   count -= 2;
1202   while(count) {
1203     dst0 += dstPitch;
1204     dst1 += dstPitch;
1205     hq2xS_16_def(dst0, dst1, src0, src1, src2, width);
1206     src0 = src1;
1207     src1 = src2;
1208     src2 += srcPitch >> 1;
1209     --count;
1210   }
1211   dst0 += dstPitch;
1212   dst1 += dstPitch;
1213   hq2xS_16_def(dst0, dst1, src0, src1, src1, width);
1214 }
1215 #endif /* !_16BPP_HACK */
1216
1217 void hq2x_32(uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height)
1218 {
1219   uint32 *dst0 = (uint32 *)dstPtr;
1220   uint32 *dst1 = dst0 + (dstPitch >> 2);
1221
1222   uint32 *src0 = (uint32 *)srcPtr;
1223   uint32 *src1 = src0 + (srcPitch >> 2);
1224   uint32 *src2 = src1 + (srcPitch >> 2);
1225
1226   int count;
1227
1228   hq2x_32_def(dst0, dst1, src0, src0, src1, width);
1229   if( height == 1 ) return;
1230
1231   count = height;
1232
1233   count -= 2;
1234   while(count>0) {
1235     dst0 += dstPitch >> 1;
1236     dst1 += dstPitch >> 1;
1237     hq2x_32_def(dst0, dst1, src0, src1, src2, width);
1238     src0 = src1;
1239     src1 = src2;
1240     src2 += srcPitch >> 2;
1241     --count;
1242   }
1243   dst0 += dstPitch >> 1;
1244   dst1 += dstPitch >> 1;
1245   hq2x_32_def(dst0, dst1, src0, src1, src1, width);
1246 }
1247
1248 void hq2xS_32(uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height)
1249 {
1250   uint32 *dst0 = (uint32 *)dstPtr;
1251   uint32 *dst1 = dst0 + (dstPitch >> 2);
1252
1253   uint32 *src0 = (uint32 *)srcPtr;
1254   uint32 *src1 = src0 + (srcPitch >> 2);
1255   uint32 *src2 = src1 + (srcPitch >> 2);
1256   hq2xS_32_def(dst0, dst1, src0, src0, src1, width);
1257   
1258   int count = height;
1259   
1260   count -= 2;
1261   while(count) {
1262     dst0 += dstPitch >> 1;
1263     dst1 += dstPitch >> 1;
1264     hq2xS_32_def(dst0, dst1, src0, src1, src2, width);
1265     src0 = src1;
1266     src1 = src2;
1267     src2 += srcPitch >> 2;
1268     --count;
1269   }
1270   dst0 += dstPitch >> 1;
1271   dst1 += dstPitch >> 1;
1272   hq2xS_32_def(dst0, dst1, src0, src1, src1, width);
1273 }
1274
1275 #if !_16BPP_HACK
1276 void lq2x_16(uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height)
1277 {
1278   uint16 *dst0 = (uint16 *)dstPtr;
1279   uint16 *dst1 = dst0 + (dstPitch >> 1);
1280
1281   uint16 *src0 = (uint16 *)srcPtr;
1282   uint16 *src1 = src0 + (srcPitch >> 1);
1283   uint16 *src2 = src1 + (srcPitch >> 1);
1284
1285   int count;
1286
1287   lq2x_16_def(dst0, dst1, src0, src0, src1, width);
1288   if( height == 1 ) return;
1289
1290   count = height;
1291
1292   count -= 2;
1293   while(count>0) {
1294     dst0 += dstPitch;
1295     dst1 += dstPitch;
1296     hq2x_16_def(dst0, dst1, src0, src1, src2, width);
1297     src0 = src1;
1298     src1 = src2;
1299     src2 += srcPitch >> 1;
1300     --count;
1301   }
1302   dst0 += dstPitch;
1303   dst1 += dstPitch;
1304   lq2x_16_def(dst0, dst1, src0, src1, src1, width);
1305 }
1306
1307 void lq2xS_16(uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height)
1308 {
1309   uint16 *dst0 = (uint16 *)dstPtr;
1310   uint16 *dst1 = dst0 + (dstPitch >> 1);
1311
1312   uint16 *src0 = (uint16 *)srcPtr;
1313   uint16 *src1 = src0 + (srcPitch >> 1);
1314   uint16 *src2 = src1 + (srcPitch >> 1);
1315
1316   int count;
1317
1318   lq2xS_16_def(dst0, dst1, src0, src0, src1, width);
1319   if( height == 1 ) return;
1320
1321   count = height;
1322
1323   count -= 2;
1324   while(count>0) {
1325     dst0 += dstPitch;
1326     dst1 += dstPitch;
1327     hq2x_16_def(dst0, dst1, src0, src1, src2, width);
1328     src0 = src1;
1329     src1 = src2;
1330     src2 += srcPitch >> 1;
1331     --count;
1332   }
1333   dst0 += dstPitch;
1334   dst1 += dstPitch;
1335   lq2xS_16_def(dst0, dst1, src0, src1, src1, width);
1336 }
1337 #endif /* !_16BPP_HACK */
1338
1339 void lq2x_32(uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height)
1340 {
1341   uint32 *dst0 = (uint32 *)dstPtr;
1342   uint32 *dst1 = dst0 + (dstPitch >> 2);
1343
1344   uint32 *src0 = (uint32 *)srcPtr;
1345   uint32 *src1 = src0 + (srcPitch >> 2);
1346   uint32 *src2 = src1 + (srcPitch >> 2);
1347
1348   int count;
1349
1350   lq2x_32_def(dst0, dst1, src0, src0, src1, width);
1351   if( height == 1 ) return;
1352
1353   count = height;
1354
1355   count -= 2;
1356   while(count>0) {
1357     dst0 += dstPitch >> 1;
1358     dst1 += dstPitch >> 1;
1359     hq2x_32_def(dst0, dst1, src0, src1, src2, width);
1360     src0 = src1;
1361     src1 = src2;
1362     src2 += srcPitch >> 2;
1363     --count;
1364   }
1365   dst0 += dstPitch >> 1;
1366   dst1 += dstPitch >> 1;
1367   lq2x_32_def(dst0, dst1, src0, src1, src1, width);
1368 }
1369
1370 void lq2xS_32(uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height)
1371 {
1372   uint32 *dst0 = (uint32 *)dstPtr;
1373   uint32 *dst1 = dst0 + (dstPitch >> 2);
1374
1375   uint32 *src0 = (uint32 *)srcPtr;
1376   uint32 *src1 = src0 + (srcPitch >> 2);
1377   uint32 *src2 = src1 + (srcPitch >> 2);
1378
1379   int count;
1380
1381   lq2xS_32_def(dst0, dst1, src0, src0, src1, width);
1382   if( height == 1 ) return;
1383
1384   count = height;
1385
1386   count -= 2;
1387   while(count>0) {
1388     dst0 += dstPitch >> 1;
1389     dst1 += dstPitch >> 1;
1390     hq2x_32_def(dst0, dst1, src0, src1, src2, width);
1391     src0 = src1;
1392     src1 = src2;
1393     src2 += srcPitch >> 2;
1394     --count;
1395   }
1396   dst0 += dstPitch >> 1;
1397   dst1 += dstPitch >> 1;
1398   lq2xS_32_def(dst0, dst1, src0, src1, src1, width);
1399 }
1400
1401 /************************************************************************/
1402 /* hq3x filters                                                         */
1403 /************************************************************************/
1404
1405 /************************************************************************/
1406 /* scale2x filters                                                      */
1407 /************************************************************************/
1408
1409 /************************************************************************/
1410 /* scale3x filters                                                      */
1411 /************************************************************************/
1412