annotate src/filters/hq3x32.cpp @ 513:3dbb863eb801

accuracy of displayed image is much improved, but there the palettes are still messed up.
author Robert McIntyre <rlm@mit.edu>
date Fri, 22 Jun 2012 18:58:47 -0500
parents f9f4f1b99eed
children
rev   line source
rlm@1 1 #include "../Port.h"
rlm@1 2 #include "hq_shared32.h"
rlm@1 3 #include "interp.h"
rlm@1 4
rlm@1 5 #define SIZE_PIXEL 2 // 16bit = 2 bytes
rlm@1 6 #define PIXELTYPE unsigned short
rlm@1 7 #define Interp1 Interp1_16
rlm@1 8 #define Interp2 Interp2_16
rlm@1 9 #define Interp3 Interp3_16
rlm@1 10 #define Interp4 Interp4_16
rlm@1 11 #define Interp5 Interp5_16
rlm@1 12
rlm@1 13 void hq3x(unsigned char *pIn, unsigned int srcPitch,
rlm@1 14 unsigned char *,
rlm@1 15 unsigned char *pOut, unsigned int dstPitch,
rlm@1 16 int Xres, int Yres)
rlm@1 17 {
rlm@1 18 int i, j;
rlm@1 19 unsigned int line;
rlm@1 20 PIXELTYPE c[10];
rlm@1 21
rlm@1 22 // +----+----+----+
rlm@1 23 // | | | |
rlm@1 24 // | c1 | c2 | c3 |
rlm@1 25 // +----+----+----+
rlm@1 26 // | | | |
rlm@1 27 // | c4 | c5 | c6 |
rlm@1 28 // +----+----+----+
rlm@1 29 // | | | |
rlm@1 30 // | c7 | c8 | c9 |
rlm@1 31 // +----+----+----+
rlm@1 32
rlm@1 33 for (j = 0; j < Yres; j++)
rlm@1 34 {
rlm@1 35 if ((j > 0) || (j < Yres - 1))
rlm@1 36 line = srcPitch;
rlm@1 37 else
rlm@1 38 line = 0;
rlm@1 39
rlm@1 40 for (i = 0; i < Xres; i++)
rlm@1 41 {
rlm@1 42 c[2] = *((PIXELTYPE *)(pIn - line));
rlm@1 43 c[5] = *((PIXELTYPE *)(pIn));
rlm@1 44 c[8] = *((PIXELTYPE *)(pIn + line));
rlm@1 45
rlm@1 46 if (i > 0)
rlm@1 47 {
rlm@1 48 c[1] = *((PIXELTYPE *)(pIn - line - SIZE_PIXEL));
rlm@1 49 c[4] = *((PIXELTYPE *)(pIn - SIZE_PIXEL));
rlm@1 50 c[7] = *((PIXELTYPE *)(pIn + line - SIZE_PIXEL));
rlm@1 51 }
rlm@1 52 else
rlm@1 53 {
rlm@1 54 c[1] = c[2];
rlm@1 55 c[4] = c[5];
rlm@1 56 c[7] = c[8];
rlm@1 57 }
rlm@1 58
rlm@1 59 if (i < Xres - 1)
rlm@1 60 {
rlm@1 61 c[3] = *((PIXELTYPE *)(pIn - line + SIZE_PIXEL));
rlm@1 62 c[6] = *((PIXELTYPE *)(pIn + SIZE_PIXEL));
rlm@1 63 c[9] = *((PIXELTYPE *)(pIn + line + SIZE_PIXEL));
rlm@1 64 }
rlm@1 65 else
rlm@1 66 {
rlm@1 67 c[3] = c[2];
rlm@1 68 c[6] = c[5];
rlm@1 69 c[9] = c[8];
rlm@1 70 }
rlm@1 71
rlm@1 72 int pattern = 0;
rlm@1 73
rlm@1 74 if (interp_16_diff(c[1], c[5]))
rlm@1 75 pattern |= 1 << 0;
rlm@1 76 if (interp_16_diff(c[2], c[5]))
rlm@1 77 pattern |= 1 << 1;
rlm@1 78 if (interp_16_diff(c[3], c[5]))
rlm@1 79 pattern |= 1 << 2;
rlm@1 80 if (interp_16_diff(c[4], c[5]))
rlm@1 81 pattern |= 1 << 3;
rlm@1 82 if (interp_16_diff(c[6], c[5]))
rlm@1 83 pattern |= 1 << 4;
rlm@1 84 if (interp_16_diff(c[7], c[5]))
rlm@1 85 pattern |= 1 << 5;
rlm@1 86 if (interp_16_diff(c[8], c[5]))
rlm@1 87 pattern |= 1 << 6;
rlm@1 88 if (interp_16_diff(c[9], c[5]))
rlm@1 89 pattern |= 1 << 7;
rlm@1 90
rlm@1 91 #define Diff interp_16_diff
rlm@1 92 #include "hq3x32.h"
rlm@1 93 #undef Diff
rlm@1 94 pIn += SIZE_PIXEL;
rlm@1 95 pOut += 3 << 1;
rlm@1 96 }
rlm@1 97 pIn += srcPitch - (Xres << 1);
rlm@1 98 pOut += dstPitch - (3 * Xres << 1);
rlm@1 99 pOut += dstPitch << 1;
rlm@1 100 // pIn+=SIZE_PIXEL;
rlm@1 101 // pOut+=3*SIZE_PIXEL;
rlm@1 102 //}
rlm@1 103 //pIn+=srcPitch-(4*Xres);
rlm@1 104 //pOut+=dstPitch-(3*Xres*SIZE_PIXEL);
rlm@1 105 //pOut+=2*dstPitch;
rlm@1 106 }
rlm@1 107 }
rlm@1 108
rlm@1 109 void hq3xS(unsigned char *pIn, unsigned int srcPitch,
rlm@1 110 unsigned char *,
rlm@1 111 unsigned char *pOut, unsigned int dstPitch,
rlm@1 112 int Xres, int Yres)
rlm@1 113 {
rlm@1 114 int i, j;
rlm@1 115 PIXELTYPE c[10];
rlm@1 116
rlm@1 117 // +----+----+----+
rlm@1 118 // | | | |
rlm@1 119 // | c1 | c2 | c3 |
rlm@1 120 // +----+----+----+
rlm@1 121 // | | | |
rlm@1 122 // | c4 | c5 | c6 |
rlm@1 123 // +----+----+----+
rlm@1 124 // | | | |
rlm@1 125 // | c7 | c8 | c9 |
rlm@1 126 // +----+----+----+
rlm@1 127
rlm@1 128 for (j = 0; j < Yres; j++)
rlm@1 129 {
rlm@1 130 for (i = 0; i < Xres; i++)
rlm@1 131 {
rlm@1 132 c[2] = *((PIXELTYPE *)(pIn - srcPitch));
rlm@1 133 c[5] = *((PIXELTYPE *)(pIn));
rlm@1 134 c[8] = *((PIXELTYPE *)(pIn + srcPitch));
rlm@1 135
rlm@1 136 c[1] = *((PIXELTYPE *)(pIn - srcPitch - SIZE_PIXEL));
rlm@1 137 c[4] = *((PIXELTYPE *)(pIn - SIZE_PIXEL));
rlm@1 138 c[7] = *((PIXELTYPE *)(pIn + srcPitch - SIZE_PIXEL));
rlm@1 139
rlm@1 140 c[3] = *((PIXELTYPE *)(pIn - srcPitch + SIZE_PIXEL));
rlm@1 141 c[6] = *((PIXELTYPE *)(pIn + SIZE_PIXEL));
rlm@1 142 c[9] = *((PIXELTYPE *)(pIn + srcPitch + SIZE_PIXEL));
rlm@1 143
rlm@1 144 int pattern = 0;
rlm@1 145
rlm@1 146 // hq3xS dynamic edge detection:
rlm@1 147 // simply comparing the center color against its surroundings will give bad results in many cases,
rlm@1 148 // so, instead, compare the center color relative to the max difference in brightness of this 3x3 block
rlm@1 149 int brightArray[10];
rlm@1 150 int maxBright = 0, minBright = 999999;
rlm@1 151 for (int j = 1; j < 10; j++)
rlm@1 152 {
rlm@1 153 int r, g, b;
rlm@1 154 if (interp_bits_per_pixel == 16)
rlm@1 155 {
rlm@1 156 b = (int)((c[j] & 0x1F)) << 3;
rlm@1 157 g = (int)((c[j] & 0x7E0)) >> 3;
rlm@1 158 r = (int)((c[j] & 0xF800)) >> 8;
rlm@1 159 }
rlm@1 160 else
rlm@1 161 {
rlm@1 162 b = (int)((c[j] & 0x1F)) << 3;
rlm@1 163 g = (int)((c[j] & 0x3E0)) >> 2;
rlm@1 164 r = (int)((c[j] & 0x7C00)) >> 7;
rlm@1 165 }
rlm@1 166 const int bright = r + r + r + g + g + g + b + b;
rlm@1 167 if (bright > maxBright) maxBright = bright;
rlm@1 168 if (bright < minBright) minBright = bright;
rlm@1 169
rlm@1 170 brightArray[j] = bright;
rlm@1 171 }
rlm@1 172 const int diffBright = ((maxBright - minBright) * 7) >> 4;
rlm@1 173 if (diffBright > 7)
rlm@1 174 {
rlm@1 175 #define ABS(x) ((x) < 0 ? -(x) : (x))
rlm@1 176
rlm@1 177 const int centerBright = brightArray[5];
rlm@1 178 if (ABS(brightArray[1] - centerBright) > diffBright)
rlm@1 179 pattern |= 1 << 0;
rlm@1 180 if (ABS(brightArray[2] - centerBright) > diffBright)
rlm@1 181 pattern |= 1 << 1;
rlm@1 182 if (ABS(brightArray[3] - centerBright) > diffBright)
rlm@1 183 pattern |= 1 << 2;
rlm@1 184 if (ABS(brightArray[4] - centerBright) > diffBright)
rlm@1 185 pattern |= 1 << 3;
rlm@1 186 if (ABS(brightArray[6] - centerBright) > diffBright)
rlm@1 187 pattern |= 1 << 4;
rlm@1 188 if (ABS(brightArray[7] - centerBright) > diffBright)
rlm@1 189 pattern |= 1 << 5;
rlm@1 190 if (ABS(brightArray[8] - centerBright) > diffBright)
rlm@1 191 pattern |= 1 << 6;
rlm@1 192 if (ABS(brightArray[9] - centerBright) > diffBright)
rlm@1 193 pattern |= 1 << 7;
rlm@1 194 }
rlm@1 195
rlm@1 196 #define Diff(x, y) false //(ABS((x) - (y)) > diffBright)
rlm@1 197 #undef cget
rlm@1 198 #define cget(x) brightArray[x]
rlm@1 199 #include "hq3x32.h"
rlm@1 200 #undef cget
rlm@1 201 #undef Diff
rlm@1 202 pIn += SIZE_PIXEL;
rlm@1 203 pOut += 3 << 1;
rlm@1 204 }
rlm@1 205 pIn += srcPitch - (Xres << 1);
rlm@1 206 pOut += dstPitch - (3 * Xres << 1);
rlm@1 207 pOut += dstPitch << 1;
rlm@1 208 // pIn+=SIZE_PIXEL;
rlm@1 209 // pOut+=3*SIZE_PIXEL;
rlm@1 210 //}
rlm@1 211 //pIn+=srcPitch-(4*Xres);
rlm@1 212 //pOut+=dstPitch-(3*Xres*SIZE_PIXEL);
rlm@1 213 //pOut+=2*dstPitch;
rlm@1 214 }
rlm@1 215 }
rlm@1 216
rlm@1 217 #undef Interp1
rlm@1 218 #undef Interp2
rlm@1 219 #undef Interp3
rlm@1 220 #undef Interp4
rlm@1 221 #undef Interp5
rlm@1 222 #undef SIZE_PIXEL
rlm@1 223 #undef PIXELTYPE
rlm@1 224 #define SIZE_PIXEL 4 // 32bit = 4 bytes
rlm@1 225 #define PIXELTYPE unsigned int
rlm@1 226
rlm@1 227 void hq3x32(unsigned char *pIn, unsigned int srcPitch,
rlm@1 228 unsigned char *,
rlm@1 229 unsigned char *pOut, unsigned int dstPitch,
rlm@1 230 int Xres, int Yres)
rlm@1 231 {
rlm@1 232 unsigned int YUV1, YUV2;
rlm@1 233 int i, j, k;
rlm@1 234 unsigned int line;
rlm@1 235 PIXELTYPE c[10];
rlm@1 236
rlm@1 237 // +----+----+----+
rlm@1 238 // | | | |
rlm@1 239 // | c1 | c2 | c3 |
rlm@1 240 // +----+----+----+
rlm@1 241 // | | | |
rlm@1 242 // | c4 | c5 | c6 |
rlm@1 243 // +----+----+----+
rlm@1 244 // | | | |
rlm@1 245 // | c7 | c8 | c9 |
rlm@1 246 // +----+----+----+
rlm@1 247
rlm@1 248 for (j = 0; j < Yres; j++)
rlm@1 249 {
rlm@1 250 if ((j > 0) && (j < Yres - 1))
rlm@1 251 line = srcPitch;
rlm@1 252 else
rlm@1 253 line = 0;
rlm@1 254
rlm@1 255 for (i = 0; i < Xres; i++)
rlm@1 256 {
rlm@1 257 c[2] = *((PIXELTYPE *)(pIn - line));
rlm@1 258 c[5] = *((PIXELTYPE *)(pIn));
rlm@1 259 c[8] = *((PIXELTYPE *)(pIn + line));
rlm@1 260
rlm@1 261 if (i > 0)
rlm@1 262 {
rlm@1 263 c[1] = *((PIXELTYPE *)(pIn - line - SIZE_PIXEL));
rlm@1 264 c[4] = *((PIXELTYPE *)(pIn - SIZE_PIXEL));
rlm@1 265 c[7] = *((PIXELTYPE *)(pIn + line - SIZE_PIXEL));
rlm@1 266 }
rlm@1 267 else
rlm@1 268 {
rlm@1 269 c[1] = c[2];
rlm@1 270 c[4] = c[5];
rlm@1 271 c[7] = c[8];
rlm@1 272 }
rlm@1 273
rlm@1 274 if (i < Xres - 1)
rlm@1 275 {
rlm@1 276 c[3] = *((PIXELTYPE *)(pIn - line + SIZE_PIXEL));
rlm@1 277 c[6] = *((PIXELTYPE *)(pIn + SIZE_PIXEL));
rlm@1 278 c[9] = *((PIXELTYPE *)(pIn + line + SIZE_PIXEL));
rlm@1 279 }
rlm@1 280 else
rlm@1 281 {
rlm@1 282 c[3] = c[2];
rlm@1 283 c[6] = c[5];
rlm@1 284 c[9] = c[8];
rlm@1 285 }
rlm@1 286
rlm@1 287 int pattern = 0;
rlm@1 288 int flag = 1;
rlm@1 289
rlm@1 290 YUV1 = RGBtoYUV(c[5]);
rlm@1 291
rlm@1 292 for (k = 1; k <= 9; k++)
rlm@1 293 {
rlm@1 294 if (k == 5) continue;
rlm@1 295
rlm@1 296 if (c[k] != c[5])
rlm@1 297 {
rlm@1 298 YUV2 = RGBtoYUV(c[k]);
rlm@1 299 if (
rlm@1 300 (abs32((YUV1 & Ymask) - (YUV2 & Ymask)) > trY) ||
rlm@1 301 (abs32((YUV1 & Umask) - (YUV2 & Umask)) > trU) ||
rlm@1 302 (abs32((YUV1 & Vmask) - (YUV2 & Vmask)) > trV)
rlm@1 303 )
rlm@1 304 pattern |= flag;
rlm@1 305 }
rlm@1 306 flag <<= 1;
rlm@1 307 }
rlm@1 308
rlm@1 309 #include "hq3x32.h"
rlm@1 310 pIn += SIZE_PIXEL;
rlm@1 311 pOut += 3 << 2;
rlm@1 312 }
rlm@1 313 pIn += srcPitch - (Xres << 2);
rlm@1 314 pOut += dstPitch - (3 * Xres << 2);
rlm@1 315 pOut += dstPitch << 1;
rlm@1 316 // pIn+=SIZE_PIXEL;
rlm@1 317 // pOut+=3*SIZE_PIXEL;
rlm@1 318 //}
rlm@1 319 //pIn+=srcPitch-(4*Xres);
rlm@1 320 //pOut+=dstPitch-(3*Xres*SIZE_PIXEL);
rlm@1 321 //pOut+=2*dstPitch;
rlm@1 322 }
rlm@1 323 }
rlm@1 324
rlm@1 325 void hq3xS32(unsigned char *pIn, unsigned int srcPitch,
rlm@1 326 unsigned char *,
rlm@1 327 unsigned char *pOut, unsigned int dstPitch,
rlm@1 328 int Xres, int Yres)
rlm@1 329 {
rlm@1 330 int i, j;
rlm@1 331 unsigned int line;
rlm@1 332 PIXELTYPE c[10];
rlm@1 333
rlm@1 334 // +----+----+----+
rlm@1 335 // | | | |
rlm@1 336 // | c1 | c2 | c3 |
rlm@1 337 // +----+----+----+
rlm@1 338 // | | | |
rlm@1 339 // | c4 | c5 | c6 |
rlm@1 340 // +----+----+----+
rlm@1 341 // | | | |
rlm@1 342 // | c7 | c8 | c9 |
rlm@1 343 // +----+----+----+
rlm@1 344
rlm@1 345 for (j = 0; j < Yres; j++)
rlm@1 346 {
rlm@1 347 if ((j > 0) && (j < Yres - 1))
rlm@1 348 line = srcPitch;
rlm@1 349 else
rlm@1 350 line = 0;
rlm@1 351
rlm@1 352 for (i = 0; i < Xres; i++)
rlm@1 353 {
rlm@1 354 c[2] = *((PIXELTYPE *)(pIn - line));
rlm@1 355 c[5] = *((PIXELTYPE *)(pIn));
rlm@1 356 c[8] = *((PIXELTYPE *)(pIn + line));
rlm@1 357
rlm@1 358 if (i > 0)
rlm@1 359 {
rlm@1 360 c[1] = *((PIXELTYPE *)(pIn - line - SIZE_PIXEL));
rlm@1 361 c[4] = *((PIXELTYPE *)(pIn - SIZE_PIXEL));
rlm@1 362 c[7] = *((PIXELTYPE *)(pIn + line - SIZE_PIXEL));
rlm@1 363 }
rlm@1 364 else
rlm@1 365 {
rlm@1 366 c[1] = c[2];
rlm@1 367 c[4] = c[5];
rlm@1 368 c[7] = c[8];
rlm@1 369 }
rlm@1 370
rlm@1 371 if (i < Xres - 1)
rlm@1 372 {
rlm@1 373 c[3] = *((PIXELTYPE *)(pIn - line + SIZE_PIXEL));
rlm@1 374 c[6] = *((PIXELTYPE *)(pIn + SIZE_PIXEL));
rlm@1 375 c[9] = *((PIXELTYPE *)(pIn + line + SIZE_PIXEL));
rlm@1 376 }
rlm@1 377 else
rlm@1 378 {
rlm@1 379 c[3] = c[2];
rlm@1 380 c[6] = c[5];
rlm@1 381 c[9] = c[8];
rlm@1 382 }
rlm@1 383
rlm@1 384 int pattern = 0;
rlm@1 385
rlm@1 386 // hq3xS dynamic edge detection:
rlm@1 387 // simply comparing the center color against its surroundings will give bad results in many cases,
rlm@1 388 // so, instead, compare the center color relative to the max difference in brightness of this 3x3 block
rlm@1 389 int brightArray[10];
rlm@1 390 int maxBright = 0, minBright = 999999;
rlm@1 391 for (int j = 1; j < 10; j++)
rlm@1 392 {
rlm@1 393 const int b = (int)((c[j] & 0xF8));
rlm@1 394 const int g = (int)((c[j] & 0xF800)) >> 8;
rlm@1 395 const int r = (int)((c[j] & 0xF80000)) >> 16;
rlm@1 396 const int bright = r + r + r + g + g + g + b + b;
rlm@1 397 if (bright > maxBright) maxBright = bright;
rlm@1 398 if (bright < minBright) minBright = bright;
rlm@1 399
rlm@1 400 brightArray[j] = bright;
rlm@1 401 }
rlm@1 402 int diffBright = ((maxBright - minBright) * 7) >> 4;
rlm@1 403 if (diffBright > 7)
rlm@1 404 {
rlm@1 405 #define ABS(x) ((x) < 0 ? -(x) : (x))
rlm@1 406
rlm@1 407 const int centerBright = brightArray[5];
rlm@1 408 if (ABS(brightArray[1] - centerBright) > diffBright)
rlm@1 409 pattern |= 1 << 0;
rlm@1 410 if (ABS(brightArray[2] - centerBright) > diffBright)
rlm@1 411 pattern |= 1 << 1;
rlm@1 412 if (ABS(brightArray[3] - centerBright) > diffBright)
rlm@1 413 pattern |= 1 << 2;
rlm@1 414 if (ABS(brightArray[4] - centerBright) > diffBright)
rlm@1 415 pattern |= 1 << 3;
rlm@1 416 if (ABS(brightArray[6] - centerBright) > diffBright)
rlm@1 417 pattern |= 1 << 4;
rlm@1 418 if (ABS(brightArray[7] - centerBright) > diffBright)
rlm@1 419 pattern |= 1 << 5;
rlm@1 420 if (ABS(brightArray[8] - centerBright) > diffBright)
rlm@1 421 pattern |= 1 << 6;
rlm@1 422 if (ABS(brightArray[9] - centerBright) > diffBright)
rlm@1 423 pattern |= 1 << 7;
rlm@1 424 }
rlm@1 425
rlm@1 426 #define Diff(x, y) false //(ABS((x) - (y)) > diffBright)
rlm@1 427 #undef cget
rlm@1 428 #define cget(x) brightArray[x]
rlm@1 429 #include "hq3x32.h"
rlm@1 430 #undef cget
rlm@1 431 #undef Diff
rlm@1 432 pIn += SIZE_PIXEL;
rlm@1 433 pOut += 3 << 2;
rlm@1 434 }
rlm@1 435 pIn += srcPitch - (Xres << 2);
rlm@1 436 pOut += dstPitch - (3 * Xres << 2);
rlm@1 437 pOut += dstPitch << 1;
rlm@1 438 // pIn+=SIZE_PIXEL;
rlm@1 439 // pOut+=3*SIZE_PIXEL;
rlm@1 440 //}
rlm@1 441 //pIn+=srcPitch-(4*Xres);
rlm@1 442 //pOut+=dstPitch-(3*Xres*SIZE_PIXEL);
rlm@1 443 //pOut+=2*dstPitch;
rlm@1 444 }
rlm@1 445 }