2 Copyright (C) 2003 Rice1964
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.
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.
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.
20 /* Copyright (C) 2007 Hiroshi Morii <koolsmoky(at)users.sourceforge.net>
21 * Modified for the Texture Filtering library
24 /* 2007 Mudlord - Added hq2xS lq2xS filters */
26 #include "TextureFilters.h"
28 /************************************************************************/
30 /************************************************************************/
32 /***************************************************************************/
35 /***************************************************************************/
38 //static unsigned interp_bits_per_pixel;
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)
45 static uint16 hq2x_interp_16_521(uint16 p1, uint16 p2, uint16 p3)
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);
51 static uint16 hq2x_interp_16_332(uint16 p1, uint16 p2, uint16 p3)
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);
57 static uint16 hq2x_interp_16_611(uint16 p1, uint16 p2, uint16 p3)
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);
63 static uint16 hq2x_interp_16_71(uint16 p1, uint16 p2)
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);
69 static uint16 hq2x_interp_16_211(uint16 p1, uint16 p2, uint16 p3)
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);
75 static uint16 hq2x_interp_16_772(uint16 p1, uint16 p2, uint16 p3)
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);
81 static uint16 hq2x_interp_16_11(uint16 p1, uint16 p2)
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);
87 static uint16 hq2x_interp_16_31(uint16 p1, uint16 p2)
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);
93 static uint16 hq2x_interp_16_1411(uint16 p1, uint16 p2, uint16 p3)
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);
99 static uint16 hq2x_interp_16_431(uint16 p1, uint16 p2, uint16 p3)
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);
105 static uint16 hq2x_interp_16_53(uint16 p1, uint16 p2)
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);
111 static uint16 hq2x_interp_16_151(uint16 p1, uint16 p2)
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);
117 static uint16 hq2x_interp_16_97(uint16 p1, uint16 p2)
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);
122 #endif /* !_16BPP_HACK */
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))
128 static uint32 hq2x_interp_32_521(uint32 p1, uint32 p2, uint32 p3)
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);
134 static uint32 hq2x_interp_32_332(uint32 p1, uint32 p2, uint32 p3)
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);
140 static uint32 hq2x_interp_32_211(uint32 p1, uint32 p2, uint32 p3)
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);
146 static uint32 hq2x_interp_32_611(uint32 p1, uint32 p2, uint32 p3)
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);
152 static uint32 hq2x_interp_32_31(uint32 p1, uint32 p2)
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);
158 static uint32 hq2x_interp_32_1411(uint32 p1, uint32 p2, uint32 p3)
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);
164 /***************************************************************************/
167 #define INTERP_Y_LIMIT (0x30*4)
168 #define INTERP_U_LIMIT (0x07*4)
169 #define INTERP_V_LIMIT (0x06*8)
172 static int hq2x_interp_16_diff(uint16 p1, uint16 p2)
180 b = (int)((p1 & 0x000F) - (p2 & 0x000F));
181 g = (int)((p1 & 0x00F0) - (p2 & 0x00F0)) >> 4;
182 r = (int)((p1 & 0x0F00) - (p2 & 0x0F00)) >> 8;
188 if (y < -INTERP_Y_LIMIT || y > INTERP_Y_LIMIT)
191 if (u < -INTERP_U_LIMIT || u > INTERP_U_LIMIT)
194 if (v < -INTERP_V_LIMIT || v > INTERP_V_LIMIT)
199 #endif /* !_16BPP_HACK */
201 static int hq2x_interp_32_diff(uint32 p1, uint32 p2)
206 if ((p1 & 0xF8F8F8) == (p2 & 0xF8F8F8))
209 b = (int)((p1 & 0xFF) - (p2 & 0xFF));
210 g = (int)((p1 & 0xFF00) - (p2 & 0xFF00)) >> 8;
211 r = (int)((p1 & 0xFF0000) - (p2 & 0xFF0000)) >> 16;
217 if (y < -INTERP_Y_LIMIT || y > INTERP_Y_LIMIT)
220 if (u < -INTERP_U_LIMIT || u > INTERP_U_LIMIT)
223 if (v < -INTERP_V_LIMIT || v > INTERP_V_LIMIT)
229 /*static void interp_set(unsigned bits_per_pixel)
231 interp_bits_per_pixel = bits_per_pixel;
235 static void hq2x_16_def(uint16* dst0, uint16* dst1, const uint16* src0, const uint16* src1, const uint16* src2, unsigned count)
239 for(i=0;i<count;++i) {
270 if (hq2x_interp_16_diff(c[0], c[4]))
272 if (hq2x_interp_16_diff(c[1], c[4]))
274 if (hq2x_interp_16_diff(c[2], c[4]))
276 if (hq2x_interp_16_diff(c[3], c[4]))
278 if (hq2x_interp_16_diff(c[5], c[4]))
280 if (hq2x_interp_16_diff(c[6], c[4]))
282 if (hq2x_interp_16_diff(c[7], c[4]))
284 if (hq2x_interp_16_diff(c[8], c[4]))
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])
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])
311 #include "TextureFilters_hq2x.h"
345 static void hq2xS_16_def(uint16* dst0, uint16* dst1, const uint16* src0, const uint16* src1, const uint16* src2, unsigned count)
349 for(i=0;i<count;++i) {
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
384 int maxBright = 0, minBright = 999999;
385 for(int j = 0 ; j < 9 ; j++) {
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;
392 b = (int)((c[j] & 0x1F)) << 3;
393 g = (int)((c[j] & 0x3E0)) >> 2;
394 r = (int)((c[j] & 0x7C00)) >> 7;
396 const int bright = r+r+r + g+g+g + b+b;
397 if(bright > maxBright) maxBright = bright;
398 if(bright < minBright) minBright = bright;
400 brightArray[j] = bright;
402 int diffBright = ((maxBright - minBright) * 7) >> 4;
404 #define ABS(x) ((x) < 0 ? -(x) : (x))
406 const int centerBright = brightArray[4];
407 if(ABS(brightArray[0] - centerBright) > diffBright)
409 if(ABS(brightArray[1] - centerBright) > diffBright)
411 if(ABS(brightArray[2] - centerBright) > diffBright)
413 if(ABS(brightArray[3] - centerBright) > diffBright)
415 if(ABS(brightArray[5] - centerBright) > diffBright)
417 if(ABS(brightArray[6] - centerBright) > diffBright)
419 if(ABS(brightArray[7] - centerBright) > diffBright)
421 if(ABS(brightArray[8] - centerBright) > diffBright)
429 #define HQ2X_MUR false
430 #define HQ2X_MDR false
431 #define HQ2X_MDL false
432 #define HQ2X_MUL false
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])
449 #include "TextureFilters_hq2x.h"
482 #endif /* !_16BPP_HACK */
484 static void hq2x_32_def(uint32* dst0, uint32* dst1, const uint32* src0, const uint32* src1, const uint32* src2, unsigned count)
488 for(i=0;i<count;++i) {
519 if (hq2x_interp_32_diff(c[0], c[4]))
521 if (hq2x_interp_32_diff(c[1], c[4]))
523 if (hq2x_interp_32_diff(c[2], c[4]))
525 if (hq2x_interp_32_diff(c[3], c[4]))
527 if (hq2x_interp_32_diff(c[5], c[4]))
529 if (hq2x_interp_32_diff(c[6], c[4]))
531 if (hq2x_interp_32_diff(c[7], c[4]))
533 if (hq2x_interp_32_diff(c[8], c[4]))
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])
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])
553 #include "TextureFilters_hq2x.h"
580 static void hq2xS_32_def(uint32* dst0, uint32* dst1, const uint32* src0, const uint32* src1, const uint32* src2, unsigned count)
584 for(i=0;i<count;++i) {
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
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;
627 brightArray[j] = bright;
629 int diffBright = ((maxBright - minBright) * 7) >> 4;
631 #define ABS(x) ((x) < 0 ? -(x) : (x))
633 const int centerBright = brightArray[4];
634 if(ABS(brightArray[0] - centerBright) > diffBright)
636 if(ABS(brightArray[1] - centerBright) > diffBright)
638 if(ABS(brightArray[2] - centerBright) > diffBright)
640 if(ABS(brightArray[3] - centerBright) > diffBright)
642 if(ABS(brightArray[5] - centerBright) > diffBright)
644 if(ABS(brightArray[6] - centerBright) > diffBright)
646 if(ABS(brightArray[7] - centerBright) > diffBright)
648 if(ABS(brightArray[8] - centerBright) > diffBright)
655 #define HQ2X_MUR false
656 #define HQ2X_MDR false
657 #define HQ2X_MDL false
658 #define HQ2X_MUL false
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])
668 #include "TextureFilters_hq2x.h"
695 /***************************************************************************/
696 /* LQ2x C implementation */
699 * This effect is derived from the hq2x effect made by Maxim Stepin
703 static void lq2x_16_def(uint16* dst0, uint16* dst1, const uint16* src0, const uint16* src1, const uint16* src2, unsigned count)
707 for(i=0;i<count;++i) {
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])
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])
779 #include "TextureFilters_lq2x.h"
813 static void lq2xS_16_def(uint16* dst0, uint16* dst1, const uint16* src0, const uint16* src1, const uint16* src2, unsigned count)
817 for(i=0;i<count;++i) {
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
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;
859 brightArray[j] = bright;
861 int diffBright = ((maxBright - minBright) * 7) >> 4;
863 #define ABS(x) ((x) < 0 ? -(x) : (x))
865 const int centerBright = brightArray[4];
866 if(ABS(brightArray[0] - centerBright) > diffBright)
868 if(ABS(brightArray[1] - centerBright) > diffBright)
870 if(ABS(brightArray[2] - centerBright) > diffBright)
872 if(ABS(brightArray[3] - centerBright) > diffBright)
874 if(ABS(brightArray[5] - centerBright) > diffBright)
876 if(ABS(brightArray[6] - centerBright) > diffBright)
878 if(ABS(brightArray[7] - centerBright) > diffBright)
880 if(ABS(brightArray[8] - centerBright) > diffBright)
888 #define HQ2X_MUR false
889 #define HQ2X_MDR false
890 #define HQ2X_MDL false
891 #define HQ2X_MUL false
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])
908 #include "TextureFilters_lq2x.h"
941 #endif /* !_16BPP_HACK */
943 static void lq2x_32_def(uint32* dst0, uint32* dst1, const uint32* src0, const uint32* src1, const uint32* src2, unsigned count)
947 for(i=0;i<count;++i) {
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])
1012 #include "TextureFilters_lq2x.h"
1039 static void lq2xS_32_def(uint32* dst0, uint32* dst1, const uint32* src0, const uint32* src1, const uint32* src2, unsigned count)
1043 for(i=0;i<count;++i) {
1044 unsigned char mask = 0;
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
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;
1085 brightArray[j] = bright;
1087 int diffBright = ((maxBright - minBright) * 7) >> 4;
1088 if(diffBright > 7) {
1089 #define ABS(x) ((x) < 0 ? -(x) : (x))
1091 const int centerBright = brightArray[4];
1092 if(ABS(brightArray[0] - centerBright) > diffBright)
1094 if(ABS(brightArray[1] - centerBright) > diffBright)
1096 if(ABS(brightArray[2] - centerBright) > diffBright)
1098 if(ABS(brightArray[3] - centerBright) > diffBright)
1100 if(ABS(brightArray[5] - centerBright) > diffBright)
1102 if(ABS(brightArray[6] - centerBright) > diffBright)
1104 if(ABS(brightArray[7] - centerBright) > diffBright)
1106 if(ABS(brightArray[8] - centerBright) > diffBright)
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])
1127 #include "TextureFilters_lq2x.h"
1155 void hq2x_16(uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height)
1157 uint16 *dst0 = (uint16 *)dstPtr;
1158 uint16 *dst1 = dst0 + (dstPitch >> 1);
1160 uint16 *src0 = (uint16 *)srcPtr;
1161 uint16 *src1 = src0 + (srcPitch >> 1);
1162 uint16 *src2 = src1 + (srcPitch >> 1);
1166 hq2x_16_def(dst0, dst1, src0, src0, src1, width);
1167 if( height == 1 ) return;
1175 hq2x_16_def(dst0, dst1, src0, src1, src2, width);
1178 src2 += srcPitch >> 1;
1183 hq2x_16_def(dst0, dst1, src0, src1, src1, width);
1187 void hq2xS_16(u8 *srcPtr, u32 srcPitch, u8 * /* deltaPtr */,
1188 u8 *dstPtr, u32 dstPitch, int width, int height)
1190 u16 *dst0 = (u16 *)dstPtr;
1191 u16 *dst1 = dst0 + (dstPitch >> 1);
1193 u16 *src0 = (u16 *)srcPtr;
1194 u16 *src1 = src0 + (srcPitch >> 1);
1195 u16 *src2 = src1 + (srcPitch >> 1);
1197 hq2xS_16_def(dst0, dst1, src0, src0, src1, width);
1205 hq2xS_16_def(dst0, dst1, src0, src1, src2, width);
1208 src2 += srcPitch >> 1;
1213 hq2xS_16_def(dst0, dst1, src0, src1, src1, width);
1215 #endif /* !_16BPP_HACK */
1217 void hq2x_32(uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height)
1219 uint32 *dst0 = (uint32 *)dstPtr;
1220 uint32 *dst1 = dst0 + (dstPitch >> 2);
1222 uint32 *src0 = (uint32 *)srcPtr;
1223 uint32 *src1 = src0 + (srcPitch >> 2);
1224 uint32 *src2 = src1 + (srcPitch >> 2);
1228 hq2x_32_def(dst0, dst1, src0, src0, src1, width);
1229 if( height == 1 ) return;
1235 dst0 += dstPitch >> 1;
1236 dst1 += dstPitch >> 1;
1237 hq2x_32_def(dst0, dst1, src0, src1, src2, width);
1240 src2 += srcPitch >> 2;
1243 dst0 += dstPitch >> 1;
1244 dst1 += dstPitch >> 1;
1245 hq2x_32_def(dst0, dst1, src0, src1, src1, width);
1248 void hq2xS_32(uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height)
1250 uint32 *dst0 = (uint32 *)dstPtr;
1251 uint32 *dst1 = dst0 + (dstPitch >> 2);
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);
1262 dst0 += dstPitch >> 1;
1263 dst1 += dstPitch >> 1;
1264 hq2xS_32_def(dst0, dst1, src0, src1, src2, width);
1267 src2 += srcPitch >> 2;
1270 dst0 += dstPitch >> 1;
1271 dst1 += dstPitch >> 1;
1272 hq2xS_32_def(dst0, dst1, src0, src1, src1, width);
1276 void lq2x_16(uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height)
1278 uint16 *dst0 = (uint16 *)dstPtr;
1279 uint16 *dst1 = dst0 + (dstPitch >> 1);
1281 uint16 *src0 = (uint16 *)srcPtr;
1282 uint16 *src1 = src0 + (srcPitch >> 1);
1283 uint16 *src2 = src1 + (srcPitch >> 1);
1287 lq2x_16_def(dst0, dst1, src0, src0, src1, width);
1288 if( height == 1 ) return;
1296 hq2x_16_def(dst0, dst1, src0, src1, src2, width);
1299 src2 += srcPitch >> 1;
1304 lq2x_16_def(dst0, dst1, src0, src1, src1, width);
1307 void lq2xS_16(uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height)
1309 uint16 *dst0 = (uint16 *)dstPtr;
1310 uint16 *dst1 = dst0 + (dstPitch >> 1);
1312 uint16 *src0 = (uint16 *)srcPtr;
1313 uint16 *src1 = src0 + (srcPitch >> 1);
1314 uint16 *src2 = src1 + (srcPitch >> 1);
1318 lq2xS_16_def(dst0, dst1, src0, src0, src1, width);
1319 if( height == 1 ) return;
1327 hq2x_16_def(dst0, dst1, src0, src1, src2, width);
1330 src2 += srcPitch >> 1;
1335 lq2xS_16_def(dst0, dst1, src0, src1, src1, width);
1337 #endif /* !_16BPP_HACK */
1339 void lq2x_32(uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height)
1341 uint32 *dst0 = (uint32 *)dstPtr;
1342 uint32 *dst1 = dst0 + (dstPitch >> 2);
1344 uint32 *src0 = (uint32 *)srcPtr;
1345 uint32 *src1 = src0 + (srcPitch >> 2);
1346 uint32 *src2 = src1 + (srcPitch >> 2);
1350 lq2x_32_def(dst0, dst1, src0, src0, src1, width);
1351 if( height == 1 ) return;
1357 dst0 += dstPitch >> 1;
1358 dst1 += dstPitch >> 1;
1359 hq2x_32_def(dst0, dst1, src0, src1, src2, width);
1362 src2 += srcPitch >> 2;
1365 dst0 += dstPitch >> 1;
1366 dst1 += dstPitch >> 1;
1367 lq2x_32_def(dst0, dst1, src0, src1, src1, width);
1370 void lq2xS_32(uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height)
1372 uint32 *dst0 = (uint32 *)dstPtr;
1373 uint32 *dst1 = dst0 + (dstPitch >> 2);
1375 uint32 *src0 = (uint32 *)srcPtr;
1376 uint32 *src1 = src0 + (srcPitch >> 2);
1377 uint32 *src2 = src1 + (srcPitch >> 2);
1381 lq2xS_32_def(dst0, dst1, src0, src0, src1, width);
1382 if( height == 1 ) return;
1388 dst0 += dstPitch >> 1;
1389 dst1 += dstPitch >> 1;
1390 hq2x_32_def(dst0, dst1, src0, src1, src2, width);
1393 src2 += srcPitch >> 2;
1396 dst0 += dstPitch >> 1;
1397 dst1 += dstPitch >> 1;
1398 lq2xS_32_def(dst0, dst1, src0, src1, src1, width);
1401 /************************************************************************/
1403 /************************************************************************/
1405 /************************************************************************/
1406 /* scale2x filters */
1407 /************************************************************************/
1409 /************************************************************************/
1410 /* scale3x filters */
1411 /************************************************************************/