| 1 7 8 package java.awt.image; 9 10 import java.awt.color.ColorSpace ; 11 import java.awt.color.ICC_ColorSpace ; 12 13 160 public class ComponentColorModel extends ColorModel { 161 162 168 private boolean signed; private boolean is_sRGB_stdScale; 171 private boolean is_LinearRGB_stdScale; 172 private boolean is_LinearGray_stdScale; 173 private boolean is_ICCGray_stdScale; 174 private byte[] tosRGB8LUT; 175 private byte[] fromsRGB8LUT8; 176 private short[] fromsRGB8LUT16; 177 private byte[] fromLinearGray16ToOtherGray8LUT; 178 private short[] fromLinearGray16ToOtherGray16LUT; 179 private boolean needScaleInit; 180 private boolean noUnnorm; 181 private boolean nonStdScale; 182 private float[] min; 183 private float[] diffMinMax; 184 private float[] compOffset; 185 private float[] compScale; 186 187 250 public ComponentColorModel (ColorSpace colorSpace, 251 int[] bits, 252 boolean hasAlpha, 253 boolean isAlphaPremultiplied, 254 int transparency, 255 int transferType) { 256 super (bitsHelper(transferType, colorSpace, hasAlpha), 257 bitsArrayHelper(bits, transferType, colorSpace, hasAlpha), 258 colorSpace, hasAlpha, isAlphaPremultiplied, transparency, 259 transferType); 260 switch(transferType) { 261 case DataBuffer.TYPE_BYTE: 262 case DataBuffer.TYPE_USHORT: 263 case DataBuffer.TYPE_INT: 264 signed = false; 265 needScaleInit = true; 266 break; 267 case DataBuffer.TYPE_SHORT: 268 signed = true; 269 needScaleInit = true; 270 break; 271 case DataBuffer.TYPE_FLOAT: 272 case DataBuffer.TYPE_DOUBLE: 273 signed = true; 274 needScaleInit = false; 275 noUnnorm = true; 276 nonStdScale = false; 277 break; 278 default: 279 throw new IllegalArgumentException ("This constructor is not "+ 280 "compatible with transferType " + transferType); 281 } 282 setupLUTs(); 283 } 284 285 329 public ComponentColorModel (ColorSpace colorSpace, 330 boolean hasAlpha, 331 boolean isAlphaPremultiplied, 332 int transparency, 333 int transferType) { 334 this(colorSpace, null, hasAlpha, isAlphaPremultiplied, 335 transparency, transferType); 336 } 337 338 private static int bitsHelper(int transferType, 339 ColorSpace colorSpace, 340 boolean hasAlpha) { 341 int numBits = DataBuffer.getDataTypeSize(transferType); 342 int numComponents = colorSpace.getNumComponents(); 343 if (hasAlpha) { 344 ++numComponents; 345 } 346 return numBits * numComponents; 347 } 348 349 private static int[] bitsArrayHelper(int[] origBits, 350 int transferType, 351 ColorSpace colorSpace, 352 boolean hasAlpha) { 353 switch(transferType) { 354 case DataBuffer.TYPE_BYTE: 355 case DataBuffer.TYPE_USHORT: 356 case DataBuffer.TYPE_INT: 357 if (origBits != null) { 358 return origBits; 359 } 360 break; 361 default: 362 break; 363 } 364 int numBits = DataBuffer.getDataTypeSize(transferType); 365 int numComponents = colorSpace.getNumComponents(); 366 if (hasAlpha) { 367 ++numComponents; 368 } 369 int[] bits = new int[numComponents]; 370 for (int i = 0; i < numComponents; i++) { 371 bits[i] = numBits; 372 } 373 return bits; 374 } 375 376 private void setupLUTs() { 377 if (is_sRGB) { 395 is_sRGB_stdScale = true; 396 nonStdScale = false; 397 } else if (ColorModel.isLinearRGBspace(colorSpace)) { 398 is_LinearRGB_stdScale = true; 402 nonStdScale = false; 403 if (transferType == DataBuffer.TYPE_BYTE) { 404 tosRGB8LUT = ColorModel.getLinearRGB8TosRGB8LUT(); 405 fromsRGB8LUT8 = ColorModel.getsRGB8ToLinearRGB8LUT(); 406 } else { 407 tosRGB8LUT = ColorModel.getLinearRGB16TosRGB8LUT(); 408 fromsRGB8LUT16 = ColorModel.getsRGB8ToLinearRGB16LUT(); 409 } 410 } else if ((colorSpaceType == ColorSpace.TYPE_GRAY) && 411 (colorSpace instanceof ICC_ColorSpace ) && 412 (colorSpace.getMinValue(0) == 0.0f) && 413 (colorSpace.getMaxValue(0) == 1.0f)) { 414 ICC_ColorSpace ics = (ICC_ColorSpace ) colorSpace; 418 is_ICCGray_stdScale = true; 419 nonStdScale = false; 420 fromsRGB8LUT16 = ColorModel.getsRGB8ToLinearRGB16LUT(); 421 if (ColorModel.isLinearGRAYspace(ics)) { 422 is_LinearGray_stdScale = true; 423 if (transferType == DataBuffer.TYPE_BYTE) { 424 tosRGB8LUT = ColorModel.getGray8TosRGB8LUT(ics); 425 } else { 426 tosRGB8LUT = ColorModel.getGray16TosRGB8LUT(ics); 427 } 428 } else { 429 if (transferType == DataBuffer.TYPE_BYTE) { 430 tosRGB8LUT = ColorModel.getGray8TosRGB8LUT(ics); 431 fromLinearGray16ToOtherGray8LUT = 432 ColorModel.getLinearGray16ToOtherGray8LUT(ics); 433 } else { 434 tosRGB8LUT = ColorModel.getGray16TosRGB8LUT(ics); 435 fromLinearGray16ToOtherGray16LUT = 436 ColorModel.getLinearGray16ToOtherGray16LUT(ics); 437 } 438 } 439 } else if (needScaleInit) { 440 nonStdScale = false; 445 for (int i = 0; i < numColorComponents; i++) { 446 if ((colorSpace.getMinValue(i) != 0.0f) || 447 (colorSpace.getMaxValue(i) != 1.0f)) { 448 nonStdScale = true; 449 break; 450 } 451 } 452 if (nonStdScale) { 453 min = new float[numColorComponents]; 454 diffMinMax = new float[numColorComponents]; 455 for (int i = 0; i < numColorComponents; i++) { 456 min[i] = colorSpace.getMinValue(i); 457 diffMinMax[i] = colorSpace.getMaxValue(i) - min[i]; 458 } 459 } 460 } 461 } 462 463 private void initScale() { 464 needScaleInit = false; if (nonStdScale || signed) { 485 noUnnorm = true; 494 } else { 495 noUnnorm = false; 496 } 497 float[] lowVal, highVal; 498 switch (transferType) { 499 case DataBuffer.TYPE_BYTE: 500 { 501 byte[] bpixel = new byte[numComponents]; 502 for (int i = 0; i < numColorComponents; i++) { 503 bpixel[i] = 0; 504 } 505 if (supportsAlpha) { 506 bpixel[numColorComponents] = 507 (byte) ((1 << nBits[numColorComponents]) - 1); 508 } 509 lowVal = getNormalizedComponents(bpixel, null, 0); 510 for (int i = 0; i < numColorComponents; i++) { 511 bpixel[i] = (byte) ((1 << nBits[i]) - 1); 512 } 513 highVal = getNormalizedComponents(bpixel, null, 0); 514 } 515 break; 516 case DataBuffer.TYPE_USHORT: 517 { 518 short[] uspixel = new short[numComponents]; 519 for (int i = 0; i < numColorComponents; i++) { 520 uspixel[i] = 0; 521 } 522 if (supportsAlpha) { 523 uspixel[numColorComponents] = 524 (short) ((1 << nBits[numColorComponents]) - 1); 525 } 526 lowVal = getNormalizedComponents(uspixel, null, 0); 527 for (int i = 0; i < numColorComponents; i++) { 528 uspixel[i] = (short) ((1 << nBits[i]) - 1); 529 } 530 highVal = getNormalizedComponents(uspixel, null, 0); 531 } 532 break; 533 case DataBuffer.TYPE_INT: 534 { 535 int[] ipixel = new int[numComponents]; 536 for (int i = 0; i < numColorComponents; i++) { 537 ipixel[i] = 0; 538 } 539 if (supportsAlpha) { 540 ipixel[numColorComponents] = 541 ((1 << nBits[numColorComponents]) - 1); 542 } 543 lowVal = getNormalizedComponents(ipixel, null, 0); 544 for (int i = 0; i < numColorComponents; i++) { 545 ipixel[i] = ((1 << nBits[i]) - 1); 546 } 547 highVal = getNormalizedComponents(ipixel, null, 0); 548 } 549 break; 550 case DataBuffer.TYPE_SHORT: 551 { 552 short[] spixel = new short[numComponents]; 553 for (int i = 0; i < numColorComponents; i++) { 554 spixel[i] = 0; 555 } 556 if (supportsAlpha) { 557 spixel[numColorComponents] = 32767; 558 } 559 lowVal = getNormalizedComponents(spixel, null, 0); 560 for (int i = 0; i < numColorComponents; i++) { 561 spixel[i] = 32767; 562 } 563 highVal = getNormalizedComponents(spixel, null, 0); 564 } 565 break; 566 default: 567 lowVal = highVal = null; break; 569 } 570 nonStdScale = false; 571 for (int i = 0; i < numColorComponents; i++) { 572 if ((lowVal[i] != 0.0f) || (highVal[i] != 1.0f)) { 573 nonStdScale = true; 574 break; 575 } 576 } 577 if (nonStdScale) { 578 noUnnorm = true; 579 is_sRGB_stdScale = false; 580 is_LinearRGB_stdScale = false; 581 is_LinearGray_stdScale = false; 582 is_ICCGray_stdScale = false; 583 compOffset = new float[numColorComponents]; 584 compScale = new float[numColorComponents]; 585 for (int i = 0; i < numColorComponents; i++) { 586 compOffset[i] = lowVal[i]; 587 compScale[i] = 1.0f / (highVal[i] - lowVal[i]); 588 } 589 } 590 } 591 592 private int getRGBComponent(int pixel, int idx) { 593 if (numComponents > 1) { 594 throw new 595 IllegalArgumentException ("More than one component per pixel"); 596 } 597 if (signed) { 598 throw new 599 IllegalArgumentException ("Component value is signed"); 600 } 601 if (needScaleInit) { 602 initScale(); 603 } 604 606 Object opixel = null; 608 switch (transferType) { 609 case DataBuffer.TYPE_BYTE: 610 { 611 byte[] bpixel = { (byte) pixel }; 612 opixel = bpixel; 613 } 614 break; 615 case DataBuffer.TYPE_USHORT: 616 { 617 short[] spixel = { (short) pixel }; 618 opixel = spixel; 619 } 620 break; 621 case DataBuffer.TYPE_INT: 622 { 623 int[] ipixel = { pixel }; 624 opixel = ipixel; 625 } 626 break; 627 } 628 float[] norm = getNormalizedComponents(opixel, null, 0); 629 float[] rgb = colorSpace.toRGB(norm); 630 631 return (int) (rgb[idx] * 255.0f + 0.5f); 632 } 633 634 652 public int getRed(int pixel) { 653 return getRGBComponent(pixel, 0); 654 } 655 656 674 public int getGreen(int pixel) { 675 return getRGBComponent(pixel, 1); 676 } 677 678 696 public int getBlue(int pixel) { 697 return getRGBComponent(pixel, 2); 698 } 699 700 713 public int getAlpha(int pixel) { 714 if (supportsAlpha == false) { 715 return 255; 716 } 717 if (numComponents > 1) { 718 throw new 719 IllegalArgumentException ("More than one component per pixel"); 720 } 721 if (signed) { 722 throw new 723 IllegalArgumentException ("Component value is signed"); 724 } 725 726 return (int) ((((float) pixel) / ((1<<nBits[0])-1)) * 255.0f + 0.5f); 727 } 728 729 745 public int getRGB(int pixel) { 746 if (numComponents > 1) { 747 throw new 748 IllegalArgumentException ("More than one component per pixel"); 749 } 750 if (signed) { 751 throw new 752 IllegalArgumentException ("Component value is signed"); 753 } 754 755 return (getAlpha(pixel) << 24) 756 | (getRed(pixel) << 16) 757 | (getGreen(pixel) << 8) 758 | (getBlue(pixel) << 0); 759 } 760 761 private int extractComponent(Object inData, int idx, int precision) { 762 768 777 boolean needAlpha = (supportsAlpha && isAlphaPremultiplied); 778 int alp = 0; 779 int comp; 780 int mask = (1 << nBits[idx]) - 1; 781 782 switch (transferType) { 783 case DataBuffer.TYPE_SHORT: { 786 short sdata[] = (short[]) inData; 787 float scalefactor = (float) ((1 << precision) - 1); 788 if (needAlpha) { 789 short s = sdata[numColorComponents]; 790 if (s != (short) 0) { 791 return (int) ((((float) sdata[idx]) / 792 ((float) s)) * scalefactor + 0.5f); 793 } else { 794 return 0; 795 } 796 } else { 797 return (int) ((sdata[idx] / 32767.0f) * scalefactor + 0.5f); 798 } 799 } 800 case DataBuffer.TYPE_FLOAT: { 801 float fdata[] = (float[]) inData; 802 float scalefactor = (float) ((1 << precision) - 1); 803 if (needAlpha) { 804 float f = fdata[numColorComponents]; 805 if (f != 0.0f) { 806 return (int) (((fdata[idx] / f) * scalefactor) + 0.5f); 807 } else { 808 return 0; 809 } 810 } else { 811 return (int) (fdata[idx] * scalefactor + 0.5f); 812 } 813 } 814 case DataBuffer.TYPE_DOUBLE: { 815 double ddata[] = (double[]) inData; 816 double scalefactor = (double) ((1 << precision) - 1); 817 if (needAlpha) { 818 double d = ddata[numColorComponents]; 819 if (d != 0.0) { 820 return (int) (((ddata[idx] / d) * scalefactor) + 0.5); 821 } else { 822 return 0; 823 } 824  
|