diff src/filters/hq2x.cpp @ 1:f9f4f1b99eed

importing src directory
author Robert McIntyre <rlm@mit.edu>
date Sat, 03 Mar 2012 10:31:27 -0600
parents
children
line wrap: on
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/filters/hq2x.cpp	Sat Mar 03 10:31:27 2012 -0600
     1.3 @@ -0,0 +1,966 @@
     1.4 +/*
     1.5 + * This file is part of the Advance project.
     1.6 + *
     1.7 + * Copyright (C) 2003 Andrea Mazzoleni
     1.8 + *
     1.9 + * This program is free software; you can redistribute it and/or modify
    1.10 + * it under the terms of the GNU General Public License as published by
    1.11 + * the Free Software Foundation; either version 2 of the License, or
    1.12 + * (at your option) any later version.
    1.13 + *
    1.14 + * This program is distributed in the hope that it will be useful,
    1.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    1.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1.17 + * GNU General Public License for more details.
    1.18 + *
    1.19 + * You should have received a copy of the GNU General Public License
    1.20 + * along with this program; if not, write to the Free Software
    1.21 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
    1.22 + *
    1.23 + * In addition, as a special exception, Andrea Mazzoleni
    1.24 + * gives permission to link the code of this program with
    1.25 + * the MAME library (or with modified versions of MAME that use the
    1.26 + * same license as MAME), and distribute linked combinations including
    1.27 + * the two.  You must obey the GNU General Public License in all
    1.28 + * respects for all of the code used other than MAME.  If you modify
    1.29 + * this file, you may extend this exception to your version of the
    1.30 + * file, but you are not obligated to do so.  If you do not wish to
    1.31 + * do so, delete this exception statement from your version.
    1.32 + */
    1.33 +#include "../Port.h"
    1.34 +#include "interp.h"
    1.35 +
    1.36 +unsigned interp_mask[2];
    1.37 +unsigned interp_bits_per_pixel;
    1.38 +
    1.39 +/***************************************************************************/
    1.40 +/* HQ2x C implementation */
    1.41 +
    1.42 +/*
    1.43 + * This effect is a rewritten implementation of the hq2x effect made by Maxim Stepin
    1.44 + */
    1.45 +
    1.46 +static void hq2x_16_def(u16 *dst0, u16 *dst1, const u16 *src0, const u16 *src1, const u16 *src2, unsigned count)
    1.47 +{
    1.48 +	unsigned i;
    1.49 +
    1.50 +	for (i = 0; i < count; ++i)
    1.51 +	{
    1.52 +		unsigned char mask;
    1.53 +
    1.54 +		u16 c[9];
    1.55 +
    1.56 +		c[1] = src0[0];
    1.57 +		c[4] = src1[0];
    1.58 +		c[7] = src2[0];
    1.59 +
    1.60 +		if (i > 0)
    1.61 +		{
    1.62 +			c[0] = src0[-1];
    1.63 +			c[3] = src1[-1];
    1.64 +			c[6] = src2[-1];
    1.65 +		}
    1.66 +		else
    1.67 +		{
    1.68 +			c[0] = c[1];
    1.69 +			c[3] = c[4];
    1.70 +			c[6] = c[7];
    1.71 +		}
    1.72 +
    1.73 +		if (i < count - 1)
    1.74 +		{
    1.75 +			c[2] = src0[1];
    1.76 +			c[5] = src1[1];
    1.77 +			c[8] = src2[1];
    1.78 +		}
    1.79 +		else
    1.80 +		{
    1.81 +			c[2] = c[1];
    1.82 +			c[5] = c[4];
    1.83 +			c[8] = c[7];
    1.84 +		}
    1.85 +
    1.86 +		mask = 0;
    1.87 +
    1.88 +		if (interp_16_diff(c[0], c[4]))
    1.89 +			mask |= 1 << 0;
    1.90 +		if (interp_16_diff(c[1], c[4]))
    1.91 +			mask |= 1 << 1;
    1.92 +		if (interp_16_diff(c[2], c[4]))
    1.93 +			mask |= 1 << 2;
    1.94 +		if (interp_16_diff(c[3], c[4]))
    1.95 +			mask |= 1 << 3;
    1.96 +		if (interp_16_diff(c[5], c[4]))
    1.97 +			mask |= 1 << 4;
    1.98 +		if (interp_16_diff(c[6], c[4]))
    1.99 +			mask |= 1 << 5;
   1.100 +		if (interp_16_diff(c[7], c[4]))
   1.101 +			mask |= 1 << 6;
   1.102 +		if (interp_16_diff(c[8], c[4]))
   1.103 +			mask |= 1 << 7;
   1.104 +
   1.105 +#define P0 dst0[0]
   1.106 +#define P1 dst0[1]
   1.107 +#define P2 dst1[0]
   1.108 +#define P3 dst1[1]
   1.109 +#define MUR interp_16_diff(c[1], c[5]) // top-right
   1.110 +#define MDR interp_16_diff(c[5], c[7]) // bottom-right
   1.111 +#define MDL interp_16_diff(c[7], c[3]) // bottom-left
   1.112 +#define MUL interp_16_diff(c[3], c[1]) // top-left
   1.113 +#define IC(p0) c[p0]
   1.114 +#define I11(p0, p1) interp_16_11(c[p0], c[p1])
   1.115 +#define I211(p0, p1, p2) interp_16_211(c[p0], c[p1], c[p2])
   1.116 +#define I31(p0, p1) interp_16_31(c[p0], c[p1])
   1.117 +#define I332(p0, p1, p2) interp_16_332(c[p0], c[p1], c[p2])
   1.118 +#define I431(p0, p1, p2) interp_16_431(c[p0], c[p1], c[p2])
   1.119 +#define I521(p0, p1, p2) interp_16_521(c[p0], c[p1], c[p2])
   1.120 +#define I53(p0, p1) interp_16_53(c[p0], c[p1])
   1.121 +#define I611(p0, p1, p2) interp_16_611(c[p0], c[p1], c[p2])
   1.122 +#define I71(p0, p1) interp_16_71(c[p0], c[p1])
   1.123 +#define I772(p0, p1, p2) interp_16_772(c[p0], c[p1], c[p2])
   1.124 +#define I97(p0, p1) interp_16_97(c[p0], c[p1])
   1.125 +#define I1411(p0, p1, p2) interp_16_1411(c[p0], c[p1], c[p2])
   1.126 +#define I151(p0, p1) interp_16_151(c[p0], c[p1])
   1.127 +
   1.128 +		switch (mask)
   1.129 +		{
   1.130 +#include "hq2x.h"
   1.131 +		}
   1.132 +
   1.133 +#undef P0
   1.134 +#undef P1
   1.135 +#undef P2
   1.136 +#undef P3
   1.137 +#undef MUR
   1.138 +#undef MDR
   1.139 +#undef MDL
   1.140 +#undef MUL
   1.141 +#undef IC
   1.142 +#undef I11
   1.143 +#undef I211
   1.144 +#undef I31
   1.145 +#undef I332
   1.146 +#undef I431
   1.147 +#undef I521
   1.148 +#undef I53
   1.149 +#undef I611
   1.150 +#undef I71
   1.151 +#undef I772
   1.152 +#undef I97
   1.153 +#undef I1411
   1.154 +#undef I151
   1.155 +
   1.156 +		src0 += 1;
   1.157 +		src1 += 1;
   1.158 +		src2 += 1;
   1.159 +		dst0 += 2;
   1.160 +		dst1 += 2;
   1.161 +	}
   1.162 +}
   1.163 +
   1.164 +static void hq2x_32_def(u32 *dst0, u32 *dst1, const u32 *src0, const u32 *src1, const u32 *src2, unsigned count)
   1.165 +{
   1.166 +	unsigned i;
   1.167 +
   1.168 +	for (i = 0; i < count; ++i)
   1.169 +	{
   1.170 +		unsigned char mask;
   1.171 +
   1.172 +		u32 c[9];
   1.173 +
   1.174 +		c[1] = src0[0];
   1.175 +		c[4] = src1[0];
   1.176 +		c[7] = src2[0];
   1.177 +
   1.178 +		if (i > 0)
   1.179 +		{
   1.180 +			c[0] = src0[-1];
   1.181 +			c[3] = src1[-1];
   1.182 +			c[6] = src2[-1];
   1.183 +		}
   1.184 +		else
   1.185 +		{
   1.186 +			c[0] = c[1];
   1.187 +			c[3] = c[4];
   1.188 +			c[6] = c[7];
   1.189 +		}
   1.190 +
   1.191 +		if (i < count - 1)
   1.192 +		{
   1.193 +			c[2] = src0[1];
   1.194 +			c[5] = src1[1];
   1.195 +			c[8] = src2[1];
   1.196 +		}
   1.197 +		else
   1.198 +		{
   1.199 +			c[2] = c[1];
   1.200 +			c[5] = c[4];
   1.201 +			c[8] = c[7];
   1.202 +		}
   1.203 +
   1.204 +		mask = 0;
   1.205 +
   1.206 +		if (interp_32_diff(c[0], c[4]))
   1.207 +			mask |= 1 << 0;
   1.208 +		if (interp_32_diff(c[1], c[4]))
   1.209 +			mask |= 1 << 1;
   1.210 +		if (interp_32_diff(c[2], c[4]))
   1.211 +			mask |= 1 << 2;
   1.212 +		if (interp_32_diff(c[3], c[4]))
   1.213 +			mask |= 1 << 3;
   1.214 +		if (interp_32_diff(c[5], c[4]))
   1.215 +			mask |= 1 << 4;
   1.216 +		if (interp_32_diff(c[6], c[4]))
   1.217 +			mask |= 1 << 5;
   1.218 +		if (interp_32_diff(c[7], c[4]))
   1.219 +			mask |= 1 << 6;
   1.220 +		if (interp_32_diff(c[8], c[4]))
   1.221 +			mask |= 1 << 7;
   1.222 +
   1.223 +#define P0 dst0[0]
   1.224 +#define P1 dst0[1]
   1.225 +#define P2 dst1[0]
   1.226 +#define P3 dst1[1]
   1.227 +#define MUR interp_32_diff(c[1], c[5]) // top-right
   1.228 +#define MDR interp_32_diff(c[5], c[7]) // bottom-right
   1.229 +#define MDL interp_32_diff(c[7], c[3]) // bottom-left
   1.230 +#define MUL interp_32_diff(c[3], c[1]) // top-left
   1.231 +#define IC(p0) c[p0]
   1.232 +#define I11(p0, p1) interp_32_11(c[p0], c[p1])
   1.233 +#define I211(p0, p1, p2) interp_32_211(c[p0], c[p1], c[p2])
   1.234 +#define I31(p0, p1) interp_32_31(c[p0], c[p1])
   1.235 +#define I332(p0, p1, p2) interp_32_332(c[p0], c[p1], c[p2])
   1.236 +#define I431(p0, p1, p2) interp_32_431(c[p0], c[p1], c[p2])
   1.237 +#define I521(p0, p1, p2) interp_32_521(c[p0], c[p1], c[p2])
   1.238 +#define I53(p0, p1) interp_32_53(c[p0], c[p1])
   1.239 +#define I611(p0, p1, p2) interp_32_611(c[p0], c[p1], c[p2])
   1.240 +#define I71(p0, p1) interp_32_71(c[p0], c[p1])
   1.241 +#define I772(p0, p1, p2) interp_32_772(c[p0], c[p1], c[p2])
   1.242 +#define I97(p0, p1) interp_32_97(c[p0], c[p1])
   1.243 +#define I1411(p0, p1, p2) interp_32_1411(c[p0], c[p1], c[p2])
   1.244 +#define I151(p0, p1) interp_32_151(c[p0], c[p1])
   1.245 +
   1.246 +		switch (mask)
   1.247 +		{
   1.248 +#include "hq2x.h"
   1.249 +		}
   1.250 +
   1.251 +#undef P0
   1.252 +#undef P1
   1.253 +#undef P2
   1.254 +#undef P3
   1.255 +#undef MUR
   1.256 +#undef MDR
   1.257 +#undef MDL
   1.258 +#undef MUL
   1.259 +#undef IC
   1.260 +#undef I11
   1.261 +#undef I211
   1.262 +#undef I31
   1.263 +#undef I332
   1.264 +#undef I431
   1.265 +#undef I521
   1.266 +#undef I53
   1.267 +#undef I611
   1.268 +#undef I71
   1.269 +#undef I772
   1.270 +#undef I97
   1.271 +#undef I1411
   1.272 +#undef I151
   1.273 +
   1.274 +		src0 += 1;
   1.275 +		src1 += 1;
   1.276 +		src2 += 1;
   1.277 +		dst0 += 2;
   1.278 +		dst1 += 2;
   1.279 +	}
   1.280 +}
   1.281 +
   1.282 +/***************************************************************************/
   1.283 +/* HQ2xS C implementation */
   1.284 +
   1.285 +/*
   1.286 + * This effect is derived from the hq2x effect made by Maxim Stepin
   1.287 + */
   1.288 +
   1.289 +static void hq2xS_16_def(u16 *dst0, u16 *dst1, const u16 *src0, const u16 *src1, const u16 *src2, unsigned count)
   1.290 +{
   1.291 +	unsigned i;
   1.292 +
   1.293 +	for (i = 0; i < count; ++i)
   1.294 +	{
   1.295 +		unsigned char mask;
   1.296 +
   1.297 +		u16 c[9];
   1.298 +
   1.299 +		c[1] = src0[0];
   1.300 +		c[4] = src1[0];
   1.301 +		c[7] = src2[0];
   1.302 +
   1.303 +		c[0] = src0[-1];
   1.304 +		c[3] = src1[-1];
   1.305 +		c[6] = src2[-1];
   1.306 +
   1.307 +		c[2] = src0[1];
   1.308 +		c[5] = src1[1];
   1.309 +		c[8] = src2[1];
   1.310 +
   1.311 +		mask = 0;
   1.312 +
   1.313 +		// hq2xS dynamic edge detection:
   1.314 +		// simply comparing the center color against its surroundings will give bad results in many cases,
   1.315 +		// so, instead, compare the center color relative to the max difference in brightness of this 3x3 block
   1.316 +		int brightArray[9];
   1.317 +		int maxBright = 0, minBright = 999999;
   1.318 +		for (int j = 0; j < 9; j++)
   1.319 +		{
   1.320 +			int r, g, b;
   1.321 +			if (interp_bits_per_pixel == 16)
   1.322 +			{
   1.323 +				b = (int)((c[j] & 0x1F)) << 3;
   1.324 +				g = (int)((c[j] & 0x7E0)) >> 3;
   1.325 +				r = (int)((c[j] & 0xF800)) >> 8;
   1.326 +			}
   1.327 +			else
   1.328 +			{
   1.329 +				b = (int)((c[j] & 0x1F)) << 3;
   1.330 +				g = (int)((c[j] & 0x3E0)) >> 2;
   1.331 +				r = (int)((c[j] & 0x7C00)) >> 7;
   1.332 +			}
   1.333 +			const int bright = r + r + r + g + g + g + b + b;
   1.334 +			if (bright > maxBright) maxBright = bright;
   1.335 +			if (bright < minBright) minBright = bright;
   1.336 +
   1.337 +			brightArray[j] = bright;
   1.338 +		}
   1.339 +		int diffBright = ((maxBright - minBright) * 7) >> 4;
   1.340 +		if (diffBright > 7)
   1.341 +		{
   1.342 +		#define ABS(x) ((x) < 0 ? -(x) : (x))
   1.343 +
   1.344 +			const int centerBright = brightArray[4];
   1.345 +			if (ABS(brightArray[0] - centerBright) > diffBright)
   1.346 +				mask |= 1 << 0;
   1.347 +			if (ABS(brightArray[1] - centerBright) > diffBright)
   1.348 +				mask |= 1 << 1;
   1.349 +			if (ABS(brightArray[2] - centerBright) > diffBright)
   1.350 +				mask |= 1 << 2;
   1.351 +			if (ABS(brightArray[3] - centerBright) > diffBright)
   1.352 +				mask |= 1 << 3;
   1.353 +			if (ABS(brightArray[5] - centerBright) > diffBright)
   1.354 +				mask |= 1 << 4;
   1.355 +			if (ABS(brightArray[6] - centerBright) > diffBright)
   1.356 +				mask |= 1 << 5;
   1.357 +			if (ABS(brightArray[7] - centerBright) > diffBright)
   1.358 +				mask |= 1 << 6;
   1.359 +			if (ABS(brightArray[8] - centerBright) > diffBright)
   1.360 +				mask |= 1 << 7;
   1.361 +		}
   1.362 +
   1.363 +#define P0 dst0[0]
   1.364 +#define P1 dst0[1]
   1.365 +#define P2 dst1[0]
   1.366 +#define P3 dst1[1]
   1.367 +#define MUR false //(ABS(brightArray[1] - brightArray[5]) > diffBright) // top-right
   1.368 +#define MDR false //(ABS(brightArray[5] - brightArray[7]) > diffBright) // bottom-right
   1.369 +#define MDL false //(ABS(brightArray[7] - brightArray[3]) > diffBright) // bottom-left
   1.370 +#define MUL false //(ABS(brightArray[3] - brightArray[1]) > diffBright) // top-left
   1.371 +#define IC(p0) c[p0]
   1.372 +#define I11(p0, p1) interp_16_11(c[p0], c[p1])
   1.373 +#define I211(p0, p1, p2) interp_16_211(c[p0], c[p1], c[p2])
   1.374 +#define I31(p0, p1) interp_16_31(c[p0], c[p1])
   1.375 +#define I332(p0, p1, p2) interp_16_332(c[p0], c[p1], c[p2])
   1.376 +#define I431(p0, p1, p2) interp_16_431(c[p0], c[p1], c[p2])
   1.377 +#define I521(p0, p1, p2) interp_16_521(c[p0], c[p1], c[p2])
   1.378 +#define I53(p0, p1) interp_16_53(c[p0], c[p1])
   1.379 +#define I611(p0, p1, p2) interp_16_611(c[p0], c[p1], c[p2])
   1.380 +#define I71(p0, p1) interp_16_71(c[p0], c[p1])
   1.381 +#define I772(p0, p1, p2) interp_16_772(c[p0], c[p1], c[p2])
   1.382 +#define I97(p0, p1) interp_16_97(c[p0], c[p1])
   1.383 +#define I1411(p0, p1, p2) interp_16_1411(c[p0], c[p1], c[p2])
   1.384 +#define I151(p0, p1) interp_16_151(c[p0], c[p1])
   1.385 +
   1.386 +		switch (mask)
   1.387 +		{
   1.388 +#include "hq2x.h"
   1.389 +		}
   1.390 +
   1.391 +#undef P0
   1.392 +#undef P1
   1.393 +#undef P2
   1.394 +#undef P3
   1.395 +#undef MUR
   1.396 +#undef MDR
   1.397 +#undef MDL
   1.398 +#undef MUL
   1.399 +#undef IC
   1.400 +#undef I11
   1.401 +#undef I211
   1.402 +#undef I31
   1.403 +#undef I332
   1.404 +#undef I431
   1.405 +#undef I521
   1.406 +#undef I53
   1.407 +#undef I611
   1.408 +#undef I71
   1.409 +#undef I772
   1.410 +#undef I97
   1.411 +#undef I1411
   1.412 +#undef I151
   1.413 +
   1.414 +		src0 += 1;
   1.415 +		src1 += 1;
   1.416 +		src2 += 1;
   1.417 +		dst0 += 2;
   1.418 +		dst1 += 2;
   1.419 +	}
   1.420 +}
   1.421 +
   1.422 +static void hq2xS_32_def(u32 *dst0, u32 *dst1, const u32 *src0, const u32 *src1, const u32 *src2, unsigned count)
   1.423 +{
   1.424 +	unsigned i;
   1.425 +
   1.426 +	for (i = 0; i < count; ++i)
   1.427 +	{
   1.428 +		unsigned char mask;
   1.429 +
   1.430 +		u32 c[9];
   1.431 +
   1.432 +		c[1] = src0[0];
   1.433 +		c[4] = src1[0];
   1.434 +		c[7] = src2[0];
   1.435 +
   1.436 +		c[0] = src0[-1];
   1.437 +		c[3] = src1[-1];
   1.438 +		c[6] = src2[-1];
   1.439 +
   1.440 +		c[2] = src0[1];
   1.441 +		c[5] = src1[1];
   1.442 +		c[8] = src2[1];
   1.443 +
   1.444 +		mask = 0;
   1.445 +
   1.446 +		// hq2xS dynamic edge detection:
   1.447 +		// simply comparing the center color against its surroundings will give bad results in many cases,
   1.448 +		// so, instead, compare the center color relative to the max difference in brightness of this 3x3 block
   1.449 +		int brightArray[9];
   1.450 +		int maxBright = 0, minBright = 999999;
   1.451 +		for (int j = 0; j < 9; j++)
   1.452 +		{
   1.453 +			const int b		 = (int)((c[j] & 0xF8));
   1.454 +			const int g		 = (int)((c[j] & 0xF800)) >> 8;
   1.455 +			const int r		 = (int)((c[j] & 0xF80000)) >> 16;
   1.456 +			const int bright = r + r + r + g + g + g + b + b;
   1.457 +			if (bright > maxBright) maxBright = bright;
   1.458 +			if (bright < minBright) minBright = bright;
   1.459 +
   1.460 +			brightArray[j] = bright;
   1.461 +		}
   1.462 +		int diffBright = ((maxBright - minBright) * 7) >> 4;
   1.463 +		if (diffBright > 7)
   1.464 +		{
   1.465 +		#define ABS(x) ((x) < 0 ? -(x) : (x))
   1.466 +
   1.467 +			const int centerBright = brightArray[4];
   1.468 +			if (ABS(brightArray[0] - centerBright) > diffBright)
   1.469 +				mask |= 1 << 0;
   1.470 +			if (ABS(brightArray[1] - centerBright) > diffBright)
   1.471 +				mask |= 1 << 1;
   1.472 +			if (ABS(brightArray[2] - centerBright) > diffBright)
   1.473 +				mask |= 1 << 2;
   1.474 +			if (ABS(brightArray[3] - centerBright) > diffBright)
   1.475 +				mask |= 1 << 3;
   1.476 +			if (ABS(brightArray[5] - centerBright) > diffBright)
   1.477 +				mask |= 1 << 4;
   1.478 +			if (ABS(brightArray[6] - centerBright) > diffBright)
   1.479 +				mask |= 1 << 5;
   1.480 +			if (ABS(brightArray[7] - centerBright) > diffBright)
   1.481 +				mask |= 1 << 6;
   1.482 +			if (ABS(brightArray[8] - centerBright) > diffBright)
   1.483 +				mask |= 1 << 7;
   1.484 +		}
   1.485 +
   1.486 +#define P0 dst0[0]
   1.487 +#define P1 dst0[1]
   1.488 +#define P2 dst1[0]
   1.489 +#define P3 dst1[1]
   1.490 +#define MUR false //(ABS(brightArray[1] - brightArray[5]) > diffBright) // top-right
   1.491 +#define MDR false //(ABS(brightArray[5] - brightArray[7]) > diffBright) // bottom-right
   1.492 +#define MDL false //(ABS(brightArray[7] - brightArray[3]) > diffBright) // bottom-left
   1.493 +#define MUL false //(ABS(brightArray[3] - brightArray[1]) > diffBright) // top-left
   1.494 +#define IC(p0) c[p0]
   1.495 +#define I11(p0, p1) interp_32_11(c[p0], c[p1])
   1.496 +#define I211(p0, p1, p2) interp_32_211(c[p0], c[p1], c[p2])
   1.497 +#define I31(p0, p1) interp_32_31(c[p0], c[p1])
   1.498 +#define I332(p0, p1, p2) interp_32_332(c[p0], c[p1], c[p2])
   1.499 +#define I431(p0, p1, p2) interp_32_431(c[p0], c[p1], c[p2])
   1.500 +#define I521(p0, p1, p2) interp_32_521(c[p0], c[p1], c[p2])
   1.501 +#define I53(p0, p1) interp_32_53(c[p0], c[p1])
   1.502 +#define I611(p0, p1, p2) interp_32_611(c[p0], c[p1], c[p2])
   1.503 +#define I71(p0, p1) interp_32_71(c[p0], c[p1])
   1.504 +#define I772(p0, p1, p2) interp_32_772(c[p0], c[p1], c[p2])
   1.505 +#define I97(p0, p1) interp_32_97(c[p0], c[p1])
   1.506 +#define I1411(p0, p1, p2) interp_32_1411(c[p0], c[p1], c[p2])
   1.507 +#define I151(p0, p1) interp_32_151(c[p0], c[p1])
   1.508 +
   1.509 +		switch (mask)
   1.510 +		{
   1.511 +#include "hq2x.h"
   1.512 +		}
   1.513 +
   1.514 +#undef P0
   1.515 +#undef P1
   1.516 +#undef P2
   1.517 +#undef P3
   1.518 +#undef MUR
   1.519 +#undef MDR
   1.520 +#undef MDL
   1.521 +#undef MUL
   1.522 +#undef IC
   1.523 +#undef I11
   1.524 +#undef I211
   1.525 +#undef I31
   1.526 +#undef I332
   1.527 +#undef I431
   1.528 +#undef I521
   1.529 +#undef I53
   1.530 +#undef I611
   1.531 +#undef I71
   1.532 +#undef I772
   1.533 +#undef I97
   1.534 +#undef I1411
   1.535 +#undef I151
   1.536 +
   1.537 +		src0 += 1;
   1.538 +		src1 += 1;
   1.539 +		src2 += 1;
   1.540 +		dst0 += 2;
   1.541 +		dst1 += 2;
   1.542 +	}
   1.543 +}
   1.544 +
   1.545 +/***************************************************************************/
   1.546 +/* LQ2x C implementation */
   1.547 +
   1.548 +/*
   1.549 + * This effect is derived from the hq2x effect made by Maxim Stepin
   1.550 + */
   1.551 +
   1.552 +static void lq2x_16_def(u16 *dst0, u16 *dst1, const u16 *src0, const u16 *src1, const u16 *src2, unsigned count)
   1.553 +{
   1.554 +	unsigned i;
   1.555 +
   1.556 +	for (i = 0; i < count; ++i)
   1.557 +	{
   1.558 +		unsigned char mask;
   1.559 +
   1.560 +		u16 c[9];
   1.561 +
   1.562 +		c[1] = src0[0];
   1.563 +		c[4] = src1[0];
   1.564 +		c[7] = src2[0];
   1.565 +
   1.566 +		if (i > 0)
   1.567 +		{
   1.568 +			c[0] = src0[-1];
   1.569 +			c[3] = src1[-1];
   1.570 +			c[6] = src2[-1];
   1.571 +		}
   1.572 +		else
   1.573 +		{
   1.574 +			c[0] = c[1];
   1.575 +			c[3] = c[4];
   1.576 +			c[6] = c[7];
   1.577 +		}
   1.578 +
   1.579 +		if (i < count - 1)
   1.580 +		{
   1.581 +			c[2] = src0[1];
   1.582 +			c[5] = src1[1];
   1.583 +			c[8] = src2[1];
   1.584 +		}
   1.585 +		else
   1.586 +		{
   1.587 +			c[2] = c[1];
   1.588 +			c[5] = c[4];
   1.589 +			c[8] = c[7];
   1.590 +		}
   1.591 +
   1.592 +		mask = 0;
   1.593 +
   1.594 +		if (c[0] != c[4])
   1.595 +			mask |= 1 << 0;
   1.596 +		if (c[1] != c[4])
   1.597 +			mask |= 1 << 1;
   1.598 +		if (c[2] != c[4])
   1.599 +			mask |= 1 << 2;
   1.600 +		if (c[3] != c[4])
   1.601 +			mask |= 1 << 3;
   1.602 +		if (c[5] != c[4])
   1.603 +			mask |= 1 << 4;
   1.604 +		if (c[6] != c[4])
   1.605 +			mask |= 1 << 5;
   1.606 +		if (c[7] != c[4])
   1.607 +			mask |= 1 << 6;
   1.608 +		if (c[8] != c[4])
   1.609 +			mask |= 1 << 7;
   1.610 +
   1.611 +#define P0 dst0[0]
   1.612 +#define P1 dst0[1]
   1.613 +#define P2 dst1[0]
   1.614 +#define P3 dst1[1]
   1.615 +#define MUR (c[1] != c[5])
   1.616 +#define MDR (c[5] != c[7])
   1.617 +#define MDL (c[7] != c[3])
   1.618 +#define MUL (c[3] != c[1])
   1.619 +#define IC(p0) c[p0]
   1.620 +#define I11(p0, p1) interp_16_11(c[p0], c[p1])
   1.621 +#define I211(p0, p1, p2) interp_16_211(c[p0], c[p1], c[p2])
   1.622 +#define I31(p0, p1) interp_16_31(c[p0], c[p1])
   1.623 +#define I332(p0, p1, p2) interp_16_332(c[p0], c[p1], c[p2])
   1.624 +#define I431(p0, p1, p2) interp_16_431(c[p0], c[p1], c[p2])
   1.625 +#define I521(p0, p1, p2) interp_16_521(c[p0], c[p1], c[p2])
   1.626 +#define I53(p0, p1) interp_16_53(c[p0], c[p1])
   1.627 +#define I611(p0, p1, p2) interp_16_611(c[p0], c[p1], c[p2])
   1.628 +#define I71(p0, p1) interp_16_71(c[p0], c[p1])
   1.629 +#define I772(p0, p1, p2) interp_16_772(c[p0], c[p1], c[p2])
   1.630 +#define I97(p0, p1) interp_16_97(c[p0], c[p1])
   1.631 +#define I1411(p0, p1, p2) interp_16_1411(c[p0], c[p1], c[p2])
   1.632 +#define I151(p0, p1) interp_16_151(c[p0], c[p1])
   1.633 +
   1.634 +		switch (mask)
   1.635 +		{
   1.636 +#include "lq2x.h"
   1.637 +		}
   1.638 +
   1.639 +#undef P0
   1.640 +#undef P1
   1.641 +#undef P2
   1.642 +#undef P3
   1.643 +#undef MUR
   1.644 +#undef MDR
   1.645 +#undef MDL
   1.646 +#undef MUL
   1.647 +#undef IC
   1.648 +#undef I11
   1.649 +#undef I211
   1.650 +#undef I31
   1.651 +#undef I332
   1.652 +#undef I431
   1.653 +#undef I521
   1.654 +#undef I53
   1.655 +#undef I611
   1.656 +#undef I71
   1.657 +#undef I772
   1.658 +#undef I97
   1.659 +#undef I1411
   1.660 +#undef I151
   1.661 +
   1.662 +		src0 += 1;
   1.663 +		src1 += 1;
   1.664 +		src2 += 1;
   1.665 +		dst0 += 2;
   1.666 +		dst1 += 2;
   1.667 +	}
   1.668 +}
   1.669 +
   1.670 +static void lq2x_32_def(u32 *dst0, u32 *dst1, const u32 *src0, const u32 *src1, const u32 *src2, unsigned count)
   1.671 +{
   1.672 +	unsigned i;
   1.673 +
   1.674 +	for (i = 0; i < count; ++i)
   1.675 +	{
   1.676 +		unsigned char mask;
   1.677 +
   1.678 +		u32 c[9];
   1.679 +
   1.680 +		c[1] = src0[0];
   1.681 +		c[4] = src1[0];
   1.682 +		c[7] = src2[0];
   1.683 +
   1.684 +		if (i > 0)
   1.685 +		{
   1.686 +			c[0] = src0[-1];
   1.687 +			c[3] = src1[-1];
   1.688 +			c[6] = src2[-1];
   1.689 +		}
   1.690 +		else
   1.691 +		{
   1.692 +			c[0] = c[1];
   1.693 +			c[3] = c[4];
   1.694 +			c[6] = c[7];
   1.695 +		}
   1.696 +
   1.697 +		if (i < count - 1)
   1.698 +		{
   1.699 +			c[2] = src0[1];
   1.700 +			c[5] = src1[1];
   1.701 +			c[8] = src2[1];
   1.702 +		}
   1.703 +		else
   1.704 +		{
   1.705 +			c[2] = c[1];
   1.706 +			c[5] = c[4];
   1.707 +			c[8] = c[7];
   1.708 +		}
   1.709 +
   1.710 +		mask = 0;
   1.711 +
   1.712 +		if (c[0] != c[4])
   1.713 +			mask |= 1 << 0;
   1.714 +		if (c[1] != c[4])
   1.715 +			mask |= 1 << 1;
   1.716 +		if (c[2] != c[4])
   1.717 +			mask |= 1 << 2;
   1.718 +		if (c[3] != c[4])
   1.719 +			mask |= 1 << 3;
   1.720 +		if (c[5] != c[4])
   1.721 +			mask |= 1 << 4;
   1.722 +		if (c[6] != c[4])
   1.723 +			mask |= 1 << 5;
   1.724 +		if (c[7] != c[4])
   1.725 +			mask |= 1 << 6;
   1.726 +		if (c[8] != c[4])
   1.727 +			mask |= 1 << 7;
   1.728 +
   1.729 +#define P0 dst0[0]
   1.730 +#define P1 dst0[1]
   1.731 +#define P2 dst1[0]
   1.732 +#define P3 dst1[1]
   1.733 +#define MUR (c[1] != c[5])
   1.734 +#define MDR (c[5] != c[7])
   1.735 +#define MDL (c[7] != c[3])
   1.736 +#define MUL (c[3] != c[1])
   1.737 +#define IC(p0) c[p0]
   1.738 +#define I11(p0, p1) interp_32_11(c[p0], c[p1])
   1.739 +#define I211(p0, p1, p2) interp_32_211(c[p0], c[p1], c[p2])
   1.740 +#define I31(p0, p1) interp_32_31(c[p0], c[p1])
   1.741 +#define I332(p0, p1, p2) interp_32_332(c[p0], c[p1], c[p2])
   1.742 +#define I431(p0, p1, p2) interp_32_431(c[p0], c[p1], c[p2])
   1.743 +#define I521(p0, p1, p2) interp_32_521(c[p0], c[p1], c[p2])
   1.744 +#define I53(p0, p1) interp_32_53(c[p0], c[p1])
   1.745 +#define I611(p0, p1, p2) interp_32_611(c[p0], c[p1], c[p2])
   1.746 +#define I71(p0, p1) interp_32_71(c[p0], c[p1])
   1.747 +#define I772(p0, p1, p2) interp_32_772(c[p0], c[p1], c[p2])
   1.748 +#define I97(p0, p1) interp_32_97(c[p0], c[p1])
   1.749 +#define I1411(p0, p1, p2) interp_32_1411(c[p0], c[p1], c[p2])
   1.750 +#define I151(p0, p1) interp_32_151(c[p0], c[p1])
   1.751 +
   1.752 +		switch (mask)
   1.753 +		{
   1.754 +#include "lq2x.h"
   1.755 +		}
   1.756 +
   1.757 +#undef P0
   1.758 +#undef P1
   1.759 +#undef P2
   1.760 +#undef P3
   1.761 +#undef MUR
   1.762 +#undef MDR
   1.763 +#undef MDL
   1.764 +#undef MUL
   1.765 +#undef IC
   1.766 +#undef I11
   1.767 +#undef I211
   1.768 +#undef I31
   1.769 +#undef I332
   1.770 +#undef I431
   1.771 +#undef I521
   1.772 +#undef I53
   1.773 +#undef I611
   1.774 +#undef I71
   1.775 +#undef I772
   1.776 +#undef I97
   1.777 +#undef I1411
   1.778 +#undef I151
   1.779 +
   1.780 +		src0 += 1;
   1.781 +		src1 += 1;
   1.782 +		src2 += 1;
   1.783 +		dst0 += 2;
   1.784 +		dst1 += 2;
   1.785 +	}
   1.786 +}
   1.787 +
   1.788 +void hq2x(u8 *srcPtr, u32 srcPitch, u8 * /* deltaPtr */,
   1.789 +          u8 *dstPtr, u32 dstPitch, int width, int height)
   1.790 +{
   1.791 +	u16 *dst0 = (u16 *)dstPtr;
   1.792 +	u16 *dst1 = dst0 + (dstPitch >> 1);
   1.793 +
   1.794 +	u16 *src0 = (u16 *)srcPtr;
   1.795 +	u16 *src1 = src0 + (srcPitch >> 1);
   1.796 +	u16 *src2 = src1 + (srcPitch >> 1);
   1.797 +
   1.798 +	hq2x_16_def(dst0, dst1, src0, src0, src1, width);
   1.799 +
   1.800 +	int count = height;
   1.801 +
   1.802 +	count -= 2;
   1.803 +	while (count)
   1.804 +	{
   1.805 +		dst0 += dstPitch;
   1.806 +		dst1 += dstPitch;
   1.807 +		hq2x_16_def(dst0, dst1, src0, src1, src2, width);
   1.808 +		src0  = src1;
   1.809 +		src1  = src2;
   1.810 +		src2 += srcPitch >> 1;
   1.811 +		--count;
   1.812 +	}
   1.813 +	dst0 += dstPitch;
   1.814 +	dst1 += dstPitch;
   1.815 +	hq2x_16_def(dst0, dst1, src0, src1, src1, width);
   1.816 +}
   1.817 +
   1.818 +void hq2x32(u8 *srcPtr, u32 srcPitch, u8 * /* deltaPtr */,
   1.819 +            u8 *dstPtr, u32 dstPitch, int width, int height)
   1.820 +{
   1.821 +	u32 *dst0 = (u32 *)dstPtr;
   1.822 +	u32 *dst1 = dst0 + (dstPitch >> 2);
   1.823 +
   1.824 +	u32 *src0 = (u32 *)srcPtr;
   1.825 +	u32 *src1 = src0 + (srcPitch >> 2);
   1.826 +	u32 *src2 = src1 + (srcPitch >> 2);
   1.827 +	hq2x_32_def(dst0, dst1, src0, src0, src1, width);
   1.828 +
   1.829 +	int count = height;
   1.830 +
   1.831 +	count -= 2;
   1.832 +	while (count)
   1.833 +	{
   1.834 +		dst0 += dstPitch >> 1;
   1.835 +		dst1 += dstPitch >> 1;
   1.836 +		hq2x_32_def(dst0, dst1, src0, src1, src2, width);
   1.837 +		src0  = src1;
   1.838 +		src1  = src2;
   1.839 +		src2 += srcPitch >> 2;
   1.840 +		--count;
   1.841 +	}
   1.842 +	dst0 += dstPitch >> 1;
   1.843 +	dst1 += dstPitch >> 1;
   1.844 +	hq2x_32_def(dst0, dst1, src0, src1, src1, width);
   1.845 +}
   1.846 +
   1.847 +void hq2xS(u8 *srcPtr, u32 srcPitch, u8 * /* deltaPtr */,
   1.848 +           u8 *dstPtr, u32 dstPitch, int width, int height)
   1.849 +{
   1.850 +	u16 *dst0 = (u16 *)dstPtr;
   1.851 +	u16 *dst1 = dst0 + (dstPitch >> 1);
   1.852 +
   1.853 +	u16 *src0 = (u16 *)srcPtr;
   1.854 +	u16 *src1 = src0 + (srcPitch >> 1);
   1.855 +	u16 *src2 = src1 + (srcPitch >> 1);
   1.856 +
   1.857 +	hq2xS_16_def(dst0, dst1, src0, src0, src1, width);
   1.858 +
   1.859 +	int count = height;
   1.860 +
   1.861 +	count -= 2;
   1.862 +	while (count)
   1.863 +	{
   1.864 +		dst0 += dstPitch;
   1.865 +		dst1 += dstPitch;
   1.866 +		hq2xS_16_def(dst0, dst1, src0, src1, src2, width);
   1.867 +		src0  = src1;
   1.868 +		src1  = src2;
   1.869 +		src2 += srcPitch >> 1;
   1.870 +		--count;
   1.871 +	}
   1.872 +	dst0 += dstPitch;
   1.873 +	dst1 += dstPitch;
   1.874 +	hq2xS_16_def(dst0, dst1, src0, src1, src1, width);
   1.875 +}
   1.876 +
   1.877 +void hq2xS32(u8 *srcPtr, u32 srcPitch, u8 * /* deltaPtr */,
   1.878 +             u8 *dstPtr, u32 dstPitch, int width, int height)
   1.879 +{
   1.880 +	u32 *dst0 = (u32 *)dstPtr;
   1.881 +	u32 *dst1 = dst0 + (dstPitch >> 2);
   1.882 +
   1.883 +	u32 *src0 = (u32 *)srcPtr;
   1.884 +	u32 *src1 = src0 + (srcPitch >> 2);
   1.885 +	u32 *src2 = src1 + (srcPitch >> 2);
   1.886 +	hq2xS_32_def(dst0, dst1, src0, src0, src1, width);
   1.887 +
   1.888 +	int count = height;
   1.889 +
   1.890 +	count -= 2;
   1.891 +	while (count)
   1.892 +	{
   1.893 +		dst0 += dstPitch >> 1;
   1.894 +		dst1 += dstPitch >> 1;
   1.895 +		hq2xS_32_def(dst0, dst1, src0, src1, src2, width);
   1.896 +		src0  = src1;
   1.897 +		src1  = src2;
   1.898 +		src2 += srcPitch >> 2;
   1.899 +		--count;
   1.900 +	}
   1.901 +	dst0 += dstPitch >> 1;
   1.902 +	dst1 += dstPitch >> 1;
   1.903 +	hq2xS_32_def(dst0, dst1, src0, src1, src1, width);
   1.904 +}
   1.905 +
   1.906 +void lq2x(u8 *srcPtr, u32 srcPitch, u8 * /* deltaPtr */,
   1.907 +          u8 *dstPtr, u32 dstPitch, int width, int height)
   1.908 +{
   1.909 +	u16 *dst0 = (u16 *)dstPtr;
   1.910 +	u16 *dst1 = dst0 + (dstPitch >> 1);
   1.911 +
   1.912 +	u16 *src0 = (u16 *)srcPtr;
   1.913 +	u16 *src1 = src0 + (srcPitch >> 1);
   1.914 +	u16 *src2 = src1 + (srcPitch >> 1);
   1.915 +
   1.916 +	lq2x_16_def(dst0, dst1, src0, src0, src1, width);
   1.917 +
   1.918 +	int count = height;
   1.919 +
   1.920 +	count -= 2;
   1.921 +	while (count)
   1.922 +	{
   1.923 +		dst0 += dstPitch;
   1.924 +		dst1 += dstPitch;
   1.925 +		lq2x_16_def(dst0, dst1, src0, src1, src2, width);
   1.926 +		src0  = src1;
   1.927 +		src1  = src2;
   1.928 +		src2 += srcPitch >> 1;
   1.929 +		--count;
   1.930 +	}
   1.931 +	dst0 += dstPitch;
   1.932 +	dst1 += dstPitch;
   1.933 +	lq2x_16_def(dst0, dst1, src0, src1, src1, width);
   1.934 +}
   1.935 +
   1.936 +void lq2x32(u8 *srcPtr, u32 srcPitch, u8 * /* deltaPtr */,
   1.937 +            u8 *dstPtr, u32 dstPitch, int width, int height)
   1.938 +{
   1.939 +	u32 *dst0 = (u32 *)dstPtr;
   1.940 +	u32 *dst1 = dst0 + (dstPitch >> 2);
   1.941 +
   1.942 +	u32 *src0 = (u32 *)srcPtr;
   1.943 +	u32 *src1 = src0 + (srcPitch >> 2);
   1.944 +	u32 *src2 = src1 + (srcPitch >> 2);
   1.945 +	lq2x_32_def(dst0, dst1, src0, src0, src1, width);
   1.946 +
   1.947 +	int count = height;
   1.948 +
   1.949 +	count -= 2;
   1.950 +	while (count)
   1.951 +	{
   1.952 +		dst0 += dstPitch >> 1;
   1.953 +		dst1 += dstPitch >> 1;
   1.954 +		lq2x_32_def(dst0, dst1, src0, src1, src2, width);
   1.955 +		src0  = src1;
   1.956 +		src1  = src2;
   1.957 +		src2 += srcPitch >> 2;
   1.958 +		--count;
   1.959 +	}
   1.960 +	dst0 += dstPitch >> 1;
   1.961 +	dst1 += dstPitch >> 1;
   1.962 +	lq2x_32_def(dst0, dst1, src0, src1, src1, width);
   1.963 +}
   1.964 +
   1.965 +void hq2x_init(unsigned bits_per_pixel)
   1.966 +{
   1.967 +	interp_set(bits_per_pixel);
   1.968 +}
   1.969 +