view src/filters/hq2x.cpp @ 311:8fa0f36140b4

began writing out my notes on the ROM in an org file.
author Dylan Holmes <ocsenave@gmail.com>
date Sun, 01 Apr 2012 03:20:33 -0500
parents f9f4f1b99eed
children
line wrap: on
line source
1 /*
2 * This file is part of the Advance project.
3 *
4 * Copyright (C) 2003 Andrea Mazzoleni
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20 * In addition, as a special exception, Andrea Mazzoleni
21 * gives permission to link the code of this program with
22 * the MAME library (or with modified versions of MAME that use the
23 * same license as MAME), and distribute linked combinations including
24 * the two. You must obey the GNU General Public License in all
25 * respects for all of the code used other than MAME. If you modify
26 * this file, you may extend this exception to your version of the
27 * file, but you are not obligated to do so. If you do not wish to
28 * do so, delete this exception statement from your version.
29 */
30 #include "../Port.h"
31 #include "interp.h"
33 unsigned interp_mask[2];
34 unsigned interp_bits_per_pixel;
36 /***************************************************************************/
37 /* HQ2x C implementation */
39 /*
40 * This effect is a rewritten implementation of the hq2x effect made by Maxim Stepin
41 */
43 static void hq2x_16_def(u16 *dst0, u16 *dst1, const u16 *src0, const u16 *src1, const u16 *src2, unsigned count)
44 {
45 unsigned i;
47 for (i = 0; i < count; ++i)
48 {
49 unsigned char mask;
51 u16 c[9];
53 c[1] = src0[0];
54 c[4] = src1[0];
55 c[7] = src2[0];
57 if (i > 0)
58 {
59 c[0] = src0[-1];
60 c[3] = src1[-1];
61 c[6] = src2[-1];
62 }
63 else
64 {
65 c[0] = c[1];
66 c[3] = c[4];
67 c[6] = c[7];
68 }
70 if (i < count - 1)
71 {
72 c[2] = src0[1];
73 c[5] = src1[1];
74 c[8] = src2[1];
75 }
76 else
77 {
78 c[2] = c[1];
79 c[5] = c[4];
80 c[8] = c[7];
81 }
83 mask = 0;
85 if (interp_16_diff(c[0], c[4]))
86 mask |= 1 << 0;
87 if (interp_16_diff(c[1], c[4]))
88 mask |= 1 << 1;
89 if (interp_16_diff(c[2], c[4]))
90 mask |= 1 << 2;
91 if (interp_16_diff(c[3], c[4]))
92 mask |= 1 << 3;
93 if (interp_16_diff(c[5], c[4]))
94 mask |= 1 << 4;
95 if (interp_16_diff(c[6], c[4]))
96 mask |= 1 << 5;
97 if (interp_16_diff(c[7], c[4]))
98 mask |= 1 << 6;
99 if (interp_16_diff(c[8], c[4]))
100 mask |= 1 << 7;
102 #define P0 dst0[0]
103 #define P1 dst0[1]
104 #define P2 dst1[0]
105 #define P3 dst1[1]
106 #define MUR interp_16_diff(c[1], c[5]) // top-right
107 #define MDR interp_16_diff(c[5], c[7]) // bottom-right
108 #define MDL interp_16_diff(c[7], c[3]) // bottom-left
109 #define MUL interp_16_diff(c[3], c[1]) // top-left
110 #define IC(p0) c[p0]
111 #define I11(p0, p1) interp_16_11(c[p0], c[p1])
112 #define I211(p0, p1, p2) interp_16_211(c[p0], c[p1], c[p2])
113 #define I31(p0, p1) interp_16_31(c[p0], c[p1])
114 #define I332(p0, p1, p2) interp_16_332(c[p0], c[p1], c[p2])
115 #define I431(p0, p1, p2) interp_16_431(c[p0], c[p1], c[p2])
116 #define I521(p0, p1, p2) interp_16_521(c[p0], c[p1], c[p2])
117 #define I53(p0, p1) interp_16_53(c[p0], c[p1])
118 #define I611(p0, p1, p2) interp_16_611(c[p0], c[p1], c[p2])
119 #define I71(p0, p1) interp_16_71(c[p0], c[p1])
120 #define I772(p0, p1, p2) interp_16_772(c[p0], c[p1], c[p2])
121 #define I97(p0, p1) interp_16_97(c[p0], c[p1])
122 #define I1411(p0, p1, p2) interp_16_1411(c[p0], c[p1], c[p2])
123 #define I151(p0, p1) interp_16_151(c[p0], c[p1])
125 switch (mask)
126 {
127 #include "hq2x.h"
128 }
130 #undef P0
131 #undef P1
132 #undef P2
133 #undef P3
134 #undef MUR
135 #undef MDR
136 #undef MDL
137 #undef MUL
138 #undef IC
139 #undef I11
140 #undef I211
141 #undef I31
142 #undef I332
143 #undef I431
144 #undef I521
145 #undef I53
146 #undef I611
147 #undef I71
148 #undef I772
149 #undef I97
150 #undef I1411
151 #undef I151
153 src0 += 1;
154 src1 += 1;
155 src2 += 1;
156 dst0 += 2;
157 dst1 += 2;
158 }
159 }
161 static void hq2x_32_def(u32 *dst0, u32 *dst1, const u32 *src0, const u32 *src1, const u32 *src2, unsigned count)
162 {
163 unsigned i;
165 for (i = 0; i < count; ++i)
166 {
167 unsigned char mask;
169 u32 c[9];
171 c[1] = src0[0];
172 c[4] = src1[0];
173 c[7] = src2[0];
175 if (i > 0)
176 {
177 c[0] = src0[-1];
178 c[3] = src1[-1];
179 c[6] = src2[-1];
180 }
181 else
182 {
183 c[0] = c[1];
184 c[3] = c[4];
185 c[6] = c[7];
186 }
188 if (i < count - 1)
189 {
190 c[2] = src0[1];
191 c[5] = src1[1];
192 c[8] = src2[1];
193 }
194 else
195 {
196 c[2] = c[1];
197 c[5] = c[4];
198 c[8] = c[7];
199 }
201 mask = 0;
203 if (interp_32_diff(c[0], c[4]))
204 mask |= 1 << 0;
205 if (interp_32_diff(c[1], c[4]))
206 mask |= 1 << 1;
207 if (interp_32_diff(c[2], c[4]))
208 mask |= 1 << 2;
209 if (interp_32_diff(c[3], c[4]))
210 mask |= 1 << 3;
211 if (interp_32_diff(c[5], c[4]))
212 mask |= 1 << 4;
213 if (interp_32_diff(c[6], c[4]))
214 mask |= 1 << 5;
215 if (interp_32_diff(c[7], c[4]))
216 mask |= 1 << 6;
217 if (interp_32_diff(c[8], c[4]))
218 mask |= 1 << 7;
220 #define P0 dst0[0]
221 #define P1 dst0[1]
222 #define P2 dst1[0]
223 #define P3 dst1[1]
224 #define MUR interp_32_diff(c[1], c[5]) // top-right
225 #define MDR interp_32_diff(c[5], c[7]) // bottom-right
226 #define MDL interp_32_diff(c[7], c[3]) // bottom-left
227 #define MUL interp_32_diff(c[3], c[1]) // top-left
228 #define IC(p0) c[p0]
229 #define I11(p0, p1) interp_32_11(c[p0], c[p1])
230 #define I211(p0, p1, p2) interp_32_211(c[p0], c[p1], c[p2])
231 #define I31(p0, p1) interp_32_31(c[p0], c[p1])
232 #define I332(p0, p1, p2) interp_32_332(c[p0], c[p1], c[p2])
233 #define I431(p0, p1, p2) interp_32_431(c[p0], c[p1], c[p2])
234 #define I521(p0, p1, p2) interp_32_521(c[p0], c[p1], c[p2])
235 #define I53(p0, p1) interp_32_53(c[p0], c[p1])
236 #define I611(p0, p1, p2) interp_32_611(c[p0], c[p1], c[p2])
237 #define I71(p0, p1) interp_32_71(c[p0], c[p1])
238 #define I772(p0, p1, p2) interp_32_772(c[p0], c[p1], c[p2])
239 #define I97(p0, p1) interp_32_97(c[p0], c[p1])
240 #define I1411(p0, p1, p2) interp_32_1411(c[p0], c[p1], c[p2])
241 #define I151(p0, p1) interp_32_151(c[p0], c[p1])
243 switch (mask)
244 {
245 #include "hq2x.h"
246 }
248 #undef P0
249 #undef P1
250 #undef P2
251 #undef P3
252 #undef MUR
253 #undef MDR
254 #undef MDL
255 #undef MUL
256 #undef IC
257 #undef I11
258 #undef I211
259 #undef I31
260 #undef I332
261 #undef I431
262 #undef I521
263 #undef I53
264 #undef I611
265 #undef I71
266 #undef I772
267 #undef I97
268 #undef I1411
269 #undef I151
271 src0 += 1;
272 src1 += 1;
273 src2 += 1;
274 dst0 += 2;
275 dst1 += 2;
276 }
277 }
279 /***************************************************************************/
280 /* HQ2xS C implementation */
282 /*
283 * This effect is derived from the hq2x effect made by Maxim Stepin
284 */
286 static void hq2xS_16_def(u16 *dst0, u16 *dst1, const u16 *src0, const u16 *src1, const u16 *src2, unsigned count)
287 {
288 unsigned i;
290 for (i = 0; i < count; ++i)
291 {
292 unsigned char mask;
294 u16 c[9];
296 c[1] = src0[0];
297 c[4] = src1[0];
298 c[7] = src2[0];
300 c[0] = src0[-1];
301 c[3] = src1[-1];
302 c[6] = src2[-1];
304 c[2] = src0[1];
305 c[5] = src1[1];
306 c[8] = src2[1];
308 mask = 0;
310 // hq2xS dynamic edge detection:
311 // simply comparing the center color against its surroundings will give bad results in many cases,
312 // so, instead, compare the center color relative to the max difference in brightness of this 3x3 block
313 int brightArray[9];
314 int maxBright = 0, minBright = 999999;
315 for (int j = 0; j < 9; j++)
316 {
317 int r, g, b;
318 if (interp_bits_per_pixel == 16)
319 {
320 b = (int)((c[j] & 0x1F)) << 3;
321 g = (int)((c[j] & 0x7E0)) >> 3;
322 r = (int)((c[j] & 0xF800)) >> 8;
323 }
324 else
325 {
326 b = (int)((c[j] & 0x1F)) << 3;
327 g = (int)((c[j] & 0x3E0)) >> 2;
328 r = (int)((c[j] & 0x7C00)) >> 7;
329 }
330 const int bright = r + r + r + g + g + g + b + b;
331 if (bright > maxBright) maxBright = bright;
332 if (bright < minBright) minBright = bright;
334 brightArray[j] = bright;
335 }
336 int diffBright = ((maxBright - minBright) * 7) >> 4;
337 if (diffBright > 7)
338 {
339 #define ABS(x) ((x) < 0 ? -(x) : (x))
341 const int centerBright = brightArray[4];
342 if (ABS(brightArray[0] - centerBright) > diffBright)
343 mask |= 1 << 0;
344 if (ABS(brightArray[1] - centerBright) > diffBright)
345 mask |= 1 << 1;
346 if (ABS(brightArray[2] - centerBright) > diffBright)
347 mask |= 1 << 2;
348 if (ABS(brightArray[3] - centerBright) > diffBright)
349 mask |= 1 << 3;
350 if (ABS(brightArray[5] - centerBright) > diffBright)
351 mask |= 1 << 4;
352 if (ABS(brightArray[6] - centerBright) > diffBright)
353 mask |= 1 << 5;
354 if (ABS(brightArray[7] - centerBright) > diffBright)
355 mask |= 1 << 6;
356 if (ABS(brightArray[8] - centerBright) > diffBright)
357 mask |= 1 << 7;
358 }
360 #define P0 dst0[0]
361 #define P1 dst0[1]
362 #define P2 dst1[0]
363 #define P3 dst1[1]
364 #define MUR false //(ABS(brightArray[1] - brightArray[5]) > diffBright) // top-right
365 #define MDR false //(ABS(brightArray[5] - brightArray[7]) > diffBright) // bottom-right
366 #define MDL false //(ABS(brightArray[7] - brightArray[3]) > diffBright) // bottom-left
367 #define MUL false //(ABS(brightArray[3] - brightArray[1]) > diffBright) // top-left
368 #define IC(p0) c[p0]
369 #define I11(p0, p1) interp_16_11(c[p0], c[p1])
370 #define I211(p0, p1, p2) interp_16_211(c[p0], c[p1], c[p2])
371 #define I31(p0, p1) interp_16_31(c[p0], c[p1])
372 #define I332(p0, p1, p2) interp_16_332(c[p0], c[p1], c[p2])
373 #define I431(p0, p1, p2) interp_16_431(c[p0], c[p1], c[p2])
374 #define I521(p0, p1, p2) interp_16_521(c[p0], c[p1], c[p2])
375 #define I53(p0, p1) interp_16_53(c[p0], c[p1])
376 #define I611(p0, p1, p2) interp_16_611(c[p0], c[p1], c[p2])
377 #define I71(p0, p1) interp_16_71(c[p0], c[p1])
378 #define I772(p0, p1, p2) interp_16_772(c[p0], c[p1], c[p2])
379 #define I97(p0, p1) interp_16_97(c[p0], c[p1])
380 #define I1411(p0, p1, p2) interp_16_1411(c[p0], c[p1], c[p2])
381 #define I151(p0, p1) interp_16_151(c[p0], c[p1])
383 switch (mask)
384 {
385 #include "hq2x.h"
386 }
388 #undef P0
389 #undef P1
390 #undef P2
391 #undef P3
392 #undef MUR
393 #undef MDR
394 #undef MDL
395 #undef MUL
396 #undef IC
397 #undef I11
398 #undef I211
399 #undef I31
400 #undef I332
401 #undef I431
402 #undef I521
403 #undef I53
404 #undef I611
405 #undef I71
406 #undef I772
407 #undef I97
408 #undef I1411
409 #undef I151
411 src0 += 1;
412 src1 += 1;
413 src2 += 1;
414 dst0 += 2;
415 dst1 += 2;
416 }
417 }
419 static void hq2xS_32_def(u32 *dst0, u32 *dst1, const u32 *src0, const u32 *src1, const u32 *src2, unsigned count)
420 {
421 unsigned i;
423 for (i = 0; i < count; ++i)
424 {
425 unsigned char mask;
427 u32 c[9];
429 c[1] = src0[0];
430 c[4] = src1[0];
431 c[7] = src2[0];
433 c[0] = src0[-1];
434 c[3] = src1[-1];
435 c[6] = src2[-1];
437 c[2] = src0[1];
438 c[5] = src1[1];
439 c[8] = src2[1];
441 mask = 0;
443 // hq2xS dynamic edge detection:
444 // simply comparing the center color against its surroundings will give bad results in many cases,
445 // so, instead, compare the center color relative to the max difference in brightness of this 3x3 block
446 int brightArray[9];
447 int maxBright = 0, minBright = 999999;
448 for (int j = 0; j < 9; j++)
449 {
450 const int b = (int)((c[j] & 0xF8));
451 const int g = (int)((c[j] & 0xF800)) >> 8;
452 const int r = (int)((c[j] & 0xF80000)) >> 16;
453 const int bright = r + r + r + g + g + g + b + b;
454 if (bright > maxBright) maxBright = bright;
455 if (bright < minBright) minBright = bright;
457 brightArray[j] = bright;
458 }
459 int diffBright = ((maxBright - minBright) * 7) >> 4;
460 if (diffBright > 7)
461 {
462 #define ABS(x) ((x) < 0 ? -(x) : (x))
464 const int centerBright = brightArray[4];
465 if (ABS(brightArray[0] - centerBright) > diffBright)
466 mask |= 1 << 0;
467 if (ABS(brightArray[1] - centerBright) > diffBright)
468 mask |= 1 << 1;
469 if (ABS(brightArray[2] - centerBright) > diffBright)
470 mask |= 1 << 2;
471 if (ABS(brightArray[3] - centerBright) > diffBright)
472 mask |= 1 << 3;
473 if (ABS(brightArray[5] - centerBright) > diffBright)
474 mask |= 1 << 4;
475 if (ABS(brightArray[6] - centerBright) > diffBright)
476 mask |= 1 << 5;
477 if (ABS(brightArray[7] - centerBright) > diffBright)
478 mask |= 1 << 6;
479 if (ABS(brightArray[8] - centerBright) > diffBright)
480 mask |= 1 << 7;
481 }
483 #define P0 dst0[0]
484 #define P1 dst0[1]
485 #define P2 dst1[0]
486 #define P3 dst1[1]
487 #define MUR false //(ABS(brightArray[1] - brightArray[5]) > diffBright) // top-right
488 #define MDR false //(ABS(brightArray[5] - brightArray[7]) > diffBright) // bottom-right
489 #define MDL false //(ABS(brightArray[7] - brightArray[3]) > diffBright) // bottom-left
490 #define MUL false //(ABS(brightArray[3] - brightArray[1]) > diffBright) // top-left
491 #define IC(p0) c[p0]
492 #define I11(p0, p1) interp_32_11(c[p0], c[p1])
493 #define I211(p0, p1, p2) interp_32_211(c[p0], c[p1], c[p2])
494 #define I31(p0, p1) interp_32_31(c[p0], c[p1])
495 #define I332(p0, p1, p2) interp_32_332(c[p0], c[p1], c[p2])
496 #define I431(p0, p1, p2) interp_32_431(c[p0], c[p1], c[p2])
497 #define I521(p0, p1, p2) interp_32_521(c[p0], c[p1], c[p2])
498 #define I53(p0, p1) interp_32_53(c[p0], c[p1])
499 #define I611(p0, p1, p2) interp_32_611(c[p0], c[p1], c[p2])
500 #define I71(p0, p1) interp_32_71(c[p0], c[p1])
501 #define I772(p0, p1, p2) interp_32_772(c[p0], c[p1], c[p2])
502 #define I97(p0, p1) interp_32_97(c[p0], c[p1])
503 #define I1411(p0, p1, p2) interp_32_1411(c[p0], c[p1], c[p2])
504 #define I151(p0, p1) interp_32_151(c[p0], c[p1])
506 switch (mask)
507 {
508 #include "hq2x.h"
509 }
511 #undef P0
512 #undef P1
513 #undef P2
514 #undef P3
515 #undef MUR
516 #undef MDR
517 #undef MDL
518 #undef MUL
519 #undef IC
520 #undef I11
521 #undef I211
522 #undef I31
523 #undef I332
524 #undef I431
525 #undef I521
526 #undef I53
527 #undef I611
528 #undef I71
529 #undef I772
530 #undef I97
531 #undef I1411
532 #undef I151
534 src0 += 1;
535 src1 += 1;
536 src2 += 1;
537 dst0 += 2;
538 dst1 += 2;
539 }
540 }
542 /***************************************************************************/
543 /* LQ2x C implementation */
545 /*
546 * This effect is derived from the hq2x effect made by Maxim Stepin
547 */
549 static void lq2x_16_def(u16 *dst0, u16 *dst1, const u16 *src0, const u16 *src1, const u16 *src2, unsigned count)
550 {
551 unsigned i;
553 for (i = 0; i < count; ++i)
554 {
555 unsigned char mask;
557 u16 c[9];
559 c[1] = src0[0];
560 c[4] = src1[0];
561 c[7] = src2[0];
563 if (i > 0)
564 {
565 c[0] = src0[-1];
566 c[3] = src1[-1];
567 c[6] = src2[-1];
568 }
569 else
570 {
571 c[0] = c[1];
572 c[3] = c[4];
573 c[6] = c[7];
574 }
576 if (i < count - 1)
577 {
578 c[2] = src0[1];
579 c[5] = src1[1];
580 c[8] = src2[1];
581 }
582 else
583 {
584 c[2] = c[1];
585 c[5] = c[4];
586 c[8] = c[7];
587 }
589 mask = 0;
591 if (c[0] != c[4])
592 mask |= 1 << 0;
593 if (c[1] != c[4])
594 mask |= 1 << 1;
595 if (c[2] != c[4])
596 mask |= 1 << 2;
597 if (c[3] != c[4])
598 mask |= 1 << 3;
599 if (c[5] != c[4])
600 mask |= 1 << 4;
601 if (c[6] != c[4])
602 mask |= 1 << 5;
603 if (c[7] != c[4])
604 mask |= 1 << 6;
605 if (c[8] != c[4])
606 mask |= 1 << 7;
608 #define P0 dst0[0]
609 #define P1 dst0[1]
610 #define P2 dst1[0]
611 #define P3 dst1[1]
612 #define MUR (c[1] != c[5])
613 #define MDR (c[5] != c[7])
614 #define MDL (c[7] != c[3])
615 #define MUL (c[3] != c[1])
616 #define IC(p0) c[p0]
617 #define I11(p0, p1) interp_16_11(c[p0], c[p1])
618 #define I211(p0, p1, p2) interp_16_211(c[p0], c[p1], c[p2])
619 #define I31(p0, p1) interp_16_31(c[p0], c[p1])
620 #define I332(p0, p1, p2) interp_16_332(c[p0], c[p1], c[p2])
621 #define I431(p0, p1, p2) interp_16_431(c[p0], c[p1], c[p2])
622 #define I521(p0, p1, p2) interp_16_521(c[p0], c[p1], c[p2])
623 #define I53(p0, p1) interp_16_53(c[p0], c[p1])
624 #define I611(p0, p1, p2) interp_16_611(c[p0], c[p1], c[p2])
625 #define I71(p0, p1) interp_16_71(c[p0], c[p1])
626 #define I772(p0, p1, p2) interp_16_772(c[p0], c[p1], c[p2])
627 #define I97(p0, p1) interp_16_97(c[p0], c[p1])
628 #define I1411(p0, p1, p2) interp_16_1411(c[p0], c[p1], c[p2])
629 #define I151(p0, p1) interp_16_151(c[p0], c[p1])
631 switch (mask)
632 {
633 #include "lq2x.h"
634 }
636 #undef P0
637 #undef P1
638 #undef P2
639 #undef P3
640 #undef MUR
641 #undef MDR
642 #undef MDL
643 #undef MUL
644 #undef IC
645 #undef I11
646 #undef I211
647 #undef I31
648 #undef I332
649 #undef I431
650 #undef I521
651 #undef I53
652 #undef I611
653 #undef I71
654 #undef I772
655 #undef I97
656 #undef I1411
657 #undef I151
659 src0 += 1;
660 src1 += 1;
661 src2 += 1;
662 dst0 += 2;
663 dst1 += 2;
664 }
665 }
667 static void lq2x_32_def(u32 *dst0, u32 *dst1, const u32 *src0, const u32 *src1, const u32 *src2, unsigned count)
668 {
669 unsigned i;
671 for (i = 0; i < count; ++i)
672 {
673 unsigned char mask;
675 u32 c[9];
677 c[1] = src0[0];
678 c[4] = src1[0];
679 c[7] = src2[0];
681 if (i > 0)
682 {
683 c[0] = src0[-1];
684 c[3] = src1[-1];
685 c[6] = src2[-1];
686 }
687 else
688 {
689 c[0] = c[1];
690 c[3] = c[4];
691 c[6] = c[7];
692 }
694 if (i < count - 1)
695 {
696 c[2] = src0[1];
697 c[5] = src1[1];
698 c[8] = src2[1];
699 }
700 else
701 {
702 c[2] = c[1];
703 c[5] = c[4];
704 c[8] = c[7];
705 }
707 mask = 0;
709 if (c[0] != c[4])
710 mask |= 1 << 0;
711 if (c[1] != c[4])
712 mask |= 1 << 1;
713 if (c[2] != c[4])
714 mask |= 1 << 2;
715 if (c[3] != c[4])
716 mask |= 1 << 3;
717 if (c[5] != c[4])
718 mask |= 1 << 4;
719 if (c[6] != c[4])
720 mask |= 1 << 5;
721 if (c[7] != c[4])
722 mask |= 1 << 6;
723 if (c[8] != c[4])
724 mask |= 1 << 7;
726 #define P0 dst0[0]
727 #define P1 dst0[1]
728 #define P2 dst1[0]
729 #define P3 dst1[1]
730 #define MUR (c[1] != c[5])
731 #define MDR (c[5] != c[7])
732 #define MDL (c[7] != c[3])
733 #define MUL (c[3] != c[1])
734 #define IC(p0) c[p0]
735 #define I11(p0, p1) interp_32_11(c[p0], c[p1])
736 #define I211(p0, p1, p2) interp_32_211(c[p0], c[p1], c[p2])
737 #define I31(p0, p1) interp_32_31(c[p0], c[p1])
738 #define I332(p0, p1, p2) interp_32_332(c[p0], c[p1], c[p2])
739 #define I431(p0, p1, p2) interp_32_431(c[p0], c[p1], c[p2])
740 #define I521(p0, p1, p2) interp_32_521(c[p0], c[p1], c[p2])
741 #define I53(p0, p1) interp_32_53(c[p0], c[p1])
742 #define I611(p0, p1, p2) interp_32_611(c[p0], c[p1], c[p2])
743 #define I71(p0, p1) interp_32_71(c[p0], c[p1])
744 #define I772(p0, p1, p2) interp_32_772(c[p0], c[p1], c[p2])
745 #define I97(p0, p1) interp_32_97(c[p0], c[p1])
746 #define I1411(p0, p1, p2) interp_32_1411(c[p0], c[p1], c[p2])
747 #define I151(p0, p1) interp_32_151(c[p0], c[p1])
749 switch (mask)
750 {
751 #include "lq2x.h"
752 }
754 #undef P0
755 #undef P1
756 #undef P2
757 #undef P3
758 #undef MUR
759 #undef MDR
760 #undef MDL
761 #undef MUL
762 #undef IC
763 #undef I11
764 #undef I211
765 #undef I31
766 #undef I332
767 #undef I431
768 #undef I521
769 #undef I53
770 #undef I611
771 #undef I71
772 #undef I772
773 #undef I97
774 #undef I1411
775 #undef I151
777 src0 += 1;
778 src1 += 1;
779 src2 += 1;
780 dst0 += 2;
781 dst1 += 2;
782 }
783 }
785 void hq2x(u8 *srcPtr, u32 srcPitch, u8 * /* deltaPtr */,
786 u8 *dstPtr, u32 dstPitch, int width, int height)
787 {
788 u16 *dst0 = (u16 *)dstPtr;
789 u16 *dst1 = dst0 + (dstPitch >> 1);
791 u16 *src0 = (u16 *)srcPtr;
792 u16 *src1 = src0 + (srcPitch >> 1);
793 u16 *src2 = src1 + (srcPitch >> 1);
795 hq2x_16_def(dst0, dst1, src0, src0, src1, width);
797 int count = height;
799 count -= 2;
800 while (count)
801 {
802 dst0 += dstPitch;
803 dst1 += dstPitch;
804 hq2x_16_def(dst0, dst1, src0, src1, src2, width);
805 src0 = src1;
806 src1 = src2;
807 src2 += srcPitch >> 1;
808 --count;
809 }
810 dst0 += dstPitch;
811 dst1 += dstPitch;
812 hq2x_16_def(dst0, dst1, src0, src1, src1, width);
813 }
815 void hq2x32(u8 *srcPtr, u32 srcPitch, u8 * /* deltaPtr */,
816 u8 *dstPtr, u32 dstPitch, int width, int height)
817 {
818 u32 *dst0 = (u32 *)dstPtr;
819 u32 *dst1 = dst0 + (dstPitch >> 2);
821 u32 *src0 = (u32 *)srcPtr;
822 u32 *src1 = src0 + (srcPitch >> 2);
823 u32 *src2 = src1 + (srcPitch >> 2);
824 hq2x_32_def(dst0, dst1, src0, src0, src1, width);
826 int count = height;
828 count -= 2;
829 while (count)
830 {
831 dst0 += dstPitch >> 1;
832 dst1 += dstPitch >> 1;
833 hq2x_32_def(dst0, dst1, src0, src1, src2, width);
834 src0 = src1;
835 src1 = src2;
836 src2 += srcPitch >> 2;
837 --count;
838 }
839 dst0 += dstPitch >> 1;
840 dst1 += dstPitch >> 1;
841 hq2x_32_def(dst0, dst1, src0, src1, src1, width);
842 }
844 void hq2xS(u8 *srcPtr, u32 srcPitch, u8 * /* deltaPtr */,
845 u8 *dstPtr, u32 dstPitch, int width, int height)
846 {
847 u16 *dst0 = (u16 *)dstPtr;
848 u16 *dst1 = dst0 + (dstPitch >> 1);
850 u16 *src0 = (u16 *)srcPtr;
851 u16 *src1 = src0 + (srcPitch >> 1);
852 u16 *src2 = src1 + (srcPitch >> 1);
854 hq2xS_16_def(dst0, dst1, src0, src0, src1, width);
856 int count = height;
858 count -= 2;
859 while (count)
860 {
861 dst0 += dstPitch;
862 dst1 += dstPitch;
863 hq2xS_16_def(dst0, dst1, src0, src1, src2, width);
864 src0 = src1;
865 src1 = src2;
866 src2 += srcPitch >> 1;
867 --count;
868 }
869 dst0 += dstPitch;
870 dst1 += dstPitch;
871 hq2xS_16_def(dst0, dst1, src0, src1, src1, width);
872 }
874 void hq2xS32(u8 *srcPtr, u32 srcPitch, u8 * /* deltaPtr */,
875 u8 *dstPtr, u32 dstPitch, int width, int height)
876 {
877 u32 *dst0 = (u32 *)dstPtr;
878 u32 *dst1 = dst0 + (dstPitch >> 2);
880 u32 *src0 = (u32 *)srcPtr;
881 u32 *src1 = src0 + (srcPitch >> 2);
882 u32 *src2 = src1 + (srcPitch >> 2);
883 hq2xS_32_def(dst0, dst1, src0, src0, src1, width);
885 int count = height;
887 count -= 2;
888 while (count)
889 {
890 dst0 += dstPitch >> 1;
891 dst1 += dstPitch >> 1;
892 hq2xS_32_def(dst0, dst1, src0, src1, src2, width);
893 src0 = src1;
894 src1 = src2;
895 src2 += srcPitch >> 2;
896 --count;
897 }
898 dst0 += dstPitch >> 1;
899 dst1 += dstPitch >> 1;
900 hq2xS_32_def(dst0, dst1, src0, src1, src1, width);
901 }
903 void lq2x(u8 *srcPtr, u32 srcPitch, u8 * /* deltaPtr */,
904 u8 *dstPtr, u32 dstPitch, int width, int height)
905 {
906 u16 *dst0 = (u16 *)dstPtr;
907 u16 *dst1 = dst0 + (dstPitch >> 1);
909 u16 *src0 = (u16 *)srcPtr;
910 u16 *src1 = src0 + (srcPitch >> 1);
911 u16 *src2 = src1 + (srcPitch >> 1);
913 lq2x_16_def(dst0, dst1, src0, src0, src1, width);
915 int count = height;
917 count -= 2;
918 while (count)
919 {
920 dst0 += dstPitch;
921 dst1 += dstPitch;
922 lq2x_16_def(dst0, dst1, src0, src1, src2, width);
923 src0 = src1;
924 src1 = src2;
925 src2 += srcPitch >> 1;
926 --count;
927 }
928 dst0 += dstPitch;
929 dst1 += dstPitch;
930 lq2x_16_def(dst0, dst1, src0, src1, src1, width);
931 }
933 void lq2x32(u8 *srcPtr, u32 srcPitch, u8 * /* deltaPtr */,
934 u8 *dstPtr, u32 dstPitch, int width, int height)
935 {
936 u32 *dst0 = (u32 *)dstPtr;
937 u32 *dst1 = dst0 + (dstPitch >> 2);
939 u32 *src0 = (u32 *)srcPtr;
940 u32 *src1 = src0 + (srcPitch >> 2);
941 u32 *src2 = src1 + (srcPitch >> 2);
942 lq2x_32_def(dst0, dst1, src0, src0, src1, width);
944 int count = height;
946 count -= 2;
947 while (count)
948 {
949 dst0 += dstPitch >> 1;
950 dst1 += dstPitch >> 1;
951 lq2x_32_def(dst0, dst1, src0, src1, src2, width);
952 src0 = src1;
953 src1 = src2;
954 src2 += srcPitch >> 2;
955 --count;
956 }
957 dst0 += dstPitch >> 1;
958 dst1 += dstPitch >> 1;
959 lq2x_32_def(dst0, dst1, src0, src1, src1, width);
960 }
962 void hq2x_init(unsigned bits_per_pixel)
963 {
964 interp_set(bits_per_pixel);
965 }