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