1 // license:BSD-3-Clause 2 // copyright-holders:Ryan Holtz 3 #if 0 4 static inline void video_filter16(int *out_r, int *out_g, int *out_b, uint16_t* vbuff, uint8_t* hbuff, const uint32_t hres); 5 static inline void divot_filter16(uint8_t* r, uint8_t* g, uint8_t* b, uint16_t* fbuff, uint32_t fbuff_index); 6 static inline void restore_filter16(int32_t* r, int32_t* g, int32_t* b, uint16_t* fbuff, uint32_t fbuff_index, uint32_t hres); 7 static inline void divot_filter16_buffer(int32_t* r, int32_t* g, int32_t* b, color_t* vibuffer); 8 static inline void restore_filter16_buffer(int32_t* r, int32_t* g, int32_t* b, color_t* vibuff, uint32_t hres); 9 static inline void restore_two(color_t* filtered, color_t* neighbour); 10 static inline void video_max(uint32_t* Pixels, uint8_t* max, uint32_t* enb); 11 static inline uint32_t ge_two(uint32_t enb); 12 13 static inline void video_filter16(int *out_r, int *out_g, int *out_b, uint16_t* vbuff, uint8_t* hbuff, const uint32_t hres) 14 { 15 color_t penumax, penumin, max, min; 16 uint16_t pix = *vbuff; 17 const uint8_t centercvg = (*hbuff & 3) + ((pix & 1) << 2) + 1; 18 uint32_t numoffull = 1; 19 uint32_t cvg; 20 uint32_t backr[7], backg[7], backb[7]; 21 uint32_t invr[7], invg[7], invb[7]; 22 int32_t coeff; 23 int32_t leftup = -hres - 2; 24 int32_t leftdown = hres - 2; 25 int32_t toleft = -2; 26 uint32_t colr, colg, colb; 27 uint32_t enb; 28 uint32_t r = ((pix >> 8) & 0xf8) | (pix >> 13); 29 uint32_t g = ((pix >> 3) & 0xf8) | ((pix >> 8) & 0x07); 30 uint32_t b = ((pix << 2) & 0xf8) | ((pix >> 3) & 0x07); 31 32 *out_r = *out_g = *out_b = 0; 33 34 backr[0] = r; 35 backg[0] = g; 36 backb[0] = b; 37 invr[0] = ~r; 38 invg[0] = ~g; 39 invb[0] = ~b; 40 41 if (centercvg == 8) 42 { 43 *out_r = r; 44 *out_g = g; 45 *out_b = b; 46 return; 47 } 48 49 for(int i = 0; i < 5; i++) 50 { 51 pix = vbuff[leftup ^ WORD_ADDR_XOR]; 52 cvg = hbuff[leftup ^ BYTE_ADDR_XOR] & 3; 53 if(i & 1) 54 { 55 if (cvg == 3 && (pix & 1)) 56 { 57 backr[numoffull] = ((pix >> 8) & 0xf8) | (pix >> 13); 58 backg[numoffull] = ((pix >> 3) & 0xf8) | ((pix >> 8) & 0x07); 59 backb[numoffull] = ((pix << 2) & 0xf8) | ((pix >> 3) & 0x07); 60 invr[numoffull] = ~backr[numoffull]; 61 invg[numoffull] = ~backg[numoffull]; 62 invb[numoffull] = ~backb[numoffull]; 63 } 64 else 65 { 66 backr[numoffull] = invr[numoffull] = 0; 67 backg[numoffull] = invg[numoffull] = 0; 68 backb[numoffull] = invb[numoffull] = 0; 69 } 70 numoffull++; 71 } 72 leftup++; 73 } 74 75 for(int i = 0; i < 5; i++) 76 { 77 pix = vbuff[leftdown ^ WORD_ADDR_XOR]; 78 cvg = hbuff[leftdown ^ BYTE_ADDR_XOR] & 3; 79 if (i&1) 80 { 81 if (cvg == 3 && (pix & 1)) 82 { 83 backr[numoffull] = ((pix >> 8) & 0xf8) | (pix >> 13); 84 backg[numoffull] = ((pix >> 3) & 0xf8) | ((pix >> 8) & 0x07); 85 backb[numoffull] = ((pix << 2) & 0xf8) | ((pix >> 3) & 0x07); 86 invr[numoffull] = ~backr[numoffull]; 87 invg[numoffull] = ~backg[numoffull]; 88 invb[numoffull] = ~backb[numoffull]; 89 } 90 else 91 { 92 backr[numoffull] = invr[numoffull] = 0; 93 backg[numoffull] = invg[numoffull] = 0; 94 backb[numoffull] = invb[numoffull] = 0; 95 } 96 numoffull++; 97 } 98 leftdown++; 99 } 100 101 for(int i = 0; i < 5; i++) 102 { 103 pix = vbuff[toleft ^ WORD_ADDR_XOR]; 104 cvg = hbuff[toleft ^ BYTE_ADDR_XOR] & 3; 105 if (!(i&3)) 106 { 107 if (cvg == 3 && (pix & 1)) 108 { 109 backr[numoffull] = ((pix >> 8) & 0xf8) | (pix >> 13); 110 backg[numoffull] = ((pix >> 3) & 0xf8) | ((pix >> 8) & 0x07); 111 backb[numoffull] = ((pix << 2) & 0xf8) | ((pix >> 3) & 0x07); 112 invr[numoffull] = ~backr[numoffull]; 113 invg[numoffull] = ~backg[numoffull]; 114 invb[numoffull] = ~backb[numoffull]; 115 } 116 else 117 { 118 backr[numoffull] = invr[numoffull] = 0; 119 backg[numoffull] = invg[numoffull] = 0; 120 backb[numoffull] = invb[numoffull] = 0; 121 } 122 numoffull++; 123 } 124 toleft++; 125 } 126 127 video_max(&backr[0], &max.i.r, &enb); 128 for(int i = 1; i < 7; i++) 129 { 130 if (!((enb >> i) & 1)) 131 { 132 backr[i] = 0; 133 } 134 } 135 video_max(&backg[0], &max.i.g, &enb); 136 for (int i = 1; i < 7; i++) 137 { 138 if (!((enb >> i) & 1)) 139 { 140 backg[i] = 0; 141 } 142 } 143 video_max(&backb[0], &max.i.b, &enb); 144 for (int i = 1; i < 7; i++) 145 { 146 if (!((enb >> i) & 1)) 147 { 148 backb[i] = 0; 149 } 150 } 151 video_max(&invr[0], &min.i.r, &enb); 152 for (int i = 1; i < 7; i++) 153 { 154 if (!((enb >> i) & 1)) 155 { 156 backr[i] = 0; 157 } 158 } 159 video_max(&invg[0], &min.i.g, &enb); 160 for (int i = 1; i < 7; i++) 161 { 162 if (!((enb >> i) & 1)) 163 { 164 backg[i] = 0; 165 } 166 } 167 video_max(&invb[0], &min.i.b, &enb); 168 for (int i = 1; i < 7; i++) 169 { 170 if (!((enb >> i) & 1)) 171 { 172 backb[i] = 0; 173 } 174 } 175 176 video_max(&backr[0], &penumax.i.r, &enb); 177 penumax.i.r = ge_two(enb) ? max.i.r : penumax.i.r; 178 179 video_max(&backg[0], &penumax.i.g, &enb); 180 penumax.i.g = ge_two(enb) ? max.i.g : penumax.i.g; 181 182 video_max(&backb[0], &penumax.i.b, &enb); 183 penumax.i.b = ge_two(enb) ? max.i.b : penumax.i.b; 184 185 video_max(&invr[0], &penumin.i.r, &enb); 186 penumin.i.r = ge_two(enb) ? min.i.r : penumin.i.r; 187 188 video_max(&invg[0], &penumin.i.g, &enb); 189 penumin.i.g = ge_two(enb) ? min.i.g : penumin.i.g; 190 191 video_max(&invb[0], &penumin.i.b, &enb); 192 penumin.i.b = ge_two(enb) ? min.i.b : penumin.i.b; 193 194 penumin.i.r = ~penumin.i.r; 195 penumin.i.g = ~penumin.i.g; 196 penumin.i.b = ~penumin.i.b; 197 198 colr = (uint32_t)penumin.i.r + (uint32_t)penumax.i.r - (r << 1); 199 colg = (uint32_t)penumin.i.g + (uint32_t)penumax.i.g - (g << 1); 200 colb = (uint32_t)penumin.i.b + (uint32_t)penumax.i.b - (b << 1); 201 coeff = 8 - centercvg; 202 colr = (((colr * coeff) + 4) >> 3) + r; 203 colg = (((colg * coeff) + 4) >> 3) + g; 204 colb = (((colb * coeff) + 4) >> 3) + b; 205 206 *out_r = colr & 0xff; 207 *out_g = colg & 0xff; 208 *out_b = colb & 0xff; 209 return; 210 } 211 212 // This needs to be fixed for endianness. 213 static inline void divot_filter16(uint8_t* r, uint8_t* g, uint8_t* b, uint16_t* fbuff, uint32_t fbuff_index) 214 { 215 uint8_t leftr, leftg, leftb, rightr, rightg, rightb; 216 uint16_t leftpix, rightpix; 217 uint16_t* next, *prev; 218 uint32_t Lsw = fbuff_index & 1; 219 next = (Lsw) ? (uint16_t*)(fbuff - 1) : (uint16_t*)(fbuff + 3); 220 prev = (Lsw) ? (uint16_t*)(fbuff - 3) : (uint16_t*)(fbuff + 1); 221 leftpix = *prev; 222 rightpix = *next; 223 224 //leftpix = *(fbuff - 1); //for BE targets 225 //rightpix = *(fbuff + 1); 226 227 leftr = ((leftpix >> 8) & 0xf8) | (leftpix >> 13); 228 leftg = ((leftpix >> 3) & 0xf8) | ((leftpix >> 8) & 0x07); 229 leftb = ((leftpix << 2) & 0xf8) | ((leftpix >> 3) & 0x07); 230 rightr = ((rightpix >> 8) & 0xf8) | (rightpix >> 13); 231 rightg = ((rightpix >> 3) & 0xf8) | ((rightpix >> 8) & 0x07); 232 rightb = ((rightpix << 2) & 0xf8) | ((rightpix >> 3) & 0x07); 233 if ((leftr >= *r && rightr >= leftr) || (leftr >= rightr && *r >= leftr)) 234 { 235 *r = leftr; //left = median value 236 } 237 if ((rightr >= *r && leftr >= rightr) || (rightr >= leftr && *r >= rightr)) 238 { 239 *r = rightr; //right = median, else *r itself is median 240 } 241 if ((leftg >= *g && rightg >= leftg) || (leftg >= rightg && *g >= leftg)) 242 { 243 *g = leftg; 244 } 245 if ((rightg >= *g && leftg >= rightg) || (rightg >= leftg && *g >= rightg)) 246 { 247 *g = rightg; 248 } 249 if ((leftb >= *b && rightb >= leftb) || (leftb >= rightb && *b >= leftb)) 250 { 251 *b = leftb; 252 } 253 if ((rightb >= *b && leftb >= rightb) || (rightb >= leftb && *b >= rightb)) 254 { 255 *b = rightb; 256 } 257 } 258 259 static inline void divot_filter16_buffer(int* r, int* g, int* b, color_t* vibuffer) 260 { 261 color_t leftpix = vibuffer[-1]; 262 color_t rightpix = vibuffer[1]; 263 color_t filtered = *vibuffer; 264 265 *r = filtered.i.r; 266 *g = filtered.i.g; 267 *b = filtered.i.b; 268 uint32_t leftr = leftpix.i.r; 269 uint32_t leftg = leftpix.i.g; 270 uint32_t leftb = leftpix.i.b; 271 uint32_t rightr = rightpix.i.r; 272 uint32_t rightg = rightpix.i.g; 273 uint32_t rightb = rightpix.i.b; 274 275 if ((leftr >= *r && rightr >= leftr) || (leftr >= rightr && *r >= leftr)) 276 { 277 *r = leftr; //left = median value 278 } 279 if ((rightr >= *r && leftr >= rightr) || (rightr >= leftr && *r >= rightr)) 280 { 281 *r = rightr; //right = median, else *r itself is median 282 } 283 if ((leftg >= *g && rightg >= leftg) || (leftg >= rightg && *g >= leftg)) 284 { 285 *g = leftg; 286 } 287 if ((rightg >= *g && leftg >= rightg) || (rightg >= leftg && *g >= rightg)) 288 { 289 *g = rightg; 290 } 291 if ((leftb >= *b && rightb >= leftb) || (leftb >= rightb && *b >= leftb)) 292 { 293 *b = leftb; 294 } 295 if ((rightb >= *b && leftb >= rightb) || (rightb >= leftb && *b >= rightb)) 296 { 297 *b = rightb; 298 } 299 300 filtered.i.r = *r; 301 filtered.i.g = *g; 302 filtered.i.b = *b; 303 } 304 305 // Fix me. 306 static inline void restore_filter16(int* r, int* g, int* b, uint16_t* fbuff, uint32_t fbuff_index, uint32_t hres) 307 { 308 int32_t leftuppix = -hres - 1; 309 int32_t leftdownpix = hres - 1; 310 int32_t toleftpix = -1; 311 uint8_t tempr, tempg, tempb; 312 uint16_t pix; 313 int i; 314 315 uint8_t r5 = *r; 316 uint8_t g5 = *g; 317 uint8_t b5 = *b; 318 r5 &= ~7; 319 g5 &= ~7; 320 b5 &= ~7; 321 322 for (i = 0; i < 3; i++) 323 { 324 pix = fbuff[leftuppix ^ 1]; 325 tempr = ((pix >> 8) & 0xf8) | (pix >> 13); 326 tempg = ((pix >> 3) & 0xf8) | ((pix >> 8) & 0x07); 327 tempb = ((pix << 2) & 0xf8) | ((pix >> 3) & 0x07); 328 tempr &= ~7; 329 tempg &= ~7; 330 tempb &= ~7; 331 if (tempr > r5) 332 { 333 *r += 1; 334 } 335 if (tempr < r5) 336 { 337 *r -= 1; 338 } 339 if (tempg > g5) 340 { 341 *g += 1; 342 } 343 if (tempg < g5) 344 { 345 *g -= 1; 346 } 347 if (tempb > b5) 348 { 349 *b += 1; 350 } 351 if (tempb < b5) 352 { 353 *b -= 1; 354 } 355 leftuppix++; 356 } 357 358 for (i = 0; i < 3; i++) 359 { 360 pix = fbuff[leftdownpix ^ 1]; 361 tempr = ((pix >> 8) & 0xf8) | (pix >> 13); 362 tempg = ((pix >> 3) & 0xf8) | ((pix >> 8) & 0x07); 363 tempb = ((pix << 2) & 0xf8) | ((pix >> 3) & 0x07); 364 tempr &= ~7; 365 tempg &= ~7; 366 tempb &= ~7; 367 if (tempr > r5) 368 { 369 *r += 1; 370 } 371 if (tempr < r5) 372 { 373 *r -= 1; 374 } 375 if (tempg > g5) 376 { 377 *g += 1; 378 } 379 if (tempg < g5) 380 { 381 *g -= 1; 382 } 383 if (tempb > b5) 384 { 385 *b += 1; 386 } 387 if (tempb < b5) 388 { 389 *b -= 1; 390 } 391 leftdownpix++; 392 } 393 for(i = 0; i < 3; i++) 394 { 395 if (!(i & 1)) 396 { 397 pix = fbuff[toleftpix ^ 1]; 398 tempr = ((pix >> 8) & 0xf8) | (pix >> 13); 399 tempg = ((pix >> 3) & 0xf8) | ((pix >> 8) & 0x07); 400 tempb = ((pix << 2) & 0xf8) | ((pix >> 3) & 0x07); 401 tempr &= ~7; 402 tempg &= ~7; 403 tempb &= ~7; 404 if (tempr > r5) 405 { 406 *r += 1; 407 } 408 if (tempr < r5) 409 { 410 *r -= 1; 411 } 412 if (tempg > g5) 413 { 414 *g += 1; 415 } 416 if (tempg < g5) 417 { 418 *g -= 1; 419 } 420 if (tempb > b5) 421 { 422 *b += 1; 423 } 424 if (tempb < b5) 425 { 426 *b -= 1; 427 } 428 } 429 toleftpix++; 430 } 431 } 432 433 static inline void restore_filter16_buffer(int32_t* r, int32_t* g, int32_t* b, color_t* vibuff, uint32_t hres) 434 { 435 color_t filtered; 436 color_t leftuppix, leftdownpix, leftpix; 437 color_t rightuppix, rightdownpix, rightpix; 438 color_t uppix, downpix; 439 int32_t ihres = (int32_t)hres; //can't apply unary minus to unsigned 440 441 leftuppix = vibuff[-ihres - 1]; 442 leftdownpix = vibuff[ihres - 1]; 443 leftpix = vibuff[-1]; 444 445 rightuppix = vibuff[-ihres + 1]; 446 rightdownpix = vibuff[ihres + 1]; 447 rightpix = vibuff[1]; 448 449 uppix = vibuff[-ihres]; 450 downpix = vibuff[ihres]; 451 filtered = *vibuff; 452 453 restore_two(&filtered, &leftuppix); 454 restore_two(&filtered, &uppix); 455 restore_two(&filtered, &rightuppix); 456 457 restore_two(&filtered, &leftpix); 458 restore_two(&filtered, &rightpix); 459 460 restore_two(&filtered, &leftdownpix); 461 restore_two(&filtered, &downpix); 462 restore_two(&filtered, &rightdownpix); 463 464 *r = filtered.i.r; 465 *g = filtered.i.g; 466 *b = filtered.i.b; 467 468 if(*r < 0) *r = 0; 469 else if(*r > 255) *r = 255; 470 if(*g < 0) *g = 0; 471 else if(*g > 255) *g = 255; 472 if(*b < 0) *b = 0; 473 else if(*b > 255) *b = 255; 474 } 475 476 // This is wrong, only the 5 upper bits are compared. 477 static inline void restore_two(color_t* filtered, color_t* neighbour) 478 { 479 if (neighbour->i.r > filtered->i.r) 480 { 481 filtered->i.r += 1; 482 } 483 if (neighbour->i.r < filtered->i.r) 484 { 485 filtered->i.r -= 1; 486 } 487 if (neighbour->i.g > filtered->i.g) 488 { 489 filtered->i.g += 1; 490 } 491 if (neighbour->i.g < filtered->i.g) 492 { 493 filtered->i.g -= 1; 494 } 495 if (neighbour->i.b > filtered->i.b) 496 { 497 filtered->i.b += 1; 498 } 499 if (neighbour->i.b < filtered->i.b) 500 { 501 filtered->i.b -= 1; 502 } 503 } 504 505 static inline void video_max(uint32_t* Pixels, uint8_t* max, uint32_t* enb) 506 { 507 int i; 508 int pos = 0; 509 *enb = 0; 510 for(i = 0; i < 7; i++) 511 { 512 if (Pixels[i] > Pixels[pos]) 513 { 514 *enb += (1 << i); 515 pos = i; 516 } 517 else if (Pixels[i] < Pixels[pos]) 518 { 519 *enb += (1 << i); 520 } 521 else 522 { 523 pos = i; 524 } 525 } 526 *max = Pixels[pos]; 527 } 528 529 static inline uint32_t ge_two(uint32_t enb) 530 { 531 if(enb & 1) 532 { 533 if(enb & 2) 534 return 1; 535 if(enb & 4) 536 return 1; 537 if(enb & 8) 538 return 1; 539 if(enb & 16) 540 return 1; 541 if(enb & 32) 542 return 1; 543 if(enb & 64) 544 return 1; 545 if(enb & 128) 546 return 1; 547 return 0; 548 } 549 else if(enb & 2) 550 { 551 if(enb & 4) 552 return 1; 553 if(enb & 8) 554 return 1; 555 if(enb & 16) 556 return 1; 557 if(enb & 32) 558 return 1; 559 if(enb & 64) 560 return 1; 561 if(enb & 128) 562 return 1; 563 return 0; 564 } 565 else if(enb & 4) 566 { 567 if(enb & 8) 568 return 1; 569 if(enb & 16) 570 return 1; 571 if(enb & 32) 572 return 1; 573 if(enb & 64) 574 return 1; 575 if(enb & 128) 576 return 1; 577 return 0; 578 } 579 else if(enb & 8) 580 { 581 if(enb & 16) 582 return 1; 583 if(enb & 32) 584 return 1; 585 if(enb & 64) 586 return 1; 587 if(enb & 128) 588 return 1; 589 return 0; 590 } 591 else if(enb & 16) 592 { 593 if(enb & 32) 594 return 1; 595 if(enb & 64) 596 return 1; 597 if(enb & 128) 598 return 1; 599 return 0; 600 } 601 else if(enb & 32) 602 { 603 if(enb & 64) 604 return 1; 605 if(enb & 128) 606 return 1; 607 return 0; 608 } 609 else if(enb & 64) 610 { 611 if(enb & 128) 612 return 1; 613 return 0; 614 } 615 return 0; 616 } 617 #endif 618