Changeset 306
- Timestamp:
- Jan 2, 2004, 7:09:29 PM (19 years ago)
- Location:
- libcaca/trunk/src
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
libcaca/trunk/src/bitmap.c
r305 r306 55 55 56 56 /* 57 * Local variables 58 */ 59 #define LOOKUP_VAL 32 60 #define LOOKUP_SAT 32 61 #define LOOKUP_HUE 16 62 static unsigned char lookup_table[LOOKUP_VAL][LOOKUP_SAT][LOOKUP_HUE]; 63 static enum caca_color lookup_colors[8]; 64 65 static int const hsv_palette[] = 66 { 67 /* hue, saturation, value */ 68 0x0, 0x0, 0x0, /* black */ 69 0x0, 0x0, 0x5ff, /* 30% */ 70 0x0, 0x0, 0x9ff, /* 70% */ 71 0x0, 0x0, 0xfff, /* white */ 72 0x1000, 0xfff, 0x5ff, /* dark yellow */ 73 0x1000, 0xfff, 0xfff, /* light yellow */ 74 0x0, 0xfff, 0x5ff, /* dark red */ 75 0x0, 0xfff, 0xfff /* light red */ 76 }; 77 78 #define HSV_XRATIO (5*5) 79 #define HSV_YRATIO (3*3) 80 #define HSV_HRATIO (2*2) 81 82 #define HSV_DISTANCE(h, s, v, index) \ 83 ((HSV_XRATIO * ((v) - hsv_palette[index * 3 + 2]) \ 84 * ((v) - hsv_palette[index * 3 + 2])) \ 85 + (hsv_palette[index * 3 + 2] \ 86 ? (HSV_YRATIO * ((s) - hsv_palette[index * 3 + 1]) \ 87 * ((s) - hsv_palette[index * 3 + 1])) \ 88 : 0) \ 89 + (hsv_palette[index * 3 + 1] \ 90 ? (HSV_HRATIO * ((h) - hsv_palette[index * 3 + 0]) \ 91 * ((h) - hsv_palette[index * 3 + 0])) \ 92 : 0)) 93 94 /* 57 95 * Local prototypes 58 96 */ … … 62 100 unsigned int *, unsigned int *, unsigned int *, 63 101 unsigned int *); 64 static void rgb2hsv_default(int, int, int, int *, int *, int *);102 static inline void rgb2hsv_default(int, int, int, int *, int *, int *); 65 103 66 104 /* Dithering methods */ … … 298 336 } 299 337 300 static void rgb2hsv_default(int r, int g, int b, int *hue, int *sat, int *val) 338 static inline void rgb2hsv_default(int r, int g, int b, 339 int *hue, int *sat, int *val) 301 340 { 302 341 int min, max, delta; … … 306 345 if(min > b) min = b; if(max < b) max = b; 307 346 308 delta = max - min; /* 0 - 0xfff f*/309 *val = max; /* 0 - 0xfff f*/347 delta = max - min; /* 0 - 0xfff */ 348 *val = max; /* 0 - 0xfff */ 310 349 311 350 if(delta) 312 351 { 313 *sat = 0x 1000* delta / max; /* 0 - 0xfff */352 *sat = 0xfff * delta / max; /* 0 - 0xfff */ 314 353 315 354 /* Generate *hue between 0 and 0x5fff */ … … 464 503 char outch; 465 504 466 /* Only used by coloured background */467 int distbg, distfg, dist, hue1, hue2;468 469 505 r = g = b = a = 0; 470 506 … … 480 516 for(myx = fromx; myx <= tox; myx++) 481 517 for(myy = fromy; myy <= toy; myy++) 482 483 484 485 518 { 519 dots++; 520 get_rgba_default(bitmap, pixels, myx, myy, &r, &g, &b, &a); 521 } 486 522 487 523 /* Normalize */ … … 514 550 if(_caca_background == CACA_BACKGROUND_SOLID) 515 551 { 516 # define XRATIO 5*5 517 # define YRATIO 3*3 518 # define HRATIO 2*2 519 # define FUZZINESS XRATIO * 0x800 520 521 /* distance to black */ 522 distbg = XRATIO * val * val; 523 distbg += FUZZINESS * _get_dither() - 0x80 * FUZZINESS; 524 distbg = distbg * 2 / 4; 525 outbg = CACA_COLOR_BLACK; 526 527 /* distance to 30% */ 528 dist = XRATIO * (val - 0x600) * (val - 0x600) 529 + YRATIO * sat * sat; 530 dist += FUZZINESS * _get_dither() - 0x80 * FUZZINESS; 531 dist = dist * 3 / 2; 532 if(dist <= distbg) 552 unsigned char point; 553 int distfg, distbg; 554 555 lookup_colors[4] = dark_colors[1 + hue / 0x1000]; 556 lookup_colors[5] = light_colors[1 + hue / 0x1000]; 557 lookup_colors[6] = dark_colors[hue / 0x1000]; 558 lookup_colors[7] = light_colors[hue / 0x1000]; 559 560 point = lookup_table[val * LOOKUP_VAL / 0x1000] 561 [sat * LOOKUP_SAT / 0x1000] 562 [(hue & 0xfff) * LOOKUP_HUE / 0x1000]; 563 564 try_again: 565 distfg = HSV_DISTANCE(hue % 0xfff, sat, val, (point >> 4)); 566 distbg = HSV_DISTANCE(hue % 0xfff, sat, val, (point & 0xf)); 567 568 /* Sanity check due to the lack of precision in lookup_table */ 569 #if 0 570 if(distbg > distfg) 533 571 { 534 outfg = outbg; 535 distfg = distbg; 536 outbg = CACA_COLOR_DARKGRAY; 537 distbg = dist; 572 point = ((point & 0xf) << 4) | (point >> 4); 573 goto try_again; 538 574 } 539 else 540 { 541 outfg = CACA_COLOR_DARKGRAY; 542 distfg = dist; 543 } 544 545 /* check dist to 70% */ 546 dist = XRATIO * (val - 0xa00) * (val - 0xa00) 547 + YRATIO * sat * sat; 548 dist += FUZZINESS * _get_dither() - 0x80 * FUZZINESS; 549 dist = dist * 3 / 2; 550 if(dist <= distbg) 551 { 552 outfg = outbg; 553 distfg = distbg; 554 outbg = CACA_COLOR_LIGHTGRAY; 555 distbg = dist; 556 } 557 else if(dist <= distfg) 558 { 559 outfg = CACA_COLOR_LIGHTGRAY; 560 distfg = dist; 561 } 562 563 /* check dist to white */ 564 dist = XRATIO * (val - 0x1000) * (val - 0x1000) 565 + YRATIO * sat * sat; 566 dist += FUZZINESS * _get_dither() - 0x80 * FUZZINESS; 567 if(dist <= distbg) 568 { 569 outfg = outbg; 570 distfg = distbg; 571 outbg = CACA_COLOR_WHITE; 572 distbg = dist; 573 } 574 else if(dist <= distfg) 575 { 576 outfg = CACA_COLOR_WHITE; 577 distfg = dist; 578 } 579 580 hue1 = (hue + 0x800) & ~0xfff; 581 if(hue > hue1) 582 hue2 = (hue + 0x1800) & ~0xfff; 583 else 584 hue2 = (hue - 0x800) & ~0xfff; 585 586 /* check dist to 2nd closest dark color */ 587 dist = XRATIO * (val - 0x600) * (val - 0x600) 588 + YRATIO * (sat - 0x1000) * (sat - 0x1000) 589 + HRATIO * (hue - hue2) * (hue - hue2); 590 dist += FUZZINESS * _get_dither() - 0x80 * FUZZINESS; 591 //dist = dist * 3 / 4; 592 if(dist <= distbg) 593 { 594 outfg = outbg; 595 distfg = distbg; 596 outbg = dark_colors[hue2 / 0x1000]; 597 distbg = dist; 598 } 599 else if(dist <= distfg) 600 { 601 outfg = dark_colors[hue2 / 0x1000]; 602 distfg = dist; 603 } 604 605 /* check dist to 2nd closest light color */ 606 dist = XRATIO * (val - 0x1000) * (val - 0x1000) 607 + YRATIO * (sat - 0x1000) * (sat - 0x1000) 608 + HRATIO * (hue - hue2) * (hue - hue2); 609 dist += FUZZINESS * _get_dither() - 0x80 * FUZZINESS; 610 //dist = dist * 3 / 4; 611 //dist = dist / 2; 612 if(dist <= distbg) 613 { 614 outfg = outbg; 615 distfg = distbg; 616 outbg = light_colors[hue2 / 0x1000]; 617 distbg = dist; 618 } 619 else if(dist <= distfg) 620 { 621 outfg = light_colors[hue2 / 0x1000]; 622 distfg = dist; 623 } 624 625 /* check dist to closest dark color */ 626 dist = XRATIO * (val - 0x600) * (val - 0x600) 627 + YRATIO * (sat - 0x1000) * (sat - 0x1000) 628 + HRATIO * (hue - hue1) * (hue - hue1); 629 dist += FUZZINESS * _get_dither() - 0x80 * FUZZINESS; 630 dist = dist * 3 / 4; 631 if(dist <= distbg) 632 { 633 outfg = outbg; 634 distfg = distbg; 635 outbg = dark_colors[hue1 / 0x1000]; 636 distbg = dist; 637 } 638 else if(dist <= distfg) 639 { 640 outfg = dark_colors[hue1 / 0x1000]; 641 distfg = dist; 642 } 643 644 /* check dist to closest light color */ 645 dist = XRATIO * (val - 0x1000) * (val - 0x1000) 646 + YRATIO * (sat - 0x1000) * (sat - 0x1000) 647 + HRATIO * (hue - hue1) * (hue - hue1); 648 dist += FUZZINESS * _get_dither() - 0x80 * FUZZINESS; 649 dist = dist / 2; 650 if(dist <= distbg) 651 { 652 outfg = outbg; 653 distfg = distbg; 654 outbg = light_colors[hue1 / 0x1000]; 655 distbg = dist; 656 } 657 else if(dist <= distfg) 658 { 659 outfg = light_colors[hue1 / 0x1000]; 660 distfg = dist; 661 } 662 663 if(distbg <= 0) distbg = 1; 664 if(distfg <= 0) distfg = 1; 665 666 /* distbg can be > distfg because of dithering fuzziness */ 667 ch = distbg * 2 * (DENSITY_CHARS - 1) / (distbg + distfg); 668 ch = 4 * ch + _get_dither() / 0x40; 669 outch = density_chars[ch]; 575 #endif 576 if(distbg > distfg) 577 distbg = distfg; 578 579 outfg = lookup_colors[(point >> 4)]; 580 outbg = lookup_colors[(point & 0xf)]; 581 582 outch = density_chars[4 * (distbg * (DENSITY_CHARS - 1) / distfg)]; 670 583 } 671 584 else … … 691 604 _increment_dither(); 692 605 } 606 } 607 608 int _caca_init_bitmap(void) 609 { 610 unsigned int v, s, h; 611 612 /* These ones are constant */ 613 lookup_colors[0] = CACA_COLOR_BLACK; 614 lookup_colors[1] = CACA_COLOR_DARKGRAY; 615 lookup_colors[2] = CACA_COLOR_LIGHTGRAY; 616 lookup_colors[3] = CACA_COLOR_WHITE; 617 618 /* These ones will be overwritten */ 619 lookup_colors[4] = CACA_COLOR_MAGENTA; 620 lookup_colors[5] = CACA_COLOR_LIGHTMAGENTA; 621 lookup_colors[6] = CACA_COLOR_RED; 622 lookup_colors[7] = CACA_COLOR_LIGHTRED; 623 624 for(v = 0; v < LOOKUP_VAL; v++) 625 for(s = 0; s < LOOKUP_SAT; s++) 626 for(h = 0; h < LOOKUP_HUE; h++) 627 { 628 int distbg, distfg, dist; 629 int val, sat, hue; 630 unsigned char outbg, outfg; 631 632 val = 0x1000 * v / LOOKUP_VAL; 633 sat = 0x1000 * s / LOOKUP_SAT; 634 hue = 0x1000 * h / LOOKUP_HUE; 635 636 /* distance to black */ 637 distbg = HSV_DISTANCE(hue, sat, val, 0); 638 distbg = distbg * 2 / 4; 639 outbg = 0; 640 641 /* distance to 30% */ 642 dist = HSV_DISTANCE(hue, sat, val, 1); 643 dist = dist * 3 / 2; 644 if(dist <= distbg) 645 { 646 outfg = outbg; 647 distfg = distbg; 648 outbg = 1; 649 distbg = dist; 650 } 651 else 652 { 653 outfg = 1; 654 distfg = dist; 655 } 656 657 /* check dist to 70% */ 658 dist = HSV_DISTANCE(hue, sat, val, 2); 659 dist = dist * 3 / 2; 660 if(dist <= distbg) 661 { 662 outfg = outbg; 663 distfg = distbg; 664 outbg = 2; 665 distbg = dist; 666 } 667 else if(dist <= distfg) 668 { 669 outfg = 2; 670 distfg = dist; 671 } 672 673 /* check dist to white */ 674 dist = HSV_DISTANCE(hue, sat, val, 3); 675 if(dist <= distbg) 676 { 677 outfg = outbg; 678 distfg = distbg; 679 outbg = 3; 680 distbg = dist; 681 } 682 else if(dist <= distfg) 683 { 684 outfg = 3; 685 distfg = dist; 686 } 687 688 /* check dist to 2nd closest dark color */ 689 dist = HSV_DISTANCE(hue, sat, val, 4); 690 //dist = dist * 3 / 4; 691 dist = dist * 3 / 4; 692 if(dist <= distbg) 693 { 694 outfg = outbg; 695 distfg = distbg; 696 outbg = 4; 697 distbg = dist; 698 } 699 else if(dist <= distfg) 700 { 701 outfg = 4; 702 distfg = dist; 703 } 704 705 /* check dist to 2nd closest light color */ 706 dist = HSV_DISTANCE(hue, sat, val, 5); 707 dist = dist / 2; 708 //dist = dist * 3 / 4; 709 //dist = dist / 2; 710 if(dist <= distbg) 711 { 712 outfg = outbg; 713 distfg = distbg; 714 outbg = 5; 715 distbg = dist; 716 } 717 else if(dist <= distfg) 718 { 719 outfg = 5; 720 distfg = dist; 721 } 722 723 /* check dist to closest dark color */ 724 dist = HSV_DISTANCE(hue, sat, val, 6); 725 dist = dist * 3 / 4; 726 if(dist <= distbg) 727 { 728 outfg = outbg; 729 distfg = distbg; 730 outbg = 6; 731 distbg = dist; 732 } 733 else if(dist <= distfg) 734 { 735 outfg = 6; 736 distfg = dist; 737 } 738 739 /* check dist to closest light color */ 740 dist = HSV_DISTANCE(hue, sat, val, 7); 741 dist = dist / 2; 742 if(dist <= distbg) 743 { 744 outfg = outbg; 745 distfg = distbg; 746 outbg = 7; 747 distbg = dist; 748 } 749 else if(dist <= distfg) 750 { 751 outfg = 7; 752 distfg = dist; 753 } 754 755 lookup_table[v][s][h] = (outfg << 4) | outbg; 756 } 757 758 return 0; 759 } 760 761 int _caca_end_bitmap(void) 762 { 763 return 0; 693 764 } 694 765 -
libcaca/trunk/src/caca.c
r305 r306 154 154 155 155 if(_caca_init_graphics()) 156 return -1; 157 158 if(_caca_init_bitmap()) 156 159 return -1; 157 160 … … 320 323 void caca_end(void) 321 324 { 325 _caca_end_bitmap(); 322 326 _caca_end_graphics(); 323 327 -
libcaca/trunk/src/caca_internals.h
r273 r306 54 54 extern int _caca_init_graphics(void); 55 55 extern int _caca_end_graphics(void); 56 extern int _caca_init_bitmap(void); 57 extern int _caca_end_bitmap(void); 56 58 57 59 /* Cached screen size */
Note: See TracChangeset
for help on using the changeset viewer.