Changeset 308
- Timestamp:
- Jan 3, 2004, 3:33:35 PM (19 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
libcaca/trunk/src/bitmap.c
r306 r308 60 60 #define LOOKUP_SAT 32 61 61 #define LOOKUP_HUE 16 62 static unsigned char lookup_table[LOOKUP_VAL][LOOKUP_SAT][LOOKUP_HUE];62 static unsigned char hsv_distances[LOOKUP_VAL][LOOKUP_SAT][LOOKUP_HUE]; 63 63 static enum caca_color lookup_colors[8]; 64 64 65 65 static int const hsv_palette[] = 66 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 */67 /* weight, hue, saturation, value */ 68 4, 0x0, 0x0, 0x0, /* black */ 69 5, 0x0, 0x0, 0x5ff, /* 30% */ 70 5, 0x0, 0x0, 0x9ff, /* 70% */ 71 4, 0x0, 0x0, 0xfff, /* white */ 72 3, 0x1000, 0xfff, 0x5ff, /* dark yellow */ 73 2, 0x1000, 0xfff, 0xfff, /* light yellow */ 74 3, 0x0, 0xfff, 0x5ff, /* dark red */ 75 2, 0x0, 0xfff, 0xfff /* light red */ 76 76 }; 77 77 78 #define HSV_XRATIO (5*5)79 #define HSV_YRATIO (3*3)80 #define HSV_HRATIO (2*2)78 #define HSV_XRATIO 6 79 #define HSV_YRATIO 3 80 #define HSV_HRATIO 3 81 81 82 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)) 83 (hsv_palette[index * 4] \ 84 * ((HSV_XRATIO * ((v) - hsv_palette[index * 4 + 3]) \ 85 * ((v) - hsv_palette[index * 4 + 3])) \ 86 + (hsv_palette[index * 4 + 3] \ 87 ? (HSV_YRATIO * ((s) - hsv_palette[index * 4 + 2]) \ 88 * ((s) - hsv_palette[index * 4 + 2])) \ 89 : 0) \ 90 + (hsv_palette[index * 4 + 2] \ 91 ? (HSV_HRATIO * ((h) - hsv_palette[index * 4 + 1]) \ 92 * ((h) - hsv_palette[index * 4 + 1])) \ 93 : 0))) 93 94 94 95 /* … … 558 559 lookup_colors[7] = light_colors[hue / 0x1000]; 559 560 560 point = lookup_table[val * LOOKUP_VAL / 0x1000] 561 [sat * LOOKUP_SAT / 0x1000] 562 [(hue & 0xfff) * LOOKUP_HUE / 0x1000]; 563 564 try_again: 561 point = hsv_distances[(val + _get_dither() * (0x1000 / LOOKUP_VAL) 562 / 0x100) * (LOOKUP_VAL - 1) / 0x1000] 563 [(sat + _get_dither() * (0x1000 / LOOKUP_SAT) 564 / 0x100) * (LOOKUP_SAT - 1) / 0x1000] 565 [((hue & 0xfff) + _get_dither() 566 * (0x1000 / LOOKUP_HUE) / 0x100) 567 * (LOOKUP_HUE - 1) / 0x1000]; 568 565 569 distfg = HSV_DISTANCE(hue % 0xfff, sat, val, (point >> 4)); 566 570 distbg = HSV_DISTANCE(hue % 0xfff, sat, val, (point & 0xf)); 567 571 568 /* Sanity check due to the lack of precision in lookup_table */ 569 #if 0 570 if(distbg > distfg) 571 { 572 point = ((point & 0xf) << 4) | (point >> 4); 573 goto try_again; 574 } 575 #endif 572 /* Sanity check due to the lack of precision in hsv_distances, 573 * and distbg can be > distfg because of dithering fuzziness. */ 576 574 if(distbg > distfg) 577 575 distbg = distfg; … … 580 578 outbg = lookup_colors[(point & 0xf)]; 581 579 582 outch = density_chars[4 * (distbg * (DENSITY_CHARS - 1) / distfg)]; 580 ch = distbg * 2 * (DENSITY_CHARS - 1) / (distbg + distfg); 581 ch = 4 * ch + _get_dither() / 0x40; 582 outch = density_chars[ch]; 583 583 } 584 584 else … … 626 626 for(h = 0; h < LOOKUP_HUE; h++) 627 627 { 628 int distbg, distfg, dist;628 int i, distbg, distfg, dist; 629 629 int val, sat, hue; 630 630 unsigned char outbg, outfg; 631 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) 632 val = 0xfff * v / (LOOKUP_VAL - 1); 633 sat = 0xfff * s / (LOOKUP_SAT - 1); 634 hue = 0xfff * h / (LOOKUP_HUE - 1); 635 636 /* Initialise distances to the distance between pure black HSV 637 * coordinates and our white colour (3) */ 638 outbg = outfg = 3; 639 distbg = distfg = HSV_DISTANCE(0, 0, 0, 3); 640 641 /* Calculate distances to eight major colour values and store the 642 * two nearest points in our lookup table. */ 643 for(i = 0; i < 8; i++) 645 644 { 646 outfg = outbg; 647 distfg = distbg; 648 outbg = 1; 649 distbg = dist; 645 dist = HSV_DISTANCE(hue, sat, val, i); 646 if(dist <= distbg) 647 { 648 outfg = outbg; 649 distfg = distbg; 650 outbg = i; 651 distbg = dist; 652 } 653 else if(dist <= distfg) 654 { 655 outfg = i; 656 distfg = dist; 657 } 650 658 } 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; 659 660 hsv_distances[v][s][h] = (outfg << 4) | outbg; 756 661 } 757 662
Note: See TracChangeset
for help on using the changeset viewer.