1 11 package org.eclipse.swt.graphics; 12 13 14 import java.io.*; 15 import org.eclipse.swt.*; 16 import org.eclipse.swt.internal.CloneableCompatibility; 17 18 33 34 public final class ImageData implements CloneableCompatibility { 35 36 39 public int width; 40 41 44 public int height; 45 46 55 public int depth; 56 57 64 public int scanlinePad; 65 66 72 public int bytesPerLine; 73 74 83 public byte[] data; 84 85 88 public PaletteData palette; 89 90 98 public int transparentPixel; 99 100 110 public byte[] maskData; 111 112 120 public int maskPad; 121 122 131 public byte[] alphaData; 132 133 144 public int alpha; 145 146 165 public int type; 166 167 172 public int x; 173 174 179 public int y; 180 181 198 public int disposalMethod; 199 200 205 public int delayTime; 206 207 210 static final byte[][] ANY_TO_EIGHT = new byte[9][]; 211 static { 212 for (int b = 0; b < 9; ++b) { 213 byte[] data = ANY_TO_EIGHT[b] = new byte[1 << b]; 214 if (b == 0) continue; 215 int inc = 0; 216 for (int bit = 0x10000; (bit >>= b) != 0;) inc |= bit; 217 for (int v = 0, p = 0; v < 0x10000; v+= inc) data[p++] = (byte)(v >> 8); 218 } 219 } 220 static final byte[] ONE_TO_ONE_MAPPING = ANY_TO_EIGHT[8]; 221 222 225 static final int[][] DITHER_MATRIX = { 226 { 0xfc0000, 0x7c0000, 0xdc0000, 0x5c0000, 0xf40000, 0x740000, 0xd40000, 0x540000 }, 227 { 0x3c0000, 0xbc0000, 0x1c0000, 0x9c0000, 0x340000, 0xb40000, 0x140000, 0x940000 }, 228 { 0xcc0000, 0x4c0000, 0xec0000, 0x6c0000, 0xc40000, 0x440000, 0xe40000, 0x640000 }, 229 { 0x0c0000, 0x8c0000, 0x2c0000, 0xac0000, 0x040000, 0x840000, 0x240000, 0xa40000 }, 230 { 0xf00000, 0x700000, 0xd00000, 0x500000, 0xf80000, 0x780000, 0xd80000, 0x580000 }, 231 { 0x300000, 0xb00000, 0x100000, 0x900000, 0x380000, 0xb80000, 0x180000, 0x980000 }, 232 { 0xc00000, 0x400000, 0xe00000, 0x600000, 0xc80000, 0x480000, 0xe80000, 0x680000 }, 233 { 0x000000, 0x800000, 0x200000, 0xa00000, 0x080000, 0x880000, 0x280000, 0xa80000 } 234 }; 235 236 252 public ImageData(int width, int height, int depth, PaletteData palette) { 253 this(width, height, depth, palette, 254 4, null, 0, null, 255 null, -1, -1, SWT.IMAGE_UNDEFINED, 256 0, 0, 0, 0); 257 } 258 259 277 public ImageData(int width, int height, int depth, PaletteData palette, int scanlinePad, byte[] data) { 278 this(width, height, depth, palette, 279 scanlinePad, checkData(data), 0, null, 280 null, -1, -1, SWT.IMAGE_UNDEFINED, 281 0, 0, 0, 0); 282 } 283 284 327 public ImageData(InputStream stream) { 328 ImageData[] data = ImageDataLoader.load(stream); 329 if (data.length < 1) SWT.error(SWT.ERROR_INVALID_IMAGE); 330 ImageData i = data[0]; 331 setAllFields( 332 i.width, 333 i.height, 334 i.depth, 335 i.scanlinePad, 336 i.bytesPerLine, 337 i.data, 338 i.palette, 339 i.transparentPixel, 340 i.maskData, 341 i.maskPad, 342 i.alphaData, 343 i.alpha, 344 i.type, 345 i.x, 346 i.y, 347 i.disposalMethod, 348 i.delayTime); 349 } 350 351 373 public ImageData(String filename) { 374 ImageData[] data = ImageDataLoader.load(filename); 375 if (data.length < 1) SWT.error(SWT.ERROR_INVALID_IMAGE); 376 ImageData i = data[0]; 377 setAllFields( 378 i.width, 379 i.height, 380 i.depth, 381 i.scanlinePad, 382 i.bytesPerLine, 383 i.data, 384 i.palette, 385 i.transparentPixel, 386 i.maskData, 387 i.maskPad, 388 i.alphaData, 389 i.alpha, 390 i.type, 391 i.x, 392 i.y, 393 i.disposalMethod, 394 i.delayTime); 395 } 396 397 400 ImageData() { 401 } 402 403 409 ImageData( 410 int width, int height, int depth, PaletteData palette, 411 int scanlinePad, byte[] data, int maskPad, byte[] maskData, 412 byte[] alphaData, int alpha, int transparentPixel, int type, 413 int x, int y, int disposalMethod, int delayTime) 414 { 415 416 if (palette == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); 417 if (!(depth == 1 || depth == 2 || depth == 4 || depth == 8 418 || depth == 16 || depth == 24 || depth == 32)) { 419 SWT.error(SWT.ERROR_INVALID_ARGUMENT); 420 } 421 if (width <= 0 || height <= 0) { 422 SWT.error(SWT.ERROR_INVALID_ARGUMENT); 423 } 424 if (scanlinePad == 0) SWT.error (SWT.ERROR_CANNOT_BE_ZERO); 425 426 int bytesPerLine = (((width * depth + 7) / 8) + (scanlinePad - 1)) 427 / scanlinePad * scanlinePad; 428 setAllFields( 429 width, 430 height, 431 depth, 432 scanlinePad, 433 bytesPerLine, 434 data != null ? data : new byte[bytesPerLine * height], 435 palette, 436 transparentPixel, 437 maskData, 438 maskPad, 439 alphaData, 440 alpha, 441 type, 442 x, 443 y, 444 disposalMethod, 445 delayTime); 446 } 447 448 457 void setAllFields(int width, int height, int depth, int scanlinePad, 458 int bytesPerLine, byte[] data, PaletteData palette, int transparentPixel, 459 byte[] maskData, int maskPad, byte[] alphaData, int alpha, 460 int type, int x, int y, int disposalMethod, int delayTime) { 461 462 this.width = width; 463 this.height = height; 464 this.depth = depth; 465 this.scanlinePad = scanlinePad; 466 this.bytesPerLine = bytesPerLine; 467 this.data = data; 468 this.palette = palette; 469 this.transparentPixel = transparentPixel; 470 this.maskData = maskData; 471 this.maskPad = maskPad; 472 this.alphaData = alphaData; 473 this.alpha = alpha; 474 this.type = type; 475 this.x = x; 476 this.y = y; 477 this.disposalMethod = disposalMethod; 478 this.delayTime = delayTime; 479 } 480 481 495 public static ImageData internal_new( 496 int width, int height, int depth, PaletteData palette, 497 int scanlinePad, byte[] data, int maskPad, byte[] maskData, 498 byte[] alphaData, int alpha, int transparentPixel, int type, 499 int x, int y, int disposalMethod, int delayTime) 500 { 501 return new ImageData( 502 width, height, depth, palette, scanlinePad, data, maskPad, maskData, 503 alphaData, alpha, transparentPixel, type, x, y, disposalMethod, delayTime); 504 } 505 506 ImageData colorMaskImage(int pixel) { 507 ImageData mask = new ImageData(width, height, 1, bwPalette(), 508 2, null, 0, null, null, -1, -1, SWT.IMAGE_UNDEFINED, 509 0, 0, 0, 0); 510 int[] row = new int[width]; 511 for (int y = 0; y < height; y++) { 512 getPixels(0, y, width, row, 0); 513 for (int i = 0; i < width; i++) { 514 if (pixel != -1 && row[i] == pixel) { 515 row[i] = 0; 516 } else { 517 row[i] = 1; 518 } 519 } 520 mask.setPixels(0, y, width, row, 0); 521 } 522 return mask; 523 } 524 525 static byte[] checkData(byte [] data) { 526 if (data == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); 527 return data; 528 } 529 530 538 public Object clone() { 539 byte[] cloneData = new byte[data.length]; 540 System.arraycopy(data, 0, cloneData, 0, data.length); 541 byte[] cloneMaskData = null; 542 if (maskData != null) { 543 cloneMaskData = new byte[maskData.length]; 544 System.arraycopy(maskData, 0, cloneMaskData, 0, maskData.length); 545 } 546 byte[] cloneAlphaData = null; 547 if (alphaData != null) { 548 cloneAlphaData = new byte[alphaData.length]; 549 System.arraycopy(alphaData, 0, cloneAlphaData, 0, alphaData.length); 550 } 551 return new ImageData( 552 width, 553 height, 554 depth, 555 palette, 556 scanlinePad, 557 cloneData, 558 maskPad, 559 cloneMaskData, 560 cloneAlphaData, 561 alpha, 562 transparentPixel, 563 type, 564 x, 565 y, 566 disposalMethod, 567 delayTime); 568 } 569 570 582 public int getAlpha(int x, int y) { 583 if (x >= width || y >= height || x < 0 || y < 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT); 584 585 if (alphaData == null) return 255; 586 return alphaData[y * width + x] & 0xFF; 587 } 588 589 607 public void getAlphas(int x, int y, int getWidth, byte[] alphas, int startIndex) { 608 if (alphas == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); 609 if (getWidth < 0 || x >= width || y >= height || x < 0 || y < 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT); 610 if (getWidth == 0) return; 611 612 if (alphaData == null) { 613 int endIndex = startIndex + getWidth; 614 for (int i = startIndex; i < endIndex; i++) { 615 alphas[i] = (byte)255; 616 } 617 return; 618 } 619 System.arraycopy(alphaData, y * width + x, alphas, startIndex, getWidth); 621 } 622 623 638 public int getPixel(int x, int y) { 639 if (x >= width || y >= height || x < 0 || y < 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT); 640 int index; 641 int theByte; 642 int mask; 643 switch (depth) { 644 case 32: 645 index = (y * bytesPerLine) + (x * 4); 646 return ((data[index] & 0xFF) << 24) + ((data[index+1] & 0xFF) << 16) + 647 ((data[index+2] & 0xFF) << 8) + (data[index+3] & 0xFF); 648 case 24: 649 index = (y * bytesPerLine) + (x * 3); 650 return ((data[index] & 0xFF) << 16) + ((data[index+1] & 0xFF) << 8) + 651 (data[index+2] & 0xFF); 652 case 16: 653 index = (y * bytesPerLine) + (x * 2); 654 return ((data[index+1] & 0xFF) << 8) + (data[index] & 0xFF); 655 case 8: 656 index = (y * bytesPerLine) + x ; 657 return data[index] & 0xFF; 658 case 4: 659 index = (y * bytesPerLine) + (x >> 1); 660 theByte = data[index] & 0xFF; 661 if ((x & 0x1) == 0) { 662 return theByte >> 4; 663 } else { 664 return theByte & 0x0F; 665 } 666 case 2: 667 index = (y * bytesPerLine) + (x >> 2); 668 theByte = data[index] & 0xFF; 669 int offset = 3 - (x % 4); 670 mask = 3 << (offset * 2); 671 return (theByte & mask) >> (offset * 2); 672 case 1: 673 index = (y * bytesPerLine) + (x >> 3); 674 theByte = data[index] & 0xFF; 675 mask = 1 << (7 - (x & 0x7)); 676 if ((theByte & mask) == 0) { 677 return 0; 678 } else { 679 return 1; 680 } 681 } 682 SWT.error(SWT.ERROR_UNSUPPORTED_DEPTH); 683 return 0; 684 } 685 686 708 public void getPixels(int x, int y, int getWidth, byte[] pixels, int startIndex) { 709 if (pixels == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); 710 if (getWidth < 0 || x >= width || y >= height || x < 0 || y < 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT); 711 if (getWidth == 0) return; 712 int index; 713 int theByte; 714 int mask = 0; 715 int n = getWidth; 716 int i = startIndex; 717 int srcX = x, srcY = y; 718 switch (depth) { 719 case 8: 720 index = (y * bytesPerLine) + x; 721 for (int j = 0; j < getWidth; j++) { 722 pixels[i] = data[index]; 723 i++; 724 srcX++; 725 if (srcX >= width) { 726 srcY++; 727 index = srcY * bytesPerLine; 728 srcX = 0; 729 } else { 730 index++; 731 } 732 } 733 return; 734 case 4: 735 index = (y * bytesPerLine) + (x >> 1); 736 if ((x & 0x1) == 1) { 737 theByte = data[index] & 0xFF; 738 pixels[i] = (byte)(theByte & 0x0F); 739 i++; 740 n--; 741 srcX++; 742 if (srcX >= width) { 743 srcY++; 744 index = srcY * bytesPerLine; 745 srcX = 0; 746 } else { 747 index++; 748 } 749 } 750 while (n > 1) { 751 theByte = data[index] & 0xFF; 752 pixels[i] = (byte)(theByte >> 4); 753 i++; 754 n--; 755 srcX++; 756 if (srcX >= width) { 757 srcY++; 758 index = srcY * bytesPerLine; 759 srcX = 0; 760 } else { 761 pixels[i] = (byte)(theByte & 0x0F); 762 i++; 763 n--; 764 srcX++; 765 if (srcX >= width) { 766 srcY++; 767 index = srcY * bytesPerLine; 768 srcX = 0; 769 } else { 770 index++; 771 } 772 } 773 } 774 if (n > 0) { 775 theByte = data[index] & 0xFF; 776 pixels[i] = (byte)(theByte >> 4); 777 } 778 return; 779 case 2: 780 index = (y * bytesPerLine) + (x >> 2); 781 theByte = data[index] & 0xFF; 782 int offset; 783 while (n > 0) { 784 offset = 3 - (srcX % 4); 785 mask = 3 << (offset * 2); 786 pixels[i] = (byte)((theByte & mask) >> (offset * 2)); 787 i++; 788 n--; 789 srcX++; 790 if (srcX >= width) { 791 srcY++; 792 index = srcY * bytesPerLine; 793 if (n > 0) theByte = data[index] & 0xFF; 794 srcX = 0; 795 } else { 796 if (offset == 0) { 797 index++; 798 theByte = data[index] & 0xFF; 799 } 800 } 801 } 802 return; 803 case 1: 804 index = (y * bytesPerLine) + (x >> 3); 805 theByte = data[index] & 0xFF; 806 while (n > 0) { 807 mask = 1 << (7 - (srcX & 0x7)); 808 if ((theByte & mask) == 0) { 809 pixels[i] = 0; 810 } else { 811 pixels[i] = 1; 812 } 813 i++; 814 n--; 815 srcX++; 816 if (srcX >= width) { 817 srcY++; 818 index = srcY * bytesPerLine; 819 if (n > 0) theByte = data[index] & 0xFF; 820 srcX = 0; 821 } else { 822 if (mask == 1) { 823 index++; 824 if (n > 0) theByte = data[index] & 0xFF; 825 } 826 } 827 } 828 return; 829 } 830 SWT.error(SWT.ERROR_UNSUPPORTED_DEPTH); 831 } 832 833 854 public void getPixels(int x, int y, int getWidth, int[] pixels, int startIndex) { 855 if (pixels == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); 856 if (getWidth < 0 || x >= width || y >= height || x < 0 || y < 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT); 857 if (getWidth == 0) return; 858 int index; 859 int theByte; 860 int mask; 861 int n = getWidth; 862 int i = startIndex; 863 int srcX = x, srcY = y; 864 switch (depth) { 865 case 32: 866 index = (y * bytesPerLine) + (x * 4); 867 i = startIndex; 868 for (int j = 0; j < getWidth; j++) { 869 pixels[i] = ((data[index] & 0xFF) << 24) | ((data[index+1] & 0xFF) << 16) 870 | ((data[index+2] & 0xFF) << 8) | (data[index+3] & 0xFF); 871 i++; 872 srcX++; 873 if (srcX >= width) { 874 srcY++; 875 index = srcY * bytesPerLine; 876 srcX = 0; 877 } else { 878 index += 4; 879 } 880 } 881 return; 882 case 24: 883 index = (y * bytesPerLine) + (x * 3); 884 for (int j = 0; j < getWidth; j++) { 885 pixels[i] = ((data[index] & 0xFF) << 16) | ((data[index+1] & 0xFF) << 8) 886 | (data[index+2] & 0xFF); 887 i++; 888 srcX++; 889 if (srcX >= width) { 890 srcY++; 891 index = srcY * bytesPerLine; 892 srcX = 0; 893 } else { 894 index += 3; 895 } 896 } 897 return; 898 case 16: 899 index = (y * bytesPerLine) + (x * 2); 900 for (int j = 0; j < getWidth; j++) { 901 pixels[i] = ((data[index+1] & 0xFF) << 8) + (data[index] & 0xFF); 902 i++; 903 srcX++; 904 if (srcX >= width) { 905 srcY++; 906 index = srcY * bytesPerLine; 907 srcX = 0; 908 } else { 909 index += 2; 910 } 911 } 912 return; 913 case 8: 914 index = (y * bytesPerLine) + x; 915 for (int j = 0; j < getWidth; j++) { 916 pixels[i] = data[index] & 0xFF; 917 i++; 918 srcX++; 919 if (srcX >= width) { 920 srcY++; 921 index = srcY * bytesPerLine; 922 srcX = 0; 923 } else { 924 index++; 925 } 926 } 927 return; 928 case 4: 929 index = (y * bytesPerLine) + (x >> 1); 930 if ((x & 0x1) == 1) { 931 theByte = data[index] & 0xFF; 932 pixels[i] = theByte & 0x0F; 933 i++; 934 n--; 935 srcX++; 936 if (srcX >= width) { 937 srcY++; 938 index = srcY * bytesPerLine; 939 srcX = 0; 940 } else { 941 index++; 942 } 943 } 944 while (n > 1) { 945 theByte = data[index] & 0xFF; 946 pixels[i] = theByte >> 4; 947 i++; 948 n--; 949 srcX++; 950 if (srcX >= width) { 951 srcY++; 952 index = srcY * bytesPerLine; 953 srcX = 0; 954 } else { 955 pixels[i] = theByte & 0x0F; 956 i++; 957 n--; 958 srcX++; 959 if (srcX >= width) { 960 srcY++; 961 index = srcY * bytesPerLine; 962 srcX = 0; 963 } else { 964 index++; 965 } 966 } 967 } 968 if (n > 0) { 969 theByte = data[index] & 0xFF; 970 pixels[i] = theByte >> 4; 971 } 972 return; 973 case 2: 974 index = (y * bytesPerLine) + (x >> 2); 975 theByte = data[index] & 0xFF; 976 int offset; 977 while (n > 0) { 978 offset = 3 - (srcX % 4); 979 mask = 3 << (offset * 2); 980 pixels[i] = (byte)((theByte & mask) >> (offset * 2)); 981 i++; 982 n--; 983 srcX++; 984 if (srcX >= width) { 985 srcY++; 986 index = srcY * bytesPerLine; 987 if (n > 0) theByte = data[index] & 0xFF; 988 srcX = 0; 989 } else { 990 if (offset == 0) { 991 index++; 992 theByte = data[index] & 0xFF; 993 } 994 } 995 } 996 return; 997 case 1: 998 index = (y * bytesPerLine) + (x >> 3); 999 theByte = data[index] & 0xFF; 1000 while (n > 0) { 1001 mask = 1 << (7 - (srcX & 0x7)); 1002 if ((theByte & mask) == 0) { 1003 pixels[i] = 0; 1004 } else { 1005 pixels[i] = 1; 1006 } 1007 i++; 1008 n--; 1009 srcX++; 1010 if (srcX >= width) { 1011 srcY++; 1012 index = srcY * bytesPerLine; 1013 if (n > 0) theByte = data[index] & 0xFF; 1014 srcX = 0; 1015 } else { 1016 if (mask == 1) { 1017 index++; 1018 if (n > 0) theByte = data[index] & 0xFF; 1019 } 1020 } 1021 } 1022 return; 1023 } 1024 SWT.error(SWT.ERROR_UNSUPPORTED_DEPTH); 1025} 1026 1027 1036public RGB[] getRGBs() { 1037 return palette.getRGBs(); 1038} 1039 1040 1048public ImageData getTransparencyMask() { 1049 if (getTransparencyType() == SWT.TRANSPARENCY_MASK) { 1050 return new ImageData(width, height, 1, bwPalette(), maskPad, maskData); 1051 } else { 1052 return colorMaskImage(transparentPixel); 1053 } 1054} 1055 1056 1063public int getTransparencyType() { 1064 if (maskData != null) return SWT.TRANSPARENCY_MASK; 1065 if (transparentPixel != -1) return SWT.TRANSPARENCY_PIXEL; 1066 if (alphaData != null) return SWT.TRANSPARENCY_ALPHA; 1067 return SWT.TRANSPARENCY_NONE; 1068} 1069 1070 1075int getByteOrder() { 1076 return depth != 16 ? MSB_FIRST : LSB_FIRST; 1077} 1078 1079 1089public ImageData scaledTo(int width, int height) { 1090 1091 final boolean flipX = (width < 0); 1092 if (flipX) width = - width; 1093 final boolean flipY = (height < 0); 1094 if (flipY) height = - height; 1095 1096 ImageData dest = new ImageData( 1097 width, height, depth, palette, 1098 scanlinePad, null, 0, null, 1099 null, -1, transparentPixel, type, 1100 x, y, disposalMethod, delayTime); 1101 1102 1103 if (palette.isDirect) blit(BLIT_SRC, 1104 this.data, this.depth, this.bytesPerLine, this.getByteOrder(), 0, 0, this.width, this.height, 0, 0, 0, 1105 ALPHA_OPAQUE, null, 0, 0, 0, 1106 dest.data, dest.depth, dest.bytesPerLine, dest.getByteOrder(), 0, 0, dest.width, dest.height, 0, 0, 0, 1107 flipX, flipY); 1108 else blit(BLIT_SRC, 1109 this.data, this.depth, this.bytesPerLine, this.getByteOrder(), 0, 0, this.width, this.height, null, null, null, 1110 ALPHA_OPAQUE, null, 0, 0, 0, 1111 dest.data, dest.depth, dest.bytesPerLine, dest.getByteOrder(), 0, 0, dest.width, dest.height, null, null, null, 1112 flipX, flipY); 1113 1114 1115 if (maskData != null) { 1116 dest.maskPad = this.maskPad; 1117 int destBpl = (dest.width + 7) / 8; 1118 destBpl = (destBpl + (dest.maskPad - 1)) / dest.maskPad * dest.maskPad; 1119 dest.maskData = new byte[destBpl * dest.height]; 1120 int srcBpl = (this.width + 7) / 8; 1121 srcBpl = (srcBpl + (this.maskPad - 1)) / this.maskPad * this.maskPad; 1122 blit(BLIT_SRC, 1123 this.maskData, 1, srcBpl, MSB_FIRST, 0, 0, this.width, this.height, null, null, null, 1124 ALPHA_OPAQUE, null, 0, 0, 0, 1125 dest.maskData, 1, destBpl, MSB_FIRST, 0, 0, dest.width, dest.height, null, null, null, 1126 flipX, flipY); 1127 } else if (alpha != -1) { 1128 dest.alpha = this.alpha; 1129 } else if (alphaData != null) { 1130 dest.alphaData = new byte[dest.width * dest.height]; 1131 blit(BLIT_SRC, 1132 this.alphaData, 8, this.width, MSB_FIRST, 0, 0, this.width, this.height, null, null, null, 1133 ALPHA_OPAQUE, null, 0, 0, 0, 1134 dest.alphaData, 8, dest.width, MSB_FIRST, 0, 0, dest.width, dest.height, null, null, null, 1135 flipX, flipY); 1136 } 1137 return dest; 1138} 1139 1140 1152public void setAlpha(int x, int y, int alpha) { 1153 if (x >= width || y >= height || x < 0 || y < 0 || alpha < 0 || alpha > 255) 1154 SWT.error(SWT.ERROR_INVALID_ARGUMENT); 1155 1156 if (alphaData == null) alphaData = new byte[width * height]; 1157 alphaData[y * width + x] = (byte)alpha; 1158} 1159 1160 1179public void setAlphas(int x, int y, int putWidth, byte[] alphas, int startIndex) { 1180 if (alphas == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); 1181 if (putWidth < 0 || x >= width || y >= height || x < 0 || y < 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT); 1182 if (putWidth == 0) return; 1183 1184 if (alphaData == null) alphaData = new byte[width * height]; 1185 System.arraycopy(alphas, startIndex, alphaData, y * width + x, putWidth); 1187} 1188 1189 1204public void setPixel(int x, int y, int pixelValue) { 1205 if (x >= width || y >= height || x < 0 || y < 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT); 1206 int index; 1207 byte theByte; 1208 int mask; 1209 switch (depth) { 1210 case 32: 1211 index = (y * bytesPerLine) + (x * 4); 1212 data[index] = (byte)((pixelValue >> 24) & 0xFF); 1213 data[index + 1] = (byte)((pixelValue >> 16) & 0xFF); 1214 data[index + 2] = (byte)((pixelValue >> 8) & 0xFF); 1215 data[index + 3] = (byte)(pixelValue & 0xFF); 1216 return; 1217 case 24: 1218 index = (y * bytesPerLine) + (x * 3); 1219 data[index] = (byte)((pixelValue >> 16) & 0xFF); 1220 data[index + 1] = (byte)((pixelValue >> 8) & 0xFF); 1221 data[index + 2] = (byte)(pixelValue & 0xFF); 1222 return; 1223 case 16: 1224 index = (y * bytesPerLine) + (x * 2); 1225 data[index + 1] = (byte)((pixelValue >> 8) & 0xFF); 1226 data[index] = (byte)(pixelValue & 0xFF); 1227 return; 1228 case 8: 1229 index = (y * bytesPerLine) + x ; 1230 data[index] = (byte)(pixelValue & 0xFF); 1231 return; 1232 case 4: 1233 index = (y * bytesPerLine) + (x >> 1); 1234 if ((x & 0x1) == 0) { 1235 data[index] = (byte)((data[index] & 0x0F) | ((pixelValue & 0x0F) << 4)); 1236 } else { 1237 data[index] = (byte)((data[index] & 0xF0) | (pixelValue & 0x0F)); 1238 } 1239 return; 1240 case 2: 1241 index = (y * bytesPerLine) + (x >> 2); 1242 theByte = data[index]; 1243 int offset = 3 - (x % 4); 1244 mask = 0xFF ^ (3 << (offset * 2)); 1245 data[index] = (byte)((data[index] & mask) | (pixelValue << (offset * 2))); 1246 return; 1247 case 1: 1248 index = (y * bytesPerLine) + (x >> 3); 1249 theByte = data[index]; 1250 mask = 1 << (7 - (x & 0x7)); 1251 if ((pixelValue & 0x1) == 1) { 1252 data[index] = (byte)(theByte | mask); 1253 } else { 1254 data[index] = (byte)(theByte & (mask ^ -1)); 1255 } 1256 return; 1257 } 1258 SWT.error(SWT.ERROR_UNSUPPORTED_DEPTH); 1259} 1260 1261 1284public void setPixels(int x, int y, int putWidth, byte[] pixels, int startIndex) { 1285 if (pixels == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); 1286 if (putWidth < 0 || x >= width || y >= height || x < 0 || y < 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT); 1287 if (putWidth == 0) return; 1288 int index; 1289 int theByte; 1290 int mask; 1291 int n = putWidth; 1292 int i = startIndex; 1293 int srcX = x, srcY = y; 1294 switch (depth) { 1295 case 8: 1296 index = (y * bytesPerLine) + x; 1297 for (int j = 0; j < putWidth; j++) { 1298 data[index] = (byte)(pixels[i] & 0xFF); 1299 i++; 1300 srcX++; 1301 if (srcX >= width) { 1302 srcY++; 1303 index = srcY * bytesPerLine; 1304 srcX = 0; 1305 } else { 1306 index++; 1307 } 1308 } 1309 return; 1310 case 4: 1311 index = (y * bytesPerLine) + (x >> 1); 1312 boolean high = (x & 0x1) == 0; 1313 while (n > 0) { 1314 theByte = pixels[i] & 0x0F; 1315 if (high) { 1316 data[index] = (byte)((data[index] & 0x0F) | (theByte << 4)); 1317 } else { 1318 data[index] = (byte)((data[index] & 0xF0) | theByte); 1319 } 1320 i++; 1321 n--; 1322 srcX++; 1323 if (srcX >= width) { 1324 srcY++; 1325 index = srcY * bytesPerLine; 1326 high = true; 1327 srcX = 0; 1328 } else { 1329 if (!high) index++; 1330 high = !high; 1331 } 1332 } 1333 return; 1334 case 2: 1335 byte [] masks = { (byte)0xFC, (byte)0xF3, (byte)0xCF, (byte)0x3F }; 1336 index = (y * bytesPerLine) + (x >> 2); 1337 int offset = 3 - (x % 4); 1338 while (n > 0) { 1339 theByte = pixels[i] & 0x3; 1340 data[index] = (byte)((data[index] & masks[offset]) | (theByte << (offset * 2))); 1341 i++; 1342 n--; 1343 srcX++; 1344 if (srcX >= width) { 1345 srcY++; 1346 index = srcY * bytesPerLine; 1347 offset = 0; 1348 srcX = 0; 1349 } else { 1350 if (offset == 0) { 1351 index++; 1352 offset = 3; 1353 } else { 1354 offset--; 1355 } 1356 } 1357 } 1358 return; 1359 case 1: 1360 index = (y * bytesPerLine) + (x >> 3); 1361 while (n > 0) { 1362 mask = 1 << (7 - (srcX & 0x7)); 1363 if ((pixels[i] & 0x1) == 1) { 1364 data[index] = (byte)((data[index] & 0xFF) | mask); 1365 } else { 1366 data[index] = (byte)((data[index] & 0xFF) & (mask ^ -1)); 1367 } 1368 i++; 1369 n--; 1370 srcX++; 1371 if (srcX >= width) { 1372 srcY++; 1373 index = srcY * bytesPerLine; 1374 srcX = 0; 1375 } else { 1376 if (mask == 1) { 1377 index++; 1378 } 1379 } 1380 } 1381 return; 1382 } 1383 SWT.error(SWT.ERROR_UNSUPPORTED_DEPTH); 1384} 1385 1386 1408public void setPixels(int x, int y, int putWidth, int[] pixels, int startIndex) { 1409 if (pixels == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); 1410 if (putWidth < 0 || x >= width || y >= height || x < 0 || y < 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT); 1411 if (putWidth == 0) return; 1412 int index; 1413 int theByte; 1414 int mask; 1415 int n = putWidth; 1416 int i = startIndex; 1417 int pixel; 1418 int srcX = x, srcY = y; 1419 switch (depth) { 1420 case 32: 1421 index = (y * bytesPerLine) + (x * 4); 1422 for (int j = 0; j < putWidth; j++) { 1423 pixel = pixels[i]; 1424 data[index] = (byte)((pixel >> 24) & 0xFF); 1425 data[index + 1] = (byte)((pixel >> 16) & 0xFF); 1426 data[index + 2] = (byte)((pixel >> 8) & 0xFF); 1427 data[index + 3] = (byte)(pixel & 0xFF); 1428 i++; 1429 srcX++; 1430 if (srcX >= width) { 1431 srcY++; 1432 index = srcY * bytesPerLine; 1433 srcX = 0; 1434 } else { 1435 index += 4; 1436 } 1437 } 1438 return; 1439 case 24: 1440 index = (y * bytesPerLine) + (x * 3); 1441 for (int j = 0; j < putWidth; j++) { 1442 pixel = pixels[i]; 1443 data[index] = (byte)((pixel >> 16) & 0xFF); 1444 data[index + 1] = (byte)((pixel >> 8) & 0xFF); 1445 data[index + 2] = (byte)(pixel & 0xFF); 1446 i++; 1447 srcX++; 1448 if (srcX >= width) { 1449 srcY++; 1450 index = srcY * bytesPerLine; 1451 srcX = 0; 1452 } else { 1453 index += 3; 1454 } 1455 } 1456 return; 1457 case 16: 1458 index = (y * bytesPerLine) + (x * 2); 1459 for (int j = 0; j < putWidth; j++) { 1460 pixel = pixels[i]; 1461 data[index] = (byte)(pixel & 0xFF); 1462 data[index + 1] = (byte)((pixel >> 8) & 0xFF); 1463 i++; 1464 srcX++; 1465 if (srcX >= width) { 1466 srcY++; 1467 index = srcY * bytesPerLine; 1468 srcX = 0; 1469 } else { 1470 index += 2; 1471 } 1472 } 1473 return; 1474 case 8: 1475 index = (y * bytesPerLine) + x; 1476 for (int j = 0; j < putWidth; j++) { 1477 data[index] = (byte)(pixels[i] & 0xFF); 1478 i++; 1479 srcX++; 1480 if (srcX >= width) { 1481 srcY++; 1482 index = srcY * bytesPerLine; 1483 srcX = 0; 1484 } else { 1485 index++; 1486 } 1487 } 1488 return; 1489 case 4: 1490 index = (y * bytesPerLine) + (x >> 1); 1491 boolean high = (x & 0x1) == 0; 1492 while (n > 0) { 1493 theByte = pixels[i] & 0x0F; 1494 if (high) { 1495 data[index] = (byte)((data[index] & 0x0F) | (theByte << 4)); 1496 } else { 1497 data[index] = (byte)((data[index] & 0xF0) | theByte); 1498 } 1499 i++; 1500 n--; 1501 srcX++; 1502 if (srcX >= width) { 1503 srcY++; 1504 index = srcY * bytesPerLine; 1505 high = true; 1506 srcX = 0; 1507 } else { 1508 if (!high) index++; 1509 high = !high; 1510 } 1511 } 1512 return; 1513 case 2: 1514 byte [] masks = { (byte)0xFC, (byte)0xF3, (byte)0xCF, (byte)0x3F }; 1515 index = (y * bytesPerLine) + (x >> 2); 1516 int offset = 3 - (x % 4); 1517 while (n > 0) { 1518 theByte = pixels[i] & 0x3; 1519 data[index] = (byte)((data[index] & masks[offset]) | (theByte << (offset * 2))); 1520 i++; 1521 n--; 1522 srcX++; 1523 if (srcX >= width) { 1524 srcY++; 1525 index = srcY * bytesPerLine; 1526 offset = 3; 1527 srcX = 0; 1528 } else { 1529 if (offset == 0) { 1530 index++; 1531 offset = 3; 1532 } else { 1533 offset--; 1534 } 1535 } 1536 } 1537 return; 1538 case 1: 1539 index = (y * bytesPerLine) + (x >> 3); 1540 while (n > 0) { 1541 mask = 1 << (7 - (srcX & 0x7)); 1542 if ((pixels[i] & 0x1) == 1) { 1543 data[index] = (byte)((data[index] & 0xFF) | mask); 1544 } else { 1545 data[index] = (byte)((data[index] & 0xFF) & (mask ^ -1)); 1546 } 1547 i++; 1548 n--; 1549 srcX++; 1550 if (srcX >= width) { 1551 srcY++; 1552 index = srcY * bytesPerLine; 1553 srcX = 0; 1554 } else { 1555 if (mask == 1) { 1556 index++; 1557 } 1558 } 1559 } 1560 return; 1561 } 1562 SWT.error(SWT.ERROR_UNSUPPORTED_DEPTH); 1563} 1564 1565 1568static PaletteData bwPalette() { 1569 return new PaletteData(new RGB[] {new RGB(0, 0, 0), new RGB(255, 255, 255)}); 1570} 1571 1572 1576static int getMSBOffset(int mask) { 1577 for (int i = 31; i >= 0; i--) { 1578 if (((mask >> i) & 0x1) != 0) return i + 1; 1579 } 1580 return 0; 1581} 1582 1583 1586static int closestMatch(int depth, byte red, byte green, byte blue, int redMask, int greenMask, int blueMask, byte[] reds, byte[] greens, byte[] blues) { 1587 if (depth > 8) { 1588 int rshift = 32 - getMSBOffset(redMask); 1589 int gshift = 32 - getMSBOffset(greenMask); 1590 int bshift = 32 - getMSBOffset(blueMask); 1591 return (((red << 24) >>> rshift) & redMask) | 1592 (((green << 24) >>> gshift) & greenMask) | 1593 (((blue << 24) >>> bshift) & blueMask); 1594 } 1595 int r, g, b; 1596 int minDistance = 0x7fffffff; 1597 int nearestPixel = 0; 1598 int n = reds.length; 1599 for (int j = 0; j < n; j++) { 1600 r = (reds[j] & 0xFF) - (red & 0xFF); 1601 g = (greens[j] & 0xFF) - (green & 0xFF); 1602 b = (blues[j] & 0xFF) - (blue & 0xFF); 1603 int distance = r*r + g*g + b*b; 1604 if (distance < minDistance) { 1605 nearestPixel = j; 1606 if (distance == 0) break; 1607 minDistance = distance; 1608 } 1609 } 1610 return nearestPixel; 1611} 1612 1613static final ImageData convertMask(ImageData mask) { 1614 if (mask.depth == 1) return mask; 1615 PaletteData palette = new PaletteData(new RGB[] {new RGB(0, 0, 0), new RGB(255,255,255)}); 1616 ImageData newMask = new ImageData(mask.width, mask.height, 1, palette); 1617 1618 int blackIndex = 0; 1619 RGB[] rgbs = mask.getRGBs(); 1620 if (rgbs != null) { 1621 while (blackIndex < rgbs.length) { 1622 if (rgbs[blackIndex].equals(palette.colors[0])) break; 1623 blackIndex++; 1624 } 1625 } 1626 int[] pixels = new int[mask.width]; 1627 for (int y = 0; y < mask.height; y++) { 1628 mask.getPixels(0, y, mask.width, pixels, 0); 1629 for (int i = 0; i < pixels.length; i++) { 1630 if (pixels[i] == blackIndex) { 1631 pixels[i] = 0; 1632 } else { 1633 pixels[i] = 1; 1634 } 1635 } 1636 newMask.setPixels(0, y, mask.width, pixels, 0); 1637 } 1638 return newMask; 1639} 1640 1641static final byte[] convertPad(byte[] data, int width, int height, int depth, int pad, int newPad) { 1642 if (pad == newPad) return data; 1643 int stride = (width * depth + 7) / 8; 1644 int bpl = (stride + (pad - 1)) / pad * pad; 1645 int newBpl = (stride + (newPad - 1)) / newPad * newPad; 1646 byte[] newData = new byte[height * newBpl]; 1647 int srcIndex = 0, destIndex = 0; 1648 for (int y = 0; y < height; y++) { 1649 System.arraycopy(data, srcIndex, newData, destIndex, stride); 1650 srcIndex += bpl; 1651 destIndex += newBpl; 1652 } 1653 return newData; 1654} 1655 1656 1659static final int 1660 BLIT_SRC = 1, BLIT_ALPHA = 2, BLIT_DITHER = 4; 1664 1667static final int 1668 ALPHA_OPAQUE = 255, ALPHA_TRANSPARENT = 0, ALPHA_CHANNEL_SEPARATE = -1, ALPHA_CHANNEL_SOURCE = -2, ALPHA_MASK_UNPACKED = -3, ALPHA_MASK_PACKED = -4, ALPHA_MASK_INDEX = -5, ALPHA_MASK_RGB = -6; 1677 1680static final int LSB_FIRST = 0; 1681static final int MSB_FIRST = 1; 1682 1683 1686private static final int 1687 TYPE_GENERIC_8 = 0, 1689 TYPE_GENERIC_16_MSB = 1, 1690 TYPE_GENERIC_16_LSB = 2, 1691 TYPE_GENERIC_24 = 3, 1692 TYPE_GENERIC_32_MSB = 4, 1693 TYPE_GENERIC_32_LSB = 5, 1694 TYPE_INDEX_8 = 6, 1696 TYPE_INDEX_4 = 7, 1697 TYPE_INDEX_2 = 8, 1698 TYPE_INDEX_1_MSB = 9, 1699 TYPE_INDEX_1_LSB = 10; 1700 1701 1748static void blit(int op, 1749 byte[] srcData, int srcDepth, int srcStride, int srcOrder, 1750 int srcX, int srcY, int srcWidth, int srcHeight, 1751 int srcRedMask, int srcGreenMask, int srcBlueMask, 1752 int alphaMode, byte[] alphaData, int alphaStride, int alphaX, int alphaY, 1753 byte[] destData, int destDepth, int destStride, int destOrder, 1754 int destX, int destY, int destWidth, int destHeight, 1755 int destRedMask, int destGreenMask, int destBlueMask, 1756 boolean flipX, boolean flipY) { 1757 if ((destWidth <= 0) || (destHeight <= 0) || (alphaMode == ALPHA_TRANSPARENT)) return; 1758 1759 final int srcAlphaMask = 0, destAlphaMask = 0; 1761 1762 1763 final int dwm1 = destWidth - 1; 1764 final int sfxi = (dwm1 != 0) ? (int)((((long)srcWidth << 16) - 1) / dwm1) : 0; 1765 final int dhm1 = destHeight - 1; 1766 final int sfyi = (dhm1 != 0) ? (int)((((long)srcHeight << 16) - 1) / dhm1) : 0; 1767 1768 1769 final int sbpp, stype; 1770 switch (srcDepth) { 1771 case 8: 1772 sbpp = 1; 1773 stype = TYPE_GENERIC_8; 1774 break; 1775 case 16: 1776 sbpp = 2; 1777 stype = (srcOrder == MSB_FIRST) ? TYPE_GENERIC_16_MSB : TYPE_GENERIC_16_LSB; 1778 break; 1779 case 24: 1780 sbpp = 3; 1781 stype = TYPE_GENERIC_24; 1782 break; 1783 case 32: 1784 sbpp = 4; 1785 stype = (srcOrder == MSB_FIRST) ? TYPE_GENERIC_32_MSB : TYPE_GENERIC_32_LSB; 1786 break; 1787 default: 1788 return; 1790 } 1791 int spr = srcY * srcStride + srcX * sbpp; 1792 1793 1794 final int dbpp, dtype; 1795 switch (destDepth) { 1796 case 8: 1797 dbpp = 1; 1798 dtype = TYPE_GENERIC_8; 1799 break; 1800 case 16: 1801 dbpp = 2; 1802 dtype = (destOrder == MSB_FIRST) ? TYPE_GENERIC_16_MSB : TYPE_GENERIC_16_LSB; 1803 break; 1804 case 24: 1805 dbpp = 3; 1806 dtype = TYPE_GENERIC_24; 1807 break; 1808 case 32: 1809 dbpp = 4; 1810 dtype = (destOrder == MSB_FIRST) ? TYPE_GENERIC_32_MSB : TYPE_GENERIC_32_LSB; 1811 break; 1812 default: 1813 return; 1815 } 1816 int dpr = ((flipY) ? destY + dhm1 : destY) * destStride + ((flipX) ? destX + dwm1 : destX) * dbpp; 1817 final int dprxi = (flipX) ? -dbpp : dbpp; 1818 final int dpryi = (flipY) ? -destStride : destStride; 1819 1820 1821 int apr; 1822 if ((op & BLIT_ALPHA) != 0) { 1823 switch (alphaMode) { 1824 case ALPHA_MASK_UNPACKED: 1825 case ALPHA_CHANNEL_SEPARATE: 1826 if (alphaData == null) alphaMode = 0x10000; 1827 apr = alphaY * alphaStride + alphaX; 1828 break; 1829 case ALPHA_MASK_PACKED: 1830 if (alphaData == null) alphaMode = 0x10000; 1831 alphaStride <<= 3; 1832 apr = alphaY * alphaStride + alphaX; 1833 break; 1834 case ALPHA_MASK_INDEX: 1835 return; 1837 case ALPHA_MASK_RGB: 1838 if (alphaData == null) alphaMode = 0x10000; 1839 apr = 0; 1840 break; 1841 default: 1842 alphaMode = (alphaMode << 16) / 255; case ALPHA_CHANNEL_SOURCE: 1844 apr = 0; 1845 break; 1846 } 1847 } else { 1848 alphaMode = 0x10000; 1849 apr = 0; 1850 } 1851 1852 1853 int dp = dpr; 1854 int sp = spr; 1855 if ((alphaMode == 0x10000) && (stype == dtype) && 1856 (srcRedMask == destRedMask) && (srcGreenMask == destGreenMask) && 1857 (srcBlueMask == destBlueMask) && (srcAlphaMask == destAlphaMask)) { 1858 1859 switch (sbpp) { 1860 case 1: 1861 for (int dy = destHeight, sfy = sfyi; dy > 0; --dy, sp = spr += (sfy >>> 16) * srcStride, sfy = (sfy & 0xffff) + sfyi, dp = dpr += dpryi) { 1862 for (int dx = destWidth, sfx = sfxi; dx > 0; --dx, dp += dprxi, sfx = (sfx & 0xffff) + sfxi) { 1863 destData[dp] = srcData[sp]; 1864 sp += (sfx >>> 16); 1865 } 1866 } 1867 break; 1868 case 2: 1869 for (int dy = destHeight, sfy = sfyi; dy > 0; --dy, sp = spr += (sfy >>> 16) * srcStride, sfy = (sfy & 0xffff) + sfyi, dp = dpr += dpryi) { 1870 for (int dx = destWidth, sfx = sfxi; dx > 0; --dx, dp += dprxi, sfx = (sfx & 0xffff) + sfxi) { 1871 destData[dp] = srcData[sp]; 1872 destData[dp + 1] = srcData[sp + 1]; 1873 sp += (sfx >>> 16) * 2; 1874 } 1875 } 1876 break; 1877 case 3: 1878 for (int dy = destHeight, sfy = sfyi; dy > 0; --dy, sp = spr += (sfy >>> 16) * srcStride, sfy = (sfy & 0xffff) + sfyi, dp = dpr += dpryi) { 1879 for (int dx = destWidth, sfx = sfxi; dx > 0; --dx, dp += dprxi, sfx = (sfx & 0xffff) + sfxi) { 1880 destData[dp] = srcData[sp]; 1881 destData[dp + 1] = srcData[sp + 1]; 1882 destData[dp + 2] = srcData[sp + 2]; 1883 sp += (sfx >>> 16) * 3; 1884 } 1885 } 1886 break; 1887 case 4: 1888 for (int dy = destHeight, sfy = sfyi; dy > 0; --dy, sp = spr += (sfy >>> 16) * srcStride, sfy = (sfy & 0xffff) + sfyi, dp = dpr += dpryi) { 1889 for (int dx = destWidth, sfx = sfxi; dx > 0; --dx, dp += dprxi, sfx = (sfx & 0xffff) + sfxi) { 1890 destData[dp] = srcData[sp]; 1891 destData[dp + 1] = srcData[sp + 1]; 1892 destData[dp + 2] = srcData[sp + 2]; 1893 destData[dp + 3] = srcData[sp + 3]; 1894 sp += (sfx >>> 16) * 4; 1895 } 1896 } 1897 break; 1898 } 1899 return; 1900 } 1901 1902 final int srcRedShift = getChannelShift(srcRedMask); 1903 final byte[] srcReds = ANY_TO_EIGHT[getChannelWidth(srcRedMask, srcRedShift)]; 1904 final int srcGreenShift = getChannelShift(srcGreenMask); 1905 final byte[] srcGreens = ANY_TO_EIGHT[getChannelWidth(srcGreenMask, srcGreenShift)]; 1906 final int srcBlueShift = getChannelShift(srcBlueMask); 1907 final byte[] srcBlues = ANY_TO_EIGHT[getChannelWidth(srcBlueMask, srcBlueShift)]; 1908 final int srcAlphaShift = getChannelShift(srcAlphaMask); 1909 final byte[] srcAlphas = ANY_TO_EIGHT[getChannelWidth(srcAlphaMask, srcAlphaShift)]; 1910 1911 final int destRedShift = getChannelShift(destRedMask); 1912 final int destRedWidth = getChannelWidth(destRedMask, destRedShift); 1913 final byte[] destReds = ANY_TO_EIGHT[destRedWidth]; 1914 final int destRedPreShift = 8 - destRedWidth; 1915 final int destGreenShift = getChannelShift(destGreenMask); 1916 final int destGreenWidth = getChannelWidth(destGreenMask, destGreenShift); 1917 final byte[] destGreens = ANY_TO_EIGHT[destGreenWidth]; 1918 final int destGreenPreShift = 8 - destGreenWidth; 1919 final int destBlueShift = getChannelShift(destBlueMask); 1920 final int destBlueWidth = getChannelWidth(destBlueMask, destBlueShift); 1921 final byte[] destBlues = ANY_TO_EIGHT[destBlueWidth]; 1922 final int destBluePreShift = 8 - destBlueWidth; 1923 final int destAlphaShift = getChannelShift(destAlphaMask); 1924 final int destAlphaWidth = getChannelWidth(destAlphaMask, destAlphaShift); 1925 final byte[] destAlphas = ANY_TO_EIGHT[destAlphaWidth]; 1926 final int destAlphaPreShift = 8 - destAlphaWidth; 1927 1928 int ap = apr, alpha = alphaMode; 1929 int r = 0, g = 0, b = 0, a = 0; 1930 int rq = 0, gq = 0, bq = 0, aq = 0; 1931 for (int dy = destHeight, sfy = sfyi; dy > 0; --dy, 1932 sp = spr += (sfy >>> 16) * srcStride, 1933 ap = apr += (sfy >>> 16) * alphaStride, 1934 sfy = (sfy & 0xffff) + sfyi, 1935 dp = dpr += dpryi) { 1936 for (int dx = destWidth, sfx = sfxi; dx > 0; --dx, 1937 dp += dprxi, 1938 sfx = (sfx & 0xffff) + sfxi) { 1939 1940 switch (stype) { 1941 case TYPE_GENERIC_8: { 1942 final int data = srcData[sp] & 0xff; 1943 sp += (sfx >>> 16); 1944 r = srcReds[(data & srcRedMask) >>> srcRedShift] & 0xff; 1945 g = srcGreens[(data & srcGreenMask) >>> srcGreenShift] & 0xff; 1946 b = srcBlues[(data & srcBlueMask) >>> srcBlueShift] & 0xff; 1947 a = srcAlphas[(data & srcAlphaMask) >>> srcAlphaShift] & 0xff; 1948 } break; 1949 case TYPE_GENERIC_16_MSB: { 1950 final int data = ((srcData[sp] & 0xff) << 8) | (srcData[sp + 1] & 0xff); 1951 sp += (sfx >>> 16) * 2; 1952 r = srcReds[(data & srcRedMask) >>> srcRedShift] & 0xff; 1953 g = srcGreens[(data & srcGreenMask) >>> srcGreenShift] & 0xff; 1954 b = srcBlues[(data & srcBlueMask) >>> srcBlueShift] & 0xff; 1955 a = srcAlphas[(data & srcAlphaMask) >>> srcAlphaShift] & 0xff; 1956 } break; 1957 case TYPE_GENERIC_16_LSB: { 1958 final int data = ((srcData[sp + 1] & 0xff) << 8) | (srcData[sp] & 0xff); 1959 sp += (sfx >>> 16) * 2; 1960 r = srcReds[(data & srcRedMask) >>> srcRedShift] & 0xff; 1961 g = srcGreens[(data & srcGreenMask) >>> srcGreenShift] & 0xff; 1962 b = srcBlues[(data & srcBlueMask) >>> srcBlueShift] & 0xff; 1963 a = srcAlphas[(data & srcAlphaMask) >>> srcAlphaShift] & 0xff; 1964 } break; 1965 case TYPE_GENERIC_24: { 1966 final int data = (( ((srcData[sp] & 0xff) << 8) | 1967 (srcData[sp + 1] & 0xff)) << 8) | 1968 (srcData[sp + 2] & 0xff); 1969 sp += (sfx >>> 16) * 3; 1970 r = srcReds[(data & srcRedMask) >>> srcRedShift] & 0xff; 1971 g = srcGreens[(data & srcGreenMask) >>> srcGreenShift] & 0xff; 1972 b = srcBlues[(data & srcBlueMask) >>> srcBlueShift] & 0xff; 1973 a = srcAlphas[(data & srcAlphaMask) >>> srcAlphaShift] & 0xff; 1974 } break; 1975 case TYPE_GENERIC_32_MSB: { 1976 final int data = (( (( ((srcData[sp] & 0xff) << 8) | 1977 (srcData[sp + 1] & 0xff)) << 8) | 1978 (srcData[sp + 2] & 0xff)) << 8) | 1979 (srcData[sp + 3] & 0xff); 1980 sp += (sfx >>> 16) * 4; 1981 r = srcReds[(data & srcRedMask) >>> srcRedShift] & 0xff; 1982 g = srcGreens[(data & srcGreenMask) >>> srcGreenShift] & 0xff; 1983 b = srcBlues[(data & srcBlueMask) >>> srcBlueShift] & 0xff; 1984 a = srcAlphas[(data & srcAlphaMask) >>> srcAlphaShift] & 0xff; 1985 } break; 1986 case TYPE_GENERIC_32_LSB: { 1987 final int data = (( (( ((srcData[sp + 3] & 0xff) << 8) | 1988 (srcData[sp + 2] & 0xff)) << 8) | 1989 (srcData[sp + 1] & 0xff)) << 8) | 1990 (srcData[sp] & 0xff); 1991 sp += (sfx >>> 16) * 4; 1992 r = srcReds[(data & srcRedMask) >>> srcRedShift] & 0xff; 1993 g = srcGreens[(data & srcGreenMask) >>> srcGreenShift] & 0xff; 1994 b = srcBlues[(data & srcBlueMask) >>> srcBlueShift] & 0xff; 1995 a = srcAlphas[(data & srcAlphaMask) >>> srcAlphaShift] & 0xff; 1996 } break; 1997 } 1998 1999 2000 switch (alphaMode) { 2001 case ALPHA_CHANNEL_SEPARATE: 2002 alpha = ((alphaData[ap] & 0xff) << 16) / 255; 2003 ap += (sfx >> 16); 2004 break; 2005 case ALPHA_CHANNEL_SOURCE: 2006 alpha = (a << 16) / 255; 2007 break; 2008 case ALPHA_MASK_UNPACKED: 2009 alpha = (alphaData[ap] != 0) ? 0x10000 : 0; 2010 ap += (sfx >> 16); 2011 break; 2012 case ALPHA_MASK_PACKED: 2013 alpha = (alphaData[ap >> 3] << ((ap & 7) + 9)) & 0x10000; 2014 ap += (sfx >> 16); 2015 break; 2016 case ALPHA_MASK_RGB: 2017 alpha = 0x10000; 2018 for (int i = 0; i < alphaData.length; i += 3) { 2019 if ((r == alphaData[i]) && (g == alphaData[i + 1]) && (b == alphaData[i + 2])) { 2020 alpha = 0x0000; 2021 break; 2022 } 2023 } 2024 break; 2025 } 2026 if (alpha != 0x10000) { 2027 if (alpha == 0x0000) continue; 2028 switch (dtype) { 2029 case TYPE_GENERIC_8: { 2030 final int data = destData[dp] & 0xff; 2031 rq = destReds[(data & destRedMask) >>> destRedShift] & 0xff; 2032 gq = destGreens[(data & destGreenMask) >>> destGreenShift] & 0xff; 2033 bq = destBlues[(data & destBlueMask) >>> destBlueShift] & 0xff; 2034 aq = destAlphas[(data & destAlphaMask) >>> destAlphaShift] & 0xff; 2035 } break; 2036 case TYPE_GENERIC_16_MSB: { 2037 final int data = ((destData[dp] & 0xff) << 8) | (destData[dp + 1] & 0xff); 2038 rq = destReds[(data & destRedMask) >>> destRedShift] & 0xff; 2039 gq = destGreens[(data & destGreenMask) >>> destGreenShift] & 0xff; 2040 bq = destBlues[(data & destBlueMask) >>> destBlueShift] & 0xff; 2041 aq = destAlphas[(data & destAlphaMask) >>> destAlphaShift] & 0xff; 2042 } break; 2043 case TYPE_GENERIC_16_LSB: { 2044 final int data = ((destData[dp + 1] & 0xff) << 8) | (destData[dp] & 0xff); 2045 rq = destReds[(data & destRedMask) >>> destRedShift] & 0xff; 2046 gq = destGreens[(data & destGreenMask) >>> destGreenShift] & 0xff; 2047 bq = destBlues[(data & destBlueMask) >>> destBlueShift] & 0xff; 2048 aq = destAlphas[(data & destAlphaMask) >>> destAlphaShift] & 0xff; 2049 } break; 2050 case TYPE_GENERIC_24: { 2051 final int data = (( ((destData[dp] & 0xff) << 8) | 2052 (destData[dp + 1] & 0xff)) << 8) | 2053 (destData[dp + 2] & 0xff); 2054 rq = destReds[(data & destRedMask) >>> destRedShift] & 0xff; 2055 gq = destGreens[(data & destGreenMask) >>> destGreenShift] & 0xff; 2056 bq = destBlues[(data & destBlueMask) >>> destBlueShift] & 0xff; 2057 aq = destAlphas[(data & destAlphaMask) >>> destAlphaShift] & 0xff; 2058 } break; 2059 case TYPE_GENERIC_32_MSB: { 2060 final int data = (( (( ((destData[dp] & 0xff) << 8) | 2061 (destData[dp + 1] & 0xff)) << 8) | 2062 (destData[dp + 2] & 0xff)) << 8) | 2063 (destData[dp + 3] & 0xff); 2064 rq = destReds[(data & destRedMask) >>> destRedShift] & 0xff; 2065 gq = destGreens[(data & destGreenMask) >>> destGreenShift] & 0xff; 2066 bq = destBlues[(data & destBlueMask) >>> destBlueShift] & 0xff; 2067 aq = destAlphas[(data & destAlphaMask) >>> destAlphaShift] & 0xff; 2068 } break; 2069 case TYPE_GENERIC_32_LSB: { 2070 final int data = (( (( ((destData[dp + 3] & 0xff) << 8) | 2071 (destData[dp + 2] & 0xff)) << 8) | 2072 (destData[dp + 1] & 0xff)) << 8) | 2073 (destData[dp] & 0xff); 2074 rq = destReds[(data & destRedMask) >>> destRedShift] & 0xff; 2075 gq = destGreens[(data & destGreenMask) >>> destGreenShift] & 0xff; 2076 bq = destBlues[(data & destBlueMask) >>> destBlueShift] & 0xff; 2077 aq = destAlphas[(data & destAlphaMask) >>> destAlphaShift] & 0xff; 2078 } break; 2079 } 2080 a = aq + ((a - aq) * alpha >> 16); 2082 r = rq + ((r - rq) * alpha >> 16); 2083 g = gq + ((g - gq) * alpha >> 16); 2084 b = bq + ((b - bq) * alpha >> 16); 2085 } 2086 2087 2088 final int data = 2089 (r >>> destRedPreShift << destRedShift) | 2090 (g >>> destGreenPreShift << destGreenShift) | 2091 (b >>> destBluePreShift << destBlueShift) | 2092 (a >>> destAlphaPreShift << destAlphaShift); 2093 switch (dtype) { 2094 case TYPE_GENERIC_8: { 2095 destData[dp] = (byte) data; 2096 } break; 2097 case TYPE_GENERIC_16_MSB: { 2098 destData[dp] = (byte) (data >>> 8); 2099 destData[dp + 1] = (byte) (data & 0xff); 2100 } break; 2101 case TYPE_GENERIC_16_LSB: { 2102 destData[dp] = (byte) (data & 0xff); 2103 destData[dp + 1] = (byte) (data >>> 8); 2104 } break; 2105 case TYPE_GENERIC_24: { 2106 destData[dp] = (byte) (data >>> 16); 2107 destData[dp + 1] = (byte) (data >>> 8); 2108 destData[dp + 2] = (byte) (data & 0xff); 2109 } break; 2110 case TYPE_GENERIC_32_MSB: { 2111 destData[dp] = (byte) (data >>> 24); 2112 destData[dp + 1] = (byte) (data >>> 16); 2113 destData[dp + 2] = (byte) (data >>> 8); 2114 destData[dp + 3] = (byte) (data & 0xff); 2115 } break; 2116 case TYPE_GENERIC_32_LSB: { 2117 destData[dp] = (byte) (data & 0xff); 2118 destData[dp + 1] = (byte) (data >>> 8); 2119 destData[dp + 2] = (byte) (data >>> 16); 2120 destData[dp + 3] = (byte) (data >>> 24); 2121 } break; 2122 } 2123 } 2124 } 2125} 2126 2127 2173static void blit(int op, 2174 byte[] srcData, int srcDepth, int srcStride, int srcOrder, 2175 int srcX, int srcY, int srcWidth, int srcHeight, 2176 byte[] srcReds, byte[] srcGreens, byte[] srcBlues, 2177 int alphaMode, byte[] alphaData, int alphaStride, int alphaX, int alphaY, 2178 byte[] destData, int destDepth, int destStride, int destOrder, 2179 int destX, int destY, int destWidth, int destHeight, 2180 byte[] destReds, byte[] destGreens, byte[] destBlues, 2181 boolean flipX, boolean flipY) { 2182 if ((destWidth <= 0) || (destHeight <= 0) || (alphaMode == ALPHA_TRANSPARENT)) return; 2183 2184 2185 final int dwm1 = destWidth - 1; 2186 final int sfxi = (dwm1 != 0) ? (int)((((long)srcWidth << 16) - 1) / dwm1) : 0; 2187 final int dhm1 = destHeight - 1; 2188 final int sfyi = (dhm1 != 0) ? (int)((((long)srcHeight << 16) - 1) / dhm1) : 0; 2189 2190 2191 final int stype; 2192 switch (srcDepth) { 2193 case 8: 2194 stype = TYPE_INDEX_8; 2195 break; 2196 case 4: 2197 srcStride <<= 1; 2198 stype = TYPE_INDEX_4; 2199 break; 2200 case 2: 2201 srcStride <<= 2; 2202 stype = TYPE_INDEX_2; 2203 break; 2204 case 1: 2205 srcStride <<= 3; 2206 stype = (srcOrder == MSB_FIRST) ? TYPE_INDEX_1_MSB : TYPE_INDEX_1_LSB; 2207 break; 2208 default: 2209 return; 2211 } 2212 int spr = srcY * srcStride + srcX; 2213 2214 2215 final int dtype; 2216 switch (destDepth) { 2217 case 8: 2218 dtype = TYPE_INDEX_8; 2219 break; 2220 case 4: 2221 destStride <<= 1; 2222 dtype = TYPE_INDEX_4; 2223 break; 2224 case 2: 2225 destStride <<= 2; 2226 dtype = TYPE_INDEX_2; 2227 break; 2228 case 1: 2229 destStride <<= 3; 2230 dtype = (destOrder == MSB_FIRST) ? TYPE_INDEX_1_MSB : TYPE_INDEX_1_LSB; 2231 break; 2232 default: 2233 return; 2235 } 2236 int dpr = ((flipY) ? destY + dhm1 : destY) * destStride + ((flipX) ? destX + dwm1 : destX); 2237 final int dprxi = (flipX) ? -1 : 1; 2238 final int dpryi = (flipY) ? -destStride : destStride; 2239 2240 2241 int apr; 2242 if ((op & BLIT_ALPHA) != 0) { 2243 switch (alphaMode) { 2244 case ALPHA_MASK_UNPACKED: 2245 case ALPHA_CHANNEL_SEPARATE: 2246 if (alphaData == null) alphaMode = 0x10000; 2247 apr = alphaY * alphaStride + alphaX; 2248 break; 2249 case ALPHA_MASK_PACKED: 2250 if (alphaData == null) alphaMode = 0x10000; 2251 alphaStride <<= 3; 2252 apr = alphaY * alphaStride + alphaX; 2253 break; 2254 case ALPHA_MASK_INDEX: 2255 case ALPHA_MASK_RGB: 2256 if (alphaData == null) alphaMode = 0x10000; 2257 apr = 0; 2258 break; 2259 default: 2260 alphaMode = (alphaMode << 16) / 255; case ALPHA_CHANNEL_SOURCE: 2262 apr = 0; 2263 break; 2264 } 2265 } else { 2266 alphaMode = 0x10000; 2267 apr = 0; 2268 } 2269 final boolean ditherEnabled = (op & BLIT_DITHER) != 0; 2270 2271 2272 int dp = dpr; 2273 int sp = spr; 2274 int ap = apr; 2275 int destPaletteSize = 1 << destDepth; 2276 if ((destReds != null) && (destReds.length < destPaletteSize)) destPaletteSize = destReds.length; 2277 byte[] paletteMapping = null; 2278 boolean isExactPaletteMapping = true; 2279 switch (alphaMode) { 2280 case 0x10000: 2281 2282 if ((stype == dtype) && 2283 (srcReds == destReds) && (srcGreens == destGreens) && (srcBlues == destBlues)) { 2284 paletteMapping = ONE_TO_ONE_MAPPING; 2285 break; 2286 2287 } else if ((srcReds == null) || (destReds == null)) { 2288 if (srcDepth <= destDepth) { 2289 paletteMapping = ONE_TO_ONE_MAPPING; 2290 } else { 2291 paletteMapping = new byte[1 << srcDepth]; 2292 int mask = (0xff << destDepth) >>> 8; 2293 for (int i = 0; i < paletteMapping.length; ++i) paletteMapping[i] = (byte)(i & mask); 2294 } 2295 break; 2296 } 2297 case ALPHA_MASK_UNPACKED: 2298 case ALPHA_MASK_PACKED: 2299 case ALPHA_MASK_INDEX: 2300 case ALPHA_MASK_RGB: 2301 2302 int srcPaletteSize = 1 << srcDepth; 2303 paletteMapping = new byte[srcPaletteSize]; 2304 if ((srcReds != null) && (srcReds.length < srcPaletteSize)) srcPaletteSize = srcReds.length; 2305 for (int i = 0, r, g, b, index; i < srcPaletteSize; ++i) { 2306 r = srcReds[i] & 0xff; 2307 g = srcGreens[i] & 0xff; 2308 b = srcBlues[i] & 0xff; 2309 index = 0; 2310 int minDistance = 0x7fffffff; 2311 for (int j = 0, dr, dg, db, distance; j < destPaletteSize; ++j) { 2312 dr = (destReds[j] & 0xff) - r; 2313 dg = (destGreens[j] & 0xff) - g; 2314 db = (destBlues[j] & 0xff) - b; 2315 distance = dr * dr + dg * dg + db * db; 2316 if (distance < minDistance) { 2317 index = j; 2318 if (distance == 0) break; 2319 minDistance = distance; 2320 } 2321 } 2322 paletteMapping[i] = (byte)index; 2323 if (minDistance != 0) isExactPaletteMapping = false; 2324 } 2325 break; 2326 } 2327 if ((paletteMapping != null) && (isExactPaletteMapping || ! ditherEnabled)) { 2328 if ((stype == dtype) && (alphaMode == 0x10000)) { 2329 2330 switch (stype) { 2331 case TYPE_INDEX_8: 2332 for (int dy = destHeight, sfy = sfyi; dy > 0; --dy, sp = spr += (sfy >>> 16) * srcStride, sfy = (sfy & 0xffff) + sfyi, dp = dpr += dpryi) { 2333 for (int dx = destWidth, sfx = sfxi; dx > 0; --dx, dp += dprxi, sfx = (sfx & 0xffff) + sfxi) { 2334 destData[dp] = paletteMapping[srcData[sp] & 0xff]; 2335 sp += (sfx >>> 16); 2336 } 2337 } 2338 break; 2339 case TYPE_INDEX_4: 2340 for (int dy = destHeight, sfy = sfyi; dy > 0; --dy, sp = spr += (sfy >>> 16) * srcStride, sfy = (sfy & 0xffff) + sfyi, dp = dpr += dpryi) { 2341 for (int dx = destWidth, sfx = sfxi; dx > 0; --dx, dp += dprxi, sfx = (sfx & 0xffff) + sfxi) { 2342 final int v; 2343 if ((sp & 1) != 0) v = paletteMapping[srcData[sp >> 1] & 0x0f]; 2344 else v = (srcData[sp >> 1] >>> 4) & 0x0f; 2345 sp += (sfx >>> 16); 2346 if ((dp & 1) != 0) destData[dp >> 1] = (byte)((destData[dp >> 1] & 0xf0) | v); 2347 else destData[dp >> 1] = (byte)((destData[dp >> 1] & 0x0f) | (v << 4)); 2348 } 2349 } 2350 break; 2351 case TYPE_INDEX_2: 2352 for (int dy = destHeight, sfy = sfyi; dy > 0; --dy, sp = spr += (sfy >>> 16) * srcStride, sfy = (sfy & 0xffff) + sfyi, dp = dpr += dpryi) { 2353 for (int dx = destWidth, sfx = sfxi; dx > 0; --dx, dp += dprxi, sfx = (sfx & 0xffff) + sfxi) { 2354 final int index = paletteMapping[(srcData[sp >> 2] >>> (6 - (sp & 3) * 2)) & 0x03]; 2355 sp += (sfx >>> 16); 2356 final int shift = 6 - (dp & 3) * 2; 2357 destData[dp >> 2] = (byte)(destData[dp >> 2] & ~(0x03 << shift) | (index << shift)); 2358 } 2359 } 2360 break; 2361 case TYPE_INDEX_1_MSB: 2362 for (int dy = destHeight, sfy = sfyi; dy > 0; --dy, sp = spr += (sfy >>> 16) * srcStride, sfy = (sfy & 0xffff) + sfyi, dp = dpr += dpryi) { 2363 for (int dx = destWidth, sfx = sfxi; dx > 0; --dx, dp += dprxi, sfx = (sfx & 0xffff) + sfxi) { 2364 final int index = paletteMapping[(srcData[sp >> 3] >>> (7 - (sp & 7))) & 0x01]; 2365 sp += (sfx >>> 16); 2366 final int shift = 7 - (dp & 7); 2367 destData[dp >> 3] = (byte)(destData[dp >> 3] & ~(0x01 << shift) | (index << shift)); 2368 } 2369 } 2370 break; 2371 case TYPE_INDEX_1_LSB: 2372 for (int dy = destHeight, sfy = sfyi; dy > 0; --dy, sp = spr += (sfy >>> 16) * srcStride, sfy = (sfy & 0xffff) + sfyi, dp = dpr += dpryi) { 2373 for (int dx = destWidth, sfx = sfxi; dx > 0; --dx, dp += dprxi, sfx = (sfx & 0xffff) + sfxi) { 2374 final int index = paletteMapping[(srcData[sp >> 3] >>> (sp & 7)) & 0x01]; 2375 sp += (sfx >>> 16); 2376 final int shift = dp & 7; 2377 destData[dp >> 3] = (byte)(destData[dp >> 3] & ~(0x01 << shift) | (index << shift)); 2378 } 2379 } 2380 break; 2381 } 2382 } else { 2383 2384 for (int dy = destHeight, sfy = sfyi; dy > 0; --dy, 2385 sp = spr += (sfy >>> 16) * srcStride, 2386 sfy = (sfy & 0xffff) + sfyi, 2387 dp = dpr += dpryi) { 2388 for (int dx = destWidth, sfx = sfxi; dx > 0; --dx, 2389 dp += dprxi, 2390 sfx = (sfx & 0xffff) + sfxi) { 2391 int index; 2392 2393 switch (stype) { 2394 case TYPE_INDEX_8: 2395 index = srcData[sp] & 0xff; 2396 sp += (sfx >>> 16); 2397 break; 2398 case TYPE_INDEX_4: 2399 if ((sp & 1) != 0) index = srcData[sp >> 1] & 0x0f; 2400 else index = (srcData[sp >> 1] >>> 4) & 0x0f; 2401 sp += (sfx >>> 16); 2402 break; 2403 case TYPE_INDEX_2: 2404 index = (srcData[sp >> 2] >>> (6 - (sp & 3) * 2)) & 0x03; 2405 sp += (sfx >>> 16); 2406 break; 2407 case TYPE_INDEX_1_MSB: 2408 index = (srcData[sp >> 3] >>> (7 - (sp & 7))) & 0x01; 2409 sp += (sfx >>> 16); 2410 break; 2411 case TYPE_INDEX_1_LSB: 2412 index = (srcData[sp >> 3] >>> (sp & 7)) & 0x01; 2413 sp += (sfx >>> 16); 2414 break; 2415 default: 2416 return; 2417 } 2418 2419 switch (alphaMode) { 2420 case ALPHA_MASK_UNPACKED: { 2421 final byte mask = alphaData[ap]; 2422 ap += (sfx >> 16); 2423 if (mask == 0) continue; 2424 } break; 2425 case ALPHA_MASK_PACKED: { 2426 final int mask = alphaData[ap >> 3] & (1 << (ap & 7)); 2427 ap += (sfx >> 16); 2428 if (mask == 0) continue; 2429 } break; 2430 case ALPHA_MASK_INDEX: { 2431 int i = 0; 2432 while (i < alphaData.length) { 2433 if (index == (alphaData[i] & 0xff)) break; 2434 } 2435 if (i < alphaData.length) continue; 2436 } break; 2437 case ALPHA_MASK_RGB: { 2438 final byte r = srcReds[index], g = srcGreens[index], b = srcBlues[index]; 2439 int i = 0; 2440 while (i < alphaData.length) { 2441 if ((r == alphaData[i]) && (g == alphaData[i + 1]) && (b == alphaData[i + 2])) break; 2442 i += 3; 2443 } 2444 if (i < alphaData.length) continue; 2445 } break; 2446 } 2447 index = paletteMapping[index] & 0xff; 2448 2449 2450 switch (dtype) { 2451 case TYPE_INDEX_8: 2452 destData[dp] = (byte) index; 2453 break; 2454 case TYPE_INDEX_4: 2455 if ((dp & 1) != 0) destData[dp >> 1] = (byte)((destData[dp >> 1] & 0xf0) | index); 2456 else destData[dp >> 1] = (byte)((destData[dp >> 1] & 0x0f) | (index << 4)); 2457 break; 2458 case TYPE_INDEX_2: { 2459 final int shift = 6 - (dp & 3) * 2; 2460 destData[dp >> 2] = (byte)(destData[dp >> 2] & ~(0x03 << shift) | (index << shift)); 2461 } break; 2462 case TYPE_INDEX_1_MSB: { 2463 final int shift = 7 - (dp & 7); 2464 destData[dp >> 3] = (byte)(destData[dp >> 3] & ~(0x01 << shift) | (index << shift)); 2465 } break; 2466 case TYPE_INDEX_1_LSB: { 2467 final int shift = dp & 7; 2468 destData[dp >> 3] = (byte)(destData[dp >> 3] & ~(0x01 << shift) | (index << shift)); 2469 } break; 2470 } 2471 } 2472 } 2473 } 2474 return; 2475 } 2476 2477 2478 int alpha = alphaMode; 2479 int index = 0; 2480 int indexq = 0; 2481 int lastindex = 0, lastr = -1, lastg = -1, lastb = -1; 2482 final int[] rerr, gerr, berr; 2483 if (ditherEnabled) { 2484 rerr = new int[destWidth + 2]; 2485 gerr = new int[destWidth + 2]; 2486 berr = new int[destWidth + 2]; 2487 } else { 2488 rerr = null; gerr = null; berr = null; 2489 } 2490 for (int dy = destHeight, sfy = sfyi; dy > 0; --dy, 2491 sp = spr += (sfy >>> 16) * srcStride, 2492 ap = apr += (sfy >>> 16) * alphaStride, 2493 sfy = (sfy & 0xffff) + sfyi, 2494 dp = dpr += dpryi) { 2495 int lrerr = 0, lgerr = 0, lberr = 0; 2496 for (int dx = destWidth, sfx = sfxi; dx > 0; --dx, 2497 dp += dprxi, 2498 sfx = (sfx & 0xffff) + sfxi) { 2499 2500 switch (stype) { 2501 case TYPE_INDEX_8: 2502 index = srcData[sp] & 0xff; 2503 sp += (sfx >>> 16); 2504 break; 2505 case TYPE_INDEX_4: 2506 if ((sp & 1) != 0) index = srcData[sp >> 1] & 0x0f; 2507 else index = (srcData[sp >> 1] >>> 4) & 0x0f; 2508 sp += (sfx >>> 16); 2509 break; 2510 case TYPE_INDEX_2: 2511 index = (srcData[sp >> 2] >>> (6 - (sp & 3) * 2)) & 0x03; 2512 sp += (sfx >>> 16); 2513 break; 2514 case TYPE_INDEX_1_MSB: 2515 index = (srcData[sp >> 3] >>> (7 - (sp & 7))) & 0x01; 2516 sp += (sfx >>> 16); 2517 break; 2518 case TYPE_INDEX_1_LSB: 2519 index = (srcData[sp >> 3] >>> (sp & 7)) & 0x01; 2520 sp += (sfx >>> 16); 2521 break; 2522 } 2523 2524 2525 int r = srcReds[index] & 0xff, g = srcGreens[index] & 0xff, b = srcBlues[index] & 0xff; 2526 switch (alphaMode) { 2527 case ALPHA_CHANNEL_SEPARATE: 2528 alpha = ((alphaData[ap] & 0xff) << 16) / 255; 2529 ap += (sfx >> 16); 2530 break; 2531 case ALPHA_MASK_UNPACKED: 2532 alpha = (alphaData[ap] != 0) ? 0x10000 : 0; 2533 ap += (sfx >> 16); 2534 break; 2535 case ALPHA_MASK_PACKED: 2536 alpha = (alphaData[ap >> 3] << ((ap & 7) + 9)) & 0x10000; 2537 ap += (sfx >> 16); 2538 break; 2539 case ALPHA_MASK_INDEX: { int i = 0; 2541 while (i < alphaData.length) { 2542 if (index == (alphaData[i] & 0xff)) break; 2543 } 2544 if (i < alphaData.length) continue; 2545 } break; 2546 case ALPHA_MASK_RGB: { 2547 int i = 0; 2548 while (i < alphaData.length) { 2549 if ((r == (alphaData[i] & 0xff)) && 2550 (g == (alphaData[i + 1] & 0xff)) && 2551 (b == (alphaData[i + 2] & 0xff))) break; 2552 i += 3; 2553 } 2554 if (i < alphaData.length) continue; 2555 } break; 2556 } 2557 if (alpha != 0x10000) { 2558 if (alpha == 0x0000) continue; 2559 switch (dtype) { 2560 case TYPE_INDEX_8: 2561 indexq = destData[dp] & 0xff; 2562 break; 2563 case TYPE_INDEX_4: 2564 if ((dp & 1) != 0) indexq = destData[dp >> 1] & 0x0f; 2565 else indexq = (destData[dp >> 1] >>> 4) & 0x0f; 2566 break; 2567 case TYPE_INDEX_2: 2568 indexq = (destData[dp >> 2] >>> (6 - (dp & 3) * 2)) & 0x03; 2569 break; 2570 case TYPE_INDEX_1_MSB: 2571 indexq = (destData[dp >> 3] >>> (7 - (dp & 7))) & 0x01; 2572 break; 2573 case TYPE_INDEX_1_LSB: 2574 indexq = (destData[dp >> 3] >>> (dp & 7)) & 0x01; 2575 break; 2576 } 2577 final int rq = destReds[indexq] & 0xff; 2579 final int gq = destGreens[indexq] & 0xff; 2580 final int bq = destBlues[indexq] & 0xff; 2581 r = rq + ((r - rq) * alpha >> 16); 2582 g = gq + ((g - gq) * alpha >> 16); 2583 b = bq + ((b - bq) * alpha >> 16); 2584 } 2585 2586 2587 if (ditherEnabled) { 2588 r += rerr[dx] >> 4; 2590 if (r < 0) r = 0; else if (r > 255) r = 255; 2591 g += gerr[dx] >> 4; 2592 if (g < 0) g = 0; else if (g > 255) g = 255; 2593 b += berr[dx] >> 4; 2594 if (b < 0) b = 0; else if (b > 255) b = 255; 2595 rerr[dx] = lrerr; 2596 gerr[dx] = lgerr; 2597 berr[dx] = lberr; 2598 } 2599 if (r != lastr || g != lastg || b != lastb) { 2600 for (int j = 0, dr, dg, db, distance, minDistance = 0x7fffffff; j < destPaletteSize; ++j) { 2602 dr = (destReds[j] & 0xff) - r; 2603 dg = (destGreens[j] & 0xff) - g; 2604 db = (destBlues[j] & 0xff) - b; 2605 distance = dr * dr + dg * dg + db * db; 2606 if (distance < minDistance) { 2607 lastindex = j; 2608 if (distance == 0) break; 2609 minDistance = distance; 2610 } 2611 } 2612 lastr = r; lastg = g; lastb = b; 2613 } 2614 if (ditherEnabled) { 2615 final int dxm1 = dx - 1, dxp1 = dx + 1; 2617 int acc; 2618 rerr[dxp1] += acc = (lrerr = r - (destReds[lastindex] & 0xff)) + lrerr + lrerr; 2619 rerr[dx] += acc += lrerr + lrerr; 2620 rerr[dxm1] += acc + lrerr + lrerr; 2621 gerr[dxp1] += acc = (lgerr = g - (destGreens[lastindex] & 0xff)) + lgerr + lgerr; 2622 gerr[dx] += acc += lgerr + lgerr; 2623 gerr[dxm1] += acc + lgerr + lgerr; 2624 berr[dxp1] += acc = (lberr = b - (destBlues[lastindex] & 0xff)) + lberr + lberr; 2625 berr[dx] += acc += lberr + lberr; 2626 berr[dxm1] += acc + lberr + lberr; 2627 } 2628 2629 2630 switch (dtype) { 2631 case TYPE_INDEX_8: 2632 destData[dp] = (byte) lastindex; 2633 break; 2634 case TYPE_INDEX_4: 2635 if ((dp & 1) != 0) destData[dp >> 1] = (byte)((destData[dp >> 1] & 0xf0) | lastindex); 2636 else destData[dp >> 1] = (byte)((destData[dp >> 1] & 0x0f) | (lastindex << 4)); 2637 break; 2638 case TYPE_INDEX_2: { 2639 final int shift = 6 - (dp & 3) * 2; 2640 destData[dp >> 2] = (byte)(destData[dp >> 2] & ~(0x03 << shift) | (lastindex << shift)); 2641 } break; 2642 case TYPE_INDEX_1_MSB: { 2643 final int shift = 7 - (dp & 7); 2644 destData[dp >> 3] = (byte)(destData[dp >> 3] & ~(0x01 << shift) | (lastindex << shift)); 2645 } break; 2646 case TYPE_INDEX_1_LSB: { 2647 final int shift = dp & 7; 2648 destData[dp >> 3] = (byte)(destData[dp >> 3] & ~(0x01 << shift) | (lastindex << shift)); 2649 } break; 2650 } 2651 } 2652 } 2653} 2654 2655 2700static void blit(int op, 2701 byte[] srcData, int srcDepth, int srcStride, int srcOrder, 2702 int srcX, int srcY, int srcWidth, int srcHeight, 2703 byte[] srcReds, byte[] srcGreens, byte[] srcBlues, 2704 int alphaMode, byte[] alphaData, int alphaStride, int alphaX, int alphaY, 2705 byte[] destData, int destDepth, int destStride, int destOrder, 2706 int destX, int destY, int destWidth, int destHeight, 2707 int destRedMask, int destGreenMask, int destBlueMask, 2708 boolean flipX, boolean flipY) { 2709 if ((destWidth <= 0) || (destHeight <= 0) || (alphaMode == ALPHA_TRANSPARENT)) return; 2710 2711 final int destAlphaMask = 0; 2713 2714 2715 final int dwm1 = destWidth - 1; 2716 final int sfxi = (dwm1 != 0) ? (int)((((long)srcWidth << 16) - 1) / dwm1) : 0; 2717 final int dhm1 = destHeight - 1; 2718 final int sfyi = (dhm1 != 0) ? (int)((((long)srcHeight << 16) - 1) / dhm1) : 0; 2719 2720 2721 final int stype; 2722 switch (srcDepth) { 2723 case 8: 2724 stype = TYPE_INDEX_8; 2725 break; 2726 case 4: 2727 srcStride <<= 1; 2728 stype = TYPE_INDEX_4; 2729 break; 2730 case 2: 2731 srcStride <<= 2; 2732 stype = TYPE_INDEX_2; 2733 break; 2734 case 1: 2735 srcStride <<= 3; 2736 stype = (srcOrder == MSB_FIRST) ? TYPE_INDEX_1_MSB : TYPE_INDEX_1_LSB; 2737 break; 2738 default: 2739 return; 2741 } 2742 int spr = srcY * srcStride + srcX; 2743 2744 2745 final int dbpp, dtype; 2746 switch (destDepth) { 2747 case 8: 2748 dbpp = 1; 2749 dtype = TYPE_GENERIC_8; 2750 break; 2751 case 16: 2752 dbpp = 2; 2753 dtype = (destOrder == MSB_FIRST) ? TYPE_GENERIC_16_MSB : TYPE_GENERIC_16_LSB; 2754 break; 2755 case 24: 2756 dbpp = 3; 2757 dtype = TYPE_GENERIC_24; 2758 break; 2759 case 32: 2760 dbpp = 4; 2761 dtype = (destOrder == MSB_FIRST) ? TYPE_GENERIC_32_MSB : TYPE_GENERIC_32_LSB; 2762 break; 2763 default: 2764 return; 2766 } 2767 int dpr = ((flipY) ? destY + dhm1 : destY) * destStride + ((flipX) ? destX + dwm1 : destX) * dbpp; 2768 final int dprxi = (flipX) ? -dbpp : dbpp; 2769 final int dpryi = (flipY) ? -destStride : destStride; 2770 2771 2772 int apr; 2773 if ((op & BLIT_ALPHA) != 0) { 2774 switch (alphaMode) { 2775 case ALPHA_MASK_UNPACKED: 2776 case ALPHA_CHANNEL_SEPARATE: 2777 if (alphaData == null) alphaMode = 0x10000; 2778 apr = alphaY * alphaStride + alphaX; 2779 break; 2780 case ALPHA_MASK_PACKED: 2781 if (alphaData == null) alphaMode = 0x10000; 2782 alphaStride <<= 3; 2783 apr = alphaY * alphaStride + alphaX; 2784 break; 2785 case ALPHA_MASK_INDEX: 2786 case ALPHA_MASK_RGB: 2787 if (alphaData == null) alphaMode = 0x10000; 2788 apr = 0; 2789 break; 2790 default: 2791 alphaMode = (alphaMode << 16) / 255; case ALPHA_CHANNEL_SOURCE: 2793 apr = 0; 2794 break; 2795 } 2796 } else { 2797 alphaMode = 0x10000; 2798 apr = 0; 2799 } 2800 2801 2802 final int destRedShift = getChannelShift(destRedMask); 2803 final int destRedWidth = getChannelWidth(destRedMask, destRedShift); 2804 final byte[] destReds = ANY_TO_EIGHT[destRedWidth]; 2805 final int destRedPreShift = 8 - destRedWidth; 2806 final int destGreenShift = getChannelShift(destGreenMask); 2807 final int destGreenWidth = getChannelWidth(destGreenMask, destGreenShift); 2808 final byte[] destGreens = ANY_TO_EIGHT[destGreenWidth]; 2809 final int destGreenPreShift = 8 - destGreenWidth; 2810 final int destBlueShift = getChannelShift(destBlueMask); 2811 final int destBlueWidth = getChannelWidth(destBlueMask, destBlueShift); 2812 final byte[] destBlues = ANY_TO_EIGHT[destBlueWidth]; 2813 final int destBluePreShift = 8 - destBlueWidth; 2814 final int destAlphaShift = getChannelShift(destAlphaMask); 2815 final int destAlphaWidth = getChannelWidth(destAlphaMask, destAlphaShift); 2816 final byte[] destAlphas = ANY_TO_EIGHT[destAlphaWidth]; 2817 final int destAlphaPreShift = 8 - destAlphaWidth; 2818 2819 int dp = dpr; 2820 int sp = spr; 2821 int ap = apr, alpha = alphaMode; 2822 int r = 0, g = 0, b = 0, a = 0, index = 0; 2823 int rq = 0, gq = 0, bq = 0, aq = 0; 2824 for (int dy = destHeight, sfy = sfyi; dy > 0; --dy, 2825 sp = spr += (sfy >>> 16) * srcStride, 2826 ap = apr += (sfy >>> 16) * alphaStride, 2827 sfy = (sfy & 0xffff) + sfyi, 2828 dp = dpr += dpryi) { 2829 for (int dx = destWidth, sfx = sfxi; dx > 0; --dx, 2830 dp += dprxi, 2831 sfx = (sfx & 0xffff) + sfxi) { 2832 2833 switch (stype) { 2834 case TYPE_INDEX_8: 2835 index = srcData[sp] & 0xff; 2836 sp += (sfx >>> 16); 2837 break; 2838 case TYPE_INDEX_4: 2839 if ((sp & 1) != 0) index = srcData[sp >> 1] & 0x0f; 2840 else index = (srcData[sp >> 1] >>> 4) & 0x0f; 2841 sp += (sfx >>> 16); 2842 break; 2843 case TYPE_INDEX_2: 2844 index = (srcData[sp >> 2] >>> (6 - (sp & 3) * 2)) & 0x03; 2845 sp += (sfx >>> 16); 2846 break; 2847 case TYPE_INDEX_1_MSB: 2848 index = (srcData[sp >> 3] >>> (7 - (sp & 7))) & 0x01; 2849 sp += (sfx >>> 16); 2850 break; 2851 case TYPE_INDEX_1_LSB: 2852 index = (srcData[sp >> 3] >>> (sp & 7)) & 0x01; 2853 sp += (sfx >>> 16); 2854 break; 2855 } 2856 2857 2858 r = srcReds[index] & 0xff; 2859 g = srcGreens[index] & 0xff; 2860 b = srcBlues[index] & 0xff; 2861 switch (alphaMode) { 2862 case ALPHA_CHANNEL_SEPARATE: 2863 alpha = ((alphaData[ap] & 0xff) << 16) / 255; 2864 ap += (sfx >> 16); 2865 break; 2866 case ALPHA_MASK_UNPACKED: 2867 alpha = (alphaData[ap] != 0) ? 0x10000 : 0; 2868 ap += (sfx >> 16); 2869 break; 2870 case ALPHA_MASK_PACKED: 2871 alpha = (alphaData[ap >> 3] << ((ap & 7) + 9)) & 0x10000; 2872 ap += (sfx >> 16); 2873 break; 2874 case ALPHA_MASK_INDEX: { int i = 0; 2876 while (i < alphaData.length) { 2877 if (index == (alphaData[i] & 0xff)) break; 2878 } 2879 if (i < alphaData.length) continue; 2880 } break; 2881 case ALPHA_MASK_RGB: { 2882 int i = 0; 2883 while (i < alphaData.length) { 2884 if ((r == (alphaData[i] & 0xff)) && 2885 (g == (alphaData[i + 1] & 0xff)) && 2886 (b == (alphaData[i + 2] & 0xff))) break; 2887 i += 3; 2888 } 2889 if (i < alphaData.length) continue; 2890 } break; 2891 } 2892 if (alpha != 0x10000) { 2893 if (alpha == 0x0000) continue; 2894 switch (dtype) { 2895 case TYPE_GENERIC_8: { 2896 final int data = destData[dp] & 0xff; 2897 rq = destReds[(data & destRedMask) >>> destRedShift] & 0xff; 2898 gq = destGreens[(data & destGreenMask) >>> destGreenShift] & 0xff; 2899 bq = destBlues[(data & destBlueMask) >>> destBlueShift] & 0xff; 2900 aq = destAlphas[(data & destAlphaMask) >>> destAlphaShift] & 0xff; 2901 } break; 2902 case TYPE_GENERIC_16_MSB: { 2903 final int data = ((destData[dp] & 0xff) << 8) | (destData[dp + 1] & 0xff); 2904 rq = destReds[(data & destRedMask) >>> destRedShift] & 0xff; 2905 gq = destGreens[(data & destGreenMask) >>> destGreenShift] & 0xff; 2906 bq = destBlues[(data & destBlueMask) >>> destBlueShift] & 0xff; 2907 aq = destAlphas[(data & destAlphaMask) >>> destAlphaShift] & 0xff; 2908 } break; 2909 case TYPE_GENERIC_16_LSB: { 2910 final int data = ((destData[dp + 1] & 0xff) << 8) | (destData[dp] & 0xff); 2911 rq = destReds[(data & destRedMask) >>> destRedShift] & 0xff; 2912 gq = destGreens[(data & destGreenMask) >>> destGreenShift] & 0xff; 2913 bq = destBlues[(data & destBlueMask) >>> destBlueShift] & 0xff; 2914 aq = destAlphas[(data & destAlphaMask) >>> destAlphaShift] & 0xff; 2915 } break; 2916 case TYPE_GENERIC_24: { 2917 final int data = (( ((destData[dp] & 0xff) << 8) | 2918 (destData[dp + 1] & 0xff)) << 8) | 2919 (destData[dp + 2] & 0xff); 2920 rq = destReds[(data & destRedMask) >>> destRedShift] & 0xff; 2921 gq = destGreens[(data & destGreenMask) >>> destGreenShift] & 0xff; 2922 bq = destBlues[(data & destBlueMask) >>> destBlueShift] & 0xff; 2923 aq = destAlphas[(data & destAlphaMask) >>> destAlphaShift] & 0xff; 2924 } break; 2925 case TYPE_GENERIC_32_MSB: { 2926 final int data = (( (( ((destData[dp] & 0xff) << 8) | 2927 (destData[dp + 1] & 0xff)) << 8) | 2928 (destData[dp + 2] & 0xff)) << 8) | 2929 (destData[dp + 3] & 0xff); 2930 rq = destReds[(data & destRedMask) >>> destRedShift] & 0xff; 2931 gq = destGreens[(data & destGreenMask) >>> destGreenShift] & 0xff; 2932 bq = destBlues[(data & destBlueMask) >>> destBlueShift] & 0xff; 2933 aq = destAlphas[(data & destAlphaMask) >>> destAlphaShift] & 0xff; 2934 } break; 2935 case TYPE_GENERIC_32_LSB: { 2936 final int data = (( (( ((destData[dp + 3] & 0xff) << 8) | 2937 (destData[dp + 2] & 0xff)) << 8) | 2938 (destData[dp + 1] & 0xff)) << 8) | 2939 (destData[dp] & 0xff); 2940 rq = destReds[(data & destRedMask) >>> destRedShift] & 0xff; 2941 gq = destGreens[(data & destGreenMask) >>> destGreenShift] & 0xff; 2942 bq = destBlues[(data & destBlueMask) >>> destBlueShift] & 0xff; 2943 aq = destAlphas[(data & destAlphaMask) >>> destAlphaShift] & 0xff; 2944 } break; 2945 } 2946 a = aq + ((a - aq) * alpha >> 16); 2948 r = rq + ((r - rq) * alpha >> 16); 2949 g = gq + ((g - gq) * alpha >> 16); 2950 b = bq + ((b - bq) * alpha >> 16); 2951 } 2952 2953 2954 final int data = 2955 (r >>> destRedPreShift << destRedShift) | 2956 (g >>> destGreenPreShift << destGreenShift) | 2957 (b >>> destBluePreShift << destBlueShift) | 2958 (a >>> destAlphaPreShift << destAlphaShift); 2959 switch (dtype) { 2960 case TYPE_GENERIC_8: { 2961 destData[dp] = (byte) data; 2962 } break; 2963 case TYPE_GENERIC_16_MSB: { 2964 destData[dp] = (byte) (data >>> 8); 2965 destData[dp + 1] = (byte) (data & 0xff); 2966 } break; 2967 case TYPE_GENERIC_16_LSB: { 2968 destData[dp] = (byte) (data & 0xff); 2969 destData[dp + 1] = (byte) (data >>> 8); 2970 } break; 2971 case TYPE_GENERIC_24: { 2972 destData[dp] = (byte) (data >>> 16); 2973 destData[dp + 1] = (byte) (data >>> 8); 2974 destData[dp + 2] = (byte) (data & 0xff); 2975 } break; 2976 case TYPE_GENERIC_32_MSB: { 2977 destData[dp] = (byte) (data >>> 24); 2978 destData[dp + 1] = (byte) (data >>> 16); 2979 destData[dp + 2] = (byte) (data >>> 8); 2980 destData[dp + 3] = (byte) (data & 0xff); 2981 } break; 2982 case TYPE_GENERIC_32_LSB: { 2983 destData[dp] = (byte) (data & 0xff); 2984 destData[dp + 1] = (byte) (data >>> 8); 2985 destData[dp + 2] = (byte) (data >>> 16); 2986 destData[dp + 3] = (byte) (data >>> 24); 2987 } break; 2988 } 2989 } 2990 } 2991} 2992 2993 3038static void blit(int op, 3039 byte[] srcData, int srcDepth, int srcStride, int srcOrder, 3040 int srcX, int srcY, int srcWidth, int srcHeight, 3041 int srcRedMask, int srcGreenMask, int srcBlueMask, 3042 int alphaMode, byte[] alphaData, int alphaStride, int alphaX, int alphaY, 3043 byte[] destData, int destDepth, int destStride, int destOrder, 3044 int destX, int destY, int destWidth, int destHeight, 3045 byte[] destReds, byte[] destGreens, byte[] destBlues, 3046 boolean flipX, boolean flipY) { 3047 if ((destWidth <= 0) || (destHeight <= 0) || (alphaMode == ALPHA_TRANSPARENT)) return; 3048 3049 final int srcAlphaMask = 0; 3051 3052 3053 final int dwm1 = destWidth - 1; 3054 final int sfxi = (dwm1 != 0) ? (int)((((long)srcWidth << 16) - 1) / dwm1) : 0; 3055 final int dhm1 = destHeight - 1; 3056 final int sfyi = (dhm1 != 0) ? (int)((((long)srcHeight << 16) - 1) / dhm1) : 0; 3057 3058 3059 final int sbpp, stype; 3060 switch (srcDepth) { 3061 case 8: 3062 sbpp = 1; 3063 stype = TYPE_GENERIC_8; 3064 break; 3065 case 16: 3066 sbpp = 2; 3067 stype = (srcOrder == MSB_FIRST) ? TYPE_GENERIC_16_MSB : TYPE_GENERIC_16_LSB; 3068 break; 3069 case 24: 3070 sbpp = 3; 3071 stype = TYPE_GENERIC_24; 3072 break; 3073 case 32: 3074 sbpp = 4; 3075 stype = (srcOrder == MSB_FIRST) ? TYPE_GENERIC_32_MSB : TYPE_GENERIC_32_LSB; 3076 break; 3077 default: 3078 return; 3080 } 3081 int spr = srcY * srcStride + srcX * sbpp; 3082 3083 3084 final int dtype; 3085 switch (destDepth) { 3086 case 8: 3087 dtype = TYPE_INDEX_8; 3088 break; 3089 case 4: 3090 destStride <<= 1; 3091 dtype = TYPE_INDEX_4; 3092 break; 3093 case 2: 3094 destStride <<= 2; 3095 dtype = TYPE_INDEX_2; 3096 break; 3097 case 1: 3098 destStride <<= 3; 3099 dtype = (destOrder == MSB_FIRST) ? TYPE_INDEX_1_MSB : TYPE_INDEX_1_LSB; 3100 break; 3101 default: 3102 return; 3104 } 3105 int dpr = ((flipY) ? destY + dhm1 : destY) * destStride + ((flipX) ? destX + dwm1 : destX); 3106 final int dprxi = (flipX) ? -1 : 1; 3107 final int dpryi = (flipY) ? -destStride : destStride; 3108 3109 3110 int apr; 3111 if ((op & BLIT_ALPHA) != 0) { 3112 switch (alphaMode) { 3113 case ALPHA_MASK_UNPACKED: 3114 case ALPHA_CHANNEL_SEPARATE: 3115 if (alphaData == null) alphaMode = 0x10000; 3116 apr = alphaY * alphaStride + alphaX; 3117 break; 3118 case ALPHA_MASK_PACKED: 3119 if (alphaData == null) alphaMode = 0x10000; 3120 alphaStride <<= 3; 3121 apr = alphaY * alphaStride + alphaX; 3122 break; 3123 case ALPHA_MASK_INDEX: 3124 return; 3126 case ALPHA_MASK_RGB: 3127 if (alphaData == null) alphaMode = 0x10000; 3128 apr = 0; 3129 break; 3130 default: 3131 alphaMode = (alphaMode << 16) / 255; case ALPHA_CHANNEL_SOURCE: 3133 apr = 0; 3134 break; 3135 } 3136 } else { 3137 alphaMode = 0x10000; 3138 apr = 0; 3139 } 3140 final boolean ditherEnabled = (op & BLIT_DITHER) != 0; 3141 3142 3143 final int srcRedShift = getChannelShift(srcRedMask); 3144 final byte[] srcReds = ANY_TO_EIGHT[getChannelWidth(srcRedMask, srcRedShift)]; 3145 final int srcGreenShift = getChannelShift(srcGreenMask); 3146 final byte[] srcGreens = ANY_TO_EIGHT[getChannelWidth(srcGreenMask, srcGreenShift)]; 3147 final int srcBlueShift = getChannelShift(srcBlueMask); 3148 final byte[] srcBlues = ANY_TO_EIGHT[getChannelWidth(srcBlueMask, srcBlueShift)]; 3149 final int srcAlphaShift = getChannelShift(srcAlphaMask); 3150 final byte[] srcAlphas = ANY_TO_EIGHT[getChannelWidth(srcAlphaMask, srcAlphaShift)]; 3151 3152 int dp = dpr; 3153 int sp = spr; 3154 int ap = apr, alpha = alphaMode; 3155 int r = 0, g = 0, b = 0, a = 0; 3156 int indexq = 0; 3157 int lastindex = 0, lastr = -1, lastg = -1, lastb = -1; 3158 final int[] rerr, gerr, berr; 3159 int destPaletteSize = 1 << destDepth; 3160 if ((destReds != null) && (destReds.length < destPaletteSize)) destPaletteSize = destReds.length; 3161 if (ditherEnabled) { 3162 rerr = new int[destWidth + 2]; 3163 gerr = new int[destWidth + 2]; 3164 berr = new int[destWidth + 2]; 3165 } else { 3166 rerr = null; gerr = null; berr = null; 3167 } 3168 for (int dy = destHeight, sfy = sfyi; dy > 0; --dy, 3169 sp = spr += (sfy >>> 16) * srcStride, 3170 ap = apr += (sfy >>> 16) * alphaStride, 3171 sfy = (sfy & 0xffff) + sfyi, 3172 dp = dpr += dpryi) { 3173 int lrerr = 0, lgerr = 0, lberr = 0; 3174 for (int dx = destWidth, sfx = sfxi; dx > 0; --dx, 3175 dp += dprxi, 3176 sfx = (sfx & 0xffff) + sfxi) { 3177 3178 switch (stype) { 3179 case TYPE_GENERIC_8: { 3180 final int data = srcData[sp] & 0xff; 3181 sp += (sfx >>> 16); 3182 r = srcReds[(data & srcRedMask) >>> srcRedShift] & 0xff; 3183 g = srcGreens[(data & srcGreenMask) >>> srcGreenShift] & 0xff; 3184 b = srcBlues[(data & srcBlueMask) >>> srcBlueShift] & 0xff; 3185 a = srcAlphas[(data & srcAlphaMask) >>> srcAlphaShift] & 0xff; 3186 } break; 3187 case TYPE_GENERIC_16_MSB: { 3188 final int data = ((srcData[sp] & 0xff) << 8) | (srcData[sp + 1] & 0xff); 3189 sp += (sfx >>> 16) * 2; 3190 r = srcReds[(data & srcRedMask) >>> srcRedShift] & 0xff; 3191 g = srcGreens[(data & srcGreenMask) >>> srcGreenShift] & 0xff; 3192 b = srcBlues[(data & srcBlueMask) >>> srcBlueShift] & 0xff; 3193 a = srcAlphas[(data & srcAlphaMask) >>> srcAlphaShift] & 0xff; 3194 } break; 3195 case TYPE_GENERIC_16_LSB: { 3196 final int data = ((srcData[sp + 1] & 0xff) << 8) | (srcData[sp] & 0xff); 3197 sp += (sfx >>> 16) * 2; 3198 r = srcReds[(data & srcRedMask) >>> srcRedShift] & 0xff; 3199 g = srcGreens[(data & srcGreenMask) >>> srcGreenShift] & 0xff; 3200 b = srcBlues[(data & srcBlueMask) >>> srcBlueShift] & 0xff; 3201 a = srcAlphas[(data & srcAlphaMask) >>> srcAlphaShift] & 0xff; 3202 } break; 3203 case TYPE_GENERIC_24: { 3204 final int data = (( ((srcData[sp] & 0xff) << 8) | 3205 (srcData[sp + 1] & 0xff)) << 8) | 3206 (srcData[sp + 2] & 0xff); 3207 sp += (sfx >>> 16) * 3; 3208 r = srcReds[(data & srcRedMask) >>> srcRedShift] & 0xff; 3209 g = srcGreens[(data & srcGreenMask) >>> srcGreenShift] & 0xff; 3210 b = srcBlues[(data & srcBlueMask) >>> srcBlueShift] & 0xff; 3211 a = srcAlphas[(data & srcAlphaMask) >>> srcAlphaShift] & 0xff; 3212 } break; 3213 case TYPE_GENERIC_32_MSB: { 3214 final int data = (( (( ((srcData[sp] & 0xff) << 8) | 3215 (srcData[sp + 1] & 0xff)) << 8) | 3216 (srcData[sp + 2] & 0xff)) << 8) | 3217 (srcData[sp + 3] & 0xff); 3218 sp += (sfx >>> 16) * 4; 3219 r = srcReds[(data & srcRedMask) >>> srcRedShift] & 0xff; 3220 g = srcGreens[(data & srcGreenMask) >>> srcGreenShift] & 0xff; 3221 b = srcBlues[(data & srcBlueMask) >>> srcBlueShift] & 0xff; 3222 a = srcAlphas[(data & srcAlphaMask) >>> srcAlphaShift] & 0xff; 3223 } break; 3224 case TYPE_GENERIC_32_LSB: { 3225 final int data = (( (( ((srcData[sp + 3] & 0xff) << 8) | 3226 (srcData[sp + 2] & 0xff)) << 8) | 3227 (srcData[sp + 1] & 0xff)) << 8) | 3228 (srcData[sp] & 0xff); 3229 sp += (sfx >>> 16) * 4; 3230 r = srcReds[(data & srcRedMask) >>> srcRedShift] & 0xff; 3231 g = srcGreens[(data & srcGreenMask) >>> srcGreenShift] & 0xff; 3232 b = srcBlues[(data & srcBlueMask) >>> srcBlueShift] & 0xff; 3233 a = srcAlphas[(data & srcAlphaMask) >>> srcAlphaShift] & 0xff; 3234 } break; 3235 } 3236 3237 3238 switch (alphaMode) { 3239 case ALPHA_CHANNEL_SEPARATE: 3240 alpha = ((alphaData[ap] & 0xff) << 16) / 255; 3241 ap += (sfx >> 16); 3242 break; 3243 case ALPHA_CHANNEL_SOURCE: 3244 alpha = (a << 16) / 255; 3245 break; 3246 case ALPHA_MASK_UNPACKED: 3247 alpha = (alphaData[ap] != 0) ? 0x10000 : 0; 3248 ap += (sfx >> 16); 3249 break; 3250 case ALPHA_MASK_PACKED: 3251 alpha = (alphaData[ap >> 3] << ((ap & 7) + 9)) & 0x10000; 3252 ap += (sfx >> 16); 3253 break; 3254 case ALPHA_MASK_RGB: 3255 alpha = 0x10000; 3256 for (int i = 0; i < alphaData.length; i += 3) { 3257 if ((r == alphaData[i]) && (g == alphaData[i + 1]) && (b == alphaData[i + 2])) { 3258 alpha = 0x0000; 3259 break; 3260 } 3261 } 3262 break; 3263 } 3264 if (alpha != 0x10000) { 3265 if (alpha == 0x0000) continue; 3266 switch (dtype) { 3267 case TYPE_INDEX_8: 3268 indexq = destData[dp] & 0xff; 3269 break; 3270 case TYPE_INDEX_4: 3271 if ((dp & 1) != 0) indexq = destData[dp >> 1] & 0x0f; 3272 else indexq = (destData[dp >> 1] >>> 4) & 0x0f; 3273 break; 3274 case TYPE_INDEX_2: 3275 indexq = (destData[dp >> 2] >>> (6 - (dp & 3) * 2)) & 0x03; 3276 break; 3277 case TYPE_INDEX_1_MSB: 3278 indexq = (destData[dp >> 3] >>> (7 - (dp & 7))) & 0x01; 3279 break; 3280 case TYPE_INDEX_1_LSB: 3281 indexq = (destData[dp >> 3] >>> (dp & 7)) & 0x01; 3282 break; 3283 } 3284 final int rq = destReds[indexq] & 0xff; 3286 final int gq = destGreens[indexq] & 0xff; 3287 final int bq = destBlues[indexq] & 0xff; 3288 r = rq + ((r - rq) * alpha >> 16); 3289 g = gq + ((g - gq) * alpha >> 16); 3290 b = bq + ((b - bq) * alpha >> 16); 3291 } 3292 3293 3294 if (ditherEnabled) { 3295 r += rerr[dx] >> 4; 3297 if (r < 0) r = 0; else if (r > 255) r = 255; 3298 g += gerr[dx] >> 4; 3299 if (g < 0) g = 0; else if (g > 255) g = 255; 3300 b += berr[dx] >> 4; 3301 if (b < 0) b = 0; else if (b > 255) b = 255; 3302 rerr[dx] = lrerr; 3303 gerr[dx] = lgerr; 3304 berr[dx] = lberr; 3305 } 3306 if (r != lastr || g != lastg || b != lastb) { 3307 for (int j = 0, dr, dg, db, distance, minDistance = 0x7fffffff; j < destPaletteSize; ++j) { 3309 dr = (destReds[j] & 0xff) - r; 3310 dg = (destGreens[j] & 0xff) - g; 3311 db = (destBlues[j] & 0xff) - b; 3312 distance = dr * dr + dg * dg + db * db; 3313 if (distance < minDistance) { 3314 lastindex = j; 3315 if (distance == 0) break; 3316 minDistance = distance; 3317 } 3318 } 3319 lastr = r; lastg = g; lastb = b; 3320 } 3321 if (ditherEnabled) { 3322 final int dxm1 = dx - 1, dxp1 = dx + 1; 3324 int acc; 3325 rerr[dxp1] += acc = (lrerr = r - (destReds[lastindex] & 0xff)) + lrerr + lrerr; 3326 rerr[dx] += acc += lrerr + lrerr; 3327 rerr[dxm1] += acc + lrerr + lrerr; 3328 gerr[dxp1] += acc = (lgerr = g - (destGreens[lastindex] & 0xff)) + lgerr + lgerr; 3329 gerr[dx] += acc += lgerr + lgerr; 3330 gerr[dxm1] += acc + lgerr + lgerr; 3331 berr[dxp1] += acc = (lberr = b - (destBlues[lastindex] & 0xff)) + lberr + lberr; 3332 berr[dx] += acc += lberr + lberr; 3333 berr[dxm1] += acc + lberr + lberr; 3334 } 3335 3336 3337 switch (dtype) { 3338 case TYPE_INDEX_8: 3339 destData[dp] = (byte) lastindex; 3340 break; 3341 case TYPE_INDEX_4: 3342 if ((dp & 1) != 0) destData[dp >> 1] = (byte)((destData[dp >> 1] & 0xf0) | lastindex); 3343 else destData[dp >> 1] = (byte)((destData[dp >> 1] & 0x0f) | (lastindex << 4)); 3344 break; 3345 case TYPE_INDEX_2: { 3346 final int shift = 6 - (dp & 3) * 2; 3347 destData[dp >> 2] = (byte)(destData[dp >> 2] & ~(0x03 << shift) | (lastindex << shift)); 3348 } break; 3349 case TYPE_INDEX_1_MSB: { 3350 final int shift = 7 - (dp & 7); 3351 destData[dp >> 3] = (byte)(destData[dp >> 3] & ~(0x01 << shift) | (lastindex << shift)); 3352 } break; 3353 case TYPE_INDEX_1_LSB: { 3354 final int shift = dp & 7; 3355 destData[dp >> 3] = (byte)(destData[dp >> 3] & ~(0x01 << shift) | (lastindex << shift)); 3356 } break; 3357 } 3358 } 3359 } 3360} 3361 3362 3365static int getChannelShift(int mask) { 3366 if (mask == 0) return 0; 3367 int i; 3368 for (i = 0; ((mask & 1) == 0) && (i < 32); ++i) { 3369 mask >>>= 1; 3370 } 3371 return i; 3372} 3373 3374 3377static int getChannelWidth(int mask, int shift) { 3378 if (mask == 0) return 0; 3379 int i; 3380 mask >>>= shift; 3381 for (i = shift; ((mask & 1) != 0) && (i < 32); ++i) { 3382 mask >>>= 1; 3383 } 3384 return i - shift; 3385} 3386 3387 3390static byte getChannelField(int data, int mask) { 3391 final int shift = getChannelShift(mask); 3392 return ANY_TO_EIGHT[getChannelWidth(mask, shift)][(data & mask) >>> shift]; 3393} 3394 3395 3411static ImageData createGradientBand( 3412 int width, int height, boolean vertical, 3413 RGB fromRGB, RGB toRGB, 3414 int redBits, int greenBits, int blueBits) { 3415 3416 final int bandWidth, bandHeight, bitmapDepth; 3417 final byte[] bitmapData; 3418 final PaletteData paletteData; 3419 3420 if (redBits != 0 && greenBits != 0 && blueBits != 0) { 3421 paletteData = new PaletteData(0x0000ff00, 0x00ff0000, 0xff000000); 3422 bitmapDepth = 32; 3423 if (redBits >= 8 && greenBits >= 8 && blueBits >= 8) { 3424 3425 final int steps; 3426 if (vertical) { 3427 bandWidth = 1; 3428 bandHeight = height; 3429 steps = bandHeight > 1 ? bandHeight - 1 : 1; 3430 } else { 3431 bandWidth = width; 3432 bandHeight = 1; 3433 steps = bandWidth > 1 ? bandWidth - 1 : 1; 3434 } 3435 final int bytesPerLine = bandWidth * 4; 3436 bitmapData = new byte[bandHeight * bytesPerLine]; 3437 buildPreciseGradientChannel(fromRGB.blue, toRGB.blue, steps, bandWidth, bandHeight, vertical, bitmapData, 0, bytesPerLine); 3438 buildPreciseGradientChannel(fromRGB.green, toRGB.green, steps, bandWidth, bandHeight, vertical, bitmapData, 1, bytesPerLine); 3439 buildPreciseGradientChannel(fromRGB.red, toRGB.red, steps, bandWidth, bandHeight, vertical, bitmapData, 2, bytesPerLine); 3440 } else { 3441 3442 final int steps; 3443 if (vertical) { 3444 bandWidth = (width < 8) ? width : 8; 3445 bandHeight = height; 3446 steps = bandHeight > 1 ? bandHeight - 1 : 1; 3447 } else { 3448 bandWidth = width; 3449 bandHeight = (height < 8) ? height : 8; 3450 steps = bandWidth > 1 ? bandWidth - 1 : 1; 3451 } 3452 final int bytesPerLine = bandWidth * 4; 3453 bitmapData = new byte[bandHeight * bytesPerLine]; 3454 buildDitheredGradientChannel(fromRGB.blue, toRGB.blue, steps, bandWidth, bandHeight, vertical, bitmapData, 0, bytesPerLine, blueBits); 3455 buildDitheredGradientChannel(fromRGB.green, toRGB.green, steps, bandWidth, bandHeight, vertical, bitmapData, 1, bytesPerLine, greenBits); 3456 buildDitheredGradientChannel(fromRGB.red, toRGB.red, steps, bandWidth, bandHeight, vertical, bitmapData, 2, bytesPerLine, redBits); 3457 } 3458 } else { 3459 3460 paletteData = new PaletteData(new RGB[] { fromRGB, toRGB }); 3461 bitmapDepth = 8; 3462 final int blendi; 3463 if (vertical) { 3464 bandWidth = (width < 8) ? width : 8; 3465 bandHeight = height; 3466 blendi = (bandHeight > 1) ? 0x1040000 / (bandHeight - 1) + 1 : 1; 3467 } else { 3468 bandWidth = width; 3469 bandHeight = (height < 8) ? height : 8; 3470 blendi = (bandWidth > 1) ? 0x1040000 / (bandWidth - 1) + 1 : 1; 3471 } 3472 final int bytesPerLine = (bandWidth + 3) & -4; 3473 bitmapData = new byte[bandHeight * bytesPerLine]; 3474 if (vertical) { 3475 for (int dy = 0, blend = 0, dp = 0; dy < bandHeight; 3476 ++dy, blend += blendi, dp += bytesPerLine) { 3477 for (int dx = 0; dx < bandWidth; ++dx) { 3478 bitmapData[dp + dx] = (blend + DITHER_MATRIX[dy & 7][dx]) < 3479 0x1000000 ? (byte)0 : (byte)1; 3480 } 3481 } 3482 } else { 3483 for (int dx = 0, blend = 0; dx < bandWidth; ++dx, blend += blendi) { 3484 for (int dy = 0, dptr = dx; dy < bandHeight; ++dy, dptr += bytesPerLine) { 3485 bitmapData[dptr] = (blend + DITHER_MATRIX[dy][dx & 7]) < 3486 0x1000000 ? (byte)0 : (byte)1; 3487 } 3488 } 3489 } 3490 } 3491 return new ImageData(bandWidth, bandHeight, bitmapDepth, paletteData, 4, bitmapData); 3492} 3493 3494 3497static final void buildPreciseGradientChannel(int from, int to, int steps, 3498 int bandWidth, int bandHeight, boolean vertical, 3499 byte[] bitmapData, int dp, int bytesPerLine) { 3500 int val = from << 16; 3501 final int inc = ((to << 16) - val) / steps + 1; 3502 if (vertical) { 3503 for (int dy = 0; dy < bandHeight; ++dy, dp += bytesPerLine) { 3504 bitmapData[dp] = (byte)(val >>> 16); 3505 val += inc; 3506 } 3507 } else { 3508 for (int dx = 0; dx < bandWidth; ++dx, dp += 4) { 3509 bitmapData[dp] = (byte)(val >>> 16); 3510 val += inc; 3511 } 3512 } 3513} 3514 3515 3518static final void buildDitheredGradientChannel(int from, int to, int steps, 3519 int bandWidth, int bandHeight, boolean vertical, 3520 byte[] bitmapData, int dp, int bytesPerLine, int bits) { 3521 final int mask = 0xff00 >>> bits; 3522 int val = from << 16; 3523 final int inc = ((to << 16) - val) / steps + 1; 3524 if (vertical) { 3525 for (int dy = 0; dy < bandHeight; ++dy, dp += bytesPerLine) { 3526 for (int dx = 0, dptr = dp; dx < bandWidth; ++dx, dptr += 4) { 3527 final int thresh = DITHER_MATRIX[dy & 7][dx] >>> bits; 3528 int temp = val + thresh; 3529 if (temp > 0xffffff) bitmapData[dptr] = -1; 3530 else bitmapData[dptr] = (byte)((temp >>> 16) & mask); 3531 } 3532 val += inc; 3533 } 3534 } else { 3535 for (int dx = 0; dx < bandWidth; ++dx, dp += 4) { 3536 for (int dy = 0, dptr = dp; dy < bandHeight; ++dy, dptr += bytesPerLine) { 3537 final int thresh = DITHER_MATRIX[dy][dx & 7] >>> bits; 3538 int temp = val + thresh; 3539 if (temp > 0xffffff) bitmapData[dptr] = -1; 3540 else bitmapData[dptr] = (byte)((temp >>> 16) & mask); 3541 } 3542 val += inc; 3543 } 3544 } 3545} 3546 3547 3567static void fillGradientRectangle(GC gc, Device device, 3568 int x, int y, int width, int height, boolean vertical, 3569 RGB fromRGB, RGB toRGB, 3570 int redBits, int greenBits, int blueBits) { 3571 3572 ImageData band = createGradientBand(width, height, vertical, 3573 fromRGB, toRGB, redBits, greenBits, blueBits); 3574 Image image = new Image(device, band); 3575 if ((band.width == 1) || (band.height == 1)) { 3576 gc.drawImage(image, 0, 0, band.width, band.height, x, y, width, height); 3577 } else { 3578 if (vertical) { 3579 for (int dx = 0; dx < width; dx += band.width) { 3580 int blitWidth = width - dx; 3581 if (blitWidth > band.width) blitWidth = band.width; 3582 gc.drawImage(image, 0, 0, blitWidth, band.height, dx + x, y, blitWidth, band.height); 3583 } 3584 } else { 3585 for (int dy = 0; dy < height; dy += band.height) { 3586 int blitHeight = height - dy; 3587 if (blitHeight > band.height) blitHeight = band.height; 3588 gc.drawImage(image, 0, 0, band.width, blitHeight, x, dy + y, band.width, blitHeight); 3589 } 3590 } 3591 } 3592 image.dispose(); 3593} 3594 3595} 3596 | Popular Tags |