Glide Plugin GLES2 port from mupen64plus-ae, but with special FrameSkip code
[mupen64plus-pandora.git] / source / gles2glide64 / src / GlideHQ / TextureFilters_hq2x.cpp
CommitLineData
98e75f2d 1/*
2Copyright (C) 2003 Rice1964
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program; if not, write to the Free Software
16Foundation, 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
45static 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
51static 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
57static 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
63static 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
69static 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
75static 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
81static 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
87static 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
93static 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
99static 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
105static 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
111static 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
117static 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
128static 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
134static 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
140static 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
146static 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
152static 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
158static 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
172static 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
201static 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
235static 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
345static 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
484static 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
580static 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
703static 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
813static 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
943static 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
1039static 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
1155void 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
1187void 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
1217void 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
1248void 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
1276void 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
1307void 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
1339void 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
1370void 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