1 7 8 package com.sun.imageio.plugins.common; 9 10 import java.awt.Point ; 11 import java.awt.Rectangle ; 12 import java.awt.Transparency ; 13 import java.awt.color.ColorSpace ; 14 import java.awt.image.BufferedImage ; 15 import java.awt.image.ColorModel ; 16 import java.awt.image.ComponentColorModel ; 17 import java.awt.image.ComponentSampleModel ; 18 import java.awt.image.DataBuffer ; 19 import java.awt.image.DataBufferByte ; 20 import java.awt.image.DataBufferInt ; 21 import java.awt.image.DataBufferShort ; 22 import java.awt.image.DataBufferUShort ; 23 import java.awt.image.DirectColorModel ; 24 import java.awt.image.IndexColorModel ; 25 import java.awt.image.MultiPixelPackedSampleModel ; 26 import java.awt.image.Raster ; 27 import java.awt.image.RenderedImage ; 28 import java.awt.image.SampleModel ; 29 import java.awt.image.SinglePixelPackedSampleModel ; 30 import java.awt.image.WritableRaster ; 31 import java.util.Arrays ; 32 33 35 import javax.imageio.IIOException ; 36 import javax.imageio.IIOImage ; 37 import javax.imageio.ImageTypeSpecifier ; 38 import javax.imageio.ImageWriter ; 39 import javax.imageio.spi.ImageWriterSpi ; 40 41 public class ImageUtil { 42 89 90 121 public static final ColorModel createColorModel(SampleModel sampleModel) { 122 if(sampleModel == null) { 124 throw new IllegalArgumentException ("sampleModel == null!"); 125 } 126 127 int dataType = sampleModel.getDataType(); 129 130 switch(dataType) { 132 case DataBuffer.TYPE_BYTE: 133 case DataBuffer.TYPE_USHORT: 134 case DataBuffer.TYPE_SHORT: 135 case DataBuffer.TYPE_INT: 136 case DataBuffer.TYPE_FLOAT: 137 case DataBuffer.TYPE_DOUBLE: 138 break; 139 default: 140 return null; 142 } 143 144 ColorModel colorModel = null; 146 147 int[] sampleSize = sampleModel.getSampleSize(); 149 150 if(sampleModel instanceof ComponentSampleModel ) { 152 int numBands = sampleModel.getNumBands(); 154 155 ColorSpace colorSpace = null; 157 if(numBands <= 2) { 158 colorSpace = ColorSpace.getInstance(ColorSpace.CS_GRAY); 159 } else if(numBands <= 4) { 160 colorSpace = ColorSpace.getInstance(ColorSpace.CS_sRGB); 161 } else { 162 colorSpace = new BogusColorSpace(numBands); 163 } 164 165 boolean hasAlpha = (numBands == 2) || (numBands == 4); 166 boolean isAlphaPremultiplied = false; 167 int transparency = hasAlpha ? 168 Transparency.TRANSLUCENT : Transparency.OPAQUE; 169 170 colorModel = new ComponentColorModel (colorSpace, 171 sampleSize, 172 hasAlpha, 173 isAlphaPremultiplied, 174 transparency, 175 dataType); 176 } else if (sampleModel.getNumBands() <= 4 && 177 sampleModel instanceof SinglePixelPackedSampleModel ) { 178 SinglePixelPackedSampleModel sppsm = 179 (SinglePixelPackedSampleModel )sampleModel; 180 181 int[] bitMasks = sppsm.getBitMasks(); 182 int rmask = 0; 183 int gmask = 0; 184 int bmask = 0; 185 int amask = 0; 186 187 int numBands = bitMasks.length; 188 if (numBands <= 2) { 189 rmask = gmask = bmask = bitMasks[0]; 190 if (numBands == 2) { 191 amask = bitMasks[1]; 192 } 193 } else { 194 rmask = bitMasks[0]; 195 gmask = bitMasks[1]; 196 bmask = bitMasks[2]; 197 if (numBands == 4) { 198 amask = bitMasks[3]; 199 } 200 } 201 202 int bits = 0; 203 for (int i = 0; i < sampleSize.length; i++) { 204 bits += sampleSize[i]; 205 } 206 207 return new DirectColorModel (bits, rmask, gmask, bmask, amask); 208 209 } else if(sampleModel instanceof MultiPixelPackedSampleModel ) { 210 int bitsPerSample = sampleSize[0]; 212 int numEntries = 1 << bitsPerSample; 213 byte[] map = new byte[numEntries]; 214 for (int i = 0; i < numEntries; i++) { 215 map[i] = (byte)(i*255/(numEntries - 1)); 216 } 217 218 colorModel = new IndexColorModel (bitsPerSample, numEntries, 219 map, map, map); 220 221 } 222 223 return colorModel; 224 } 225 226 241 public static byte[] getPackedBinaryData(Raster raster, 242 Rectangle rect) { 243 SampleModel sm = raster.getSampleModel(); 244 if(!isBinary(sm)) { 245 throw new IllegalArgumentException (I18N.getString("ImageUtil0")); 246 } 247 248 int rectX = rect.x; 249 int rectY = rect.y; 250 int rectWidth = rect.width; 251 int rectHeight = rect.height; 252 253 DataBuffer dataBuffer = raster.getDataBuffer(); 254 255 int dx = rectX - raster.getSampleModelTranslateX(); 256 int dy = rectY - raster.getSampleModelTranslateY(); 257 258 MultiPixelPackedSampleModel mpp = (MultiPixelPackedSampleModel )sm; 259 int lineStride = mpp.getScanlineStride(); 260 int eltOffset = dataBuffer.getOffset() + mpp.getOffset(dx, dy); 261 int bitOffset = mpp.getBitOffset(dx); 262 263 int numBytesPerRow = (rectWidth + 7)/8; 264 if(dataBuffer instanceof DataBufferByte && 265 eltOffset == 0 && bitOffset == 0 && 266 numBytesPerRow == lineStride && 267 ((DataBufferByte )dataBuffer).getData().length == 268 numBytesPerRow*rectHeight) { 269 return ((DataBufferByte )dataBuffer).getData(); 270 } 271 272 byte[] binaryDataArray = new byte[numBytesPerRow*rectHeight]; 273 274 int b = 0; 275 276 if(bitOffset == 0) { 277 if(dataBuffer instanceof DataBufferByte ) { 278 byte[] data = ((DataBufferByte )dataBuffer).getData(); 279 int stride = numBytesPerRow; 280 int offset = 0; 281 for(int y = 0; y < rectHeight; y++) { 282 System.arraycopy(data, eltOffset, 283 binaryDataArray, offset, 284 stride); 285 offset += stride; 286 eltOffset += lineStride; 287 } 288 } else if(dataBuffer instanceof DataBufferShort || 289 dataBuffer instanceof DataBufferUShort ) { 290 short[] data = dataBuffer instanceof DataBufferShort ? 291 ((DataBufferShort )dataBuffer).getData() : 292 ((DataBufferUShort )dataBuffer).getData(); 293 294 for(int y = 0; y < rectHeight; y++) { 295 int xRemaining = rectWidth; 296 int i = eltOffset; 297 while(xRemaining > 8) { 298 short datum = data[i++]; 299 binaryDataArray[b++] = (byte)((datum >>> 8) & 0xFF); 300 binaryDataArray[b++] = (byte)(datum & 0xFF); 301 xRemaining -= 16; 302 } 303 if(xRemaining > 0) { 304 binaryDataArray[b++] = (byte)((data[i] >>> 8) & 0XFF); 305 } 306 eltOffset += lineStride; 307 } 308 } else if(dataBuffer instanceof DataBufferInt ) { 309 int[] data = ((DataBufferInt )dataBuffer).getData(); 310 311 for(int y = 0; y < rectHeight; y++) { 312 int xRemaining = rectWidth; 313 int i = eltOffset; 314 while(xRemaining > 24) { 315 int datum = data[i++]; 316 binaryDataArray[b++] = (byte)((datum >>> 24) & 0xFF); 317 binaryDataArray[b++] = (byte)((datum >>> 16) & 0xFF); 318 binaryDataArray[b++] = (byte)((datum >>> 8) & 0xFF); 319 binaryDataArray[b++] = (byte)(datum & 0xFF); 320 xRemaining -= 32; 321 } 322 int shift = 24; 323 while(xRemaining > 0) { 324 binaryDataArray[b++] = 325 (byte)((data[i] >>> shift) & 0xFF); 326 shift -= 8; 327 xRemaining -= 8; 328 } 329 eltOffset += lineStride; 330 } 331 } 332 } else { if(dataBuffer instanceof DataBufferByte ) { 334 byte[] data = ((DataBufferByte )dataBuffer).getData(); 335 336 if((bitOffset & 7) == 0) { 337 int stride = numBytesPerRow; 338 int offset = 0; 339 for(int y = 0; y < rectHeight; y++) { 340 System.arraycopy(data, eltOffset, 341 binaryDataArray, offset, 342 stride); 343 offset += stride; 344 eltOffset += lineStride; 345 } 346 } else { int leftShift = bitOffset & 7; 348 int rightShift = 8 - leftShift; 349 for(int y = 0; y < rectHeight; y++) { 350 int i = eltOffset; 351 int xRemaining = rectWidth; 352 while(xRemaining > 0) { 353 if(xRemaining > rightShift) { 354 binaryDataArray[b++] = 355 (byte)(((data[i++]&0xFF) << leftShift) | 356 ((data[i]&0xFF) >>> rightShift)); 357 } else { 358 binaryDataArray[b++] = 359 (byte)((data[i]&0xFF) << leftShift); 360 } 361 xRemaining -= 8; 362 } 363 eltOffset += lineStride; 364 } 365 } 366 } else if(dataBuffer instanceof DataBufferShort || 367 dataBuffer instanceof DataBufferUShort ) { 368 short[] data = dataBuffer instanceof DataBufferShort ? 369 ((DataBufferShort )dataBuffer).getData() : 370 ((DataBufferUShort )dataBuffer).getData(); 371 372 for(int y = 0; y < rectHeight; y++) { 373 int bOffset = bitOffset; 374 for(int x = 0; x < rectWidth; x += 8, bOffset += 8) { 375 int i = eltOffset + bOffset/16; 376 int mod = bOffset % 16; 377 int left = data[i] & 0xFFFF; 378 if(mod <= 8) { 379 binaryDataArray[b++] = (byte)(left >>> (8 - mod)); 380 } else { 381 int delta = mod - 8; 382 int right = data[i+1] & 0xFFFF; 383 binaryDataArray[b++] = 384 (byte)((left << delta) | 385 (right >>> (16 - delta))); 386 } 387 } 388 eltOffset += lineStride; 389 } 390 } else if(dataBuffer instanceof DataBufferInt ) { 391 int[] data = ((DataBufferInt )dataBuffer).getData(); 392 393 for(int y = 0; y < rectHeight; y++) { 394 int bOffset = bitOffset; 395 for(int x = 0; x < rectWidth; x += 8, bOffset += 8) { 396 int i = eltOffset + bOffset/32; 397 int mod = bOffset % 32; 398 int left = data[i]; 399 if(mod <= 24) { 400 binaryDataArray[b++] = 401 (byte)(left >>> (24 - mod)); 402 } else { 403 int delta = mod - 24; 404 int right = data[i+1]; 405 binaryDataArray[b++] = 406 (byte)((left << delta) | 407 (right >>> (32 - delta))); 408 } 409 } 410 eltOffset += lineStride; 411 } 412 } 413 } 414 415 return binaryDataArray; 416 } 417 418 426 public static byte[] getUnpackedBinaryData(Raster raster, 427 Rectangle rect) { 428 SampleModel sm = raster.getSampleModel(); 429 if(!isBinary(sm)) { 430 throw new IllegalArgumentException (I18N.getString("ImageUtil0")); 431 } 432 433 int rectX = rect.x; 434 int rectY = rect.y; 435 int rectWidth = rect.width; 436 int rectHeight = rect.height; 437 438 DataBuffer dataBuffer = raster.getDataBuffer(); 439 440 int dx = rectX - raster.getSampleModelTranslateX(); 441 int dy = rectY - raster.getSampleModelTranslateY(); 442 443 MultiPixelPackedSampleModel mpp = (MultiPixelPackedSampleModel )sm; 444 int lineStride = mpp.getScanlineStride(); 445 int eltOffset = dataBuffer.getOffset() + mpp.getOffset(dx, dy); 446 int bitOffset = mpp.getBitOffset(dx); 447 448 byte[] bdata = new byte[rectWidth*rectHeight]; 449 int maxY = rectY + rectHeight; 450 int maxX = rectX + rectWidth; 451 int k = 0; 452 453 if(dataBuffer instanceof DataBufferByte ) { 454 byte[] data = ((DataBufferByte )dataBuffer).getData(); 455 for(int y = rectY; y < maxY; y++) { 456 int bOffset = eltOffset*8 + bitOffset; 457 for(int x = rectX; x < maxX; x++) { 458 byte b = data[bOffset/8]; 459 bdata[k++] = 460 (byte)((b >>> (7 - bOffset & 7)) & 0x0000001); 461 bOffset++; 462 } 463 eltOffset += lineStride; 464 } 465 } else if(dataBuffer instanceof DataBufferShort || 466 dataBuffer instanceof DataBufferUShort ) { 467 short[] data = dataBuffer instanceof DataBufferShort ? 468 ((DataBufferShort )dataBuffer).getData() : 469 ((DataBufferUShort )dataBuffer).getData(); 470 for(int y = rectY; y < maxY; y++) { 471 int bOffset = eltOffset*16 + bitOffset; 472 for(int x = rectX; x < maxX; x++) { 473 short s = data[bOffset/16]; 474 bdata[k++] = 475 (byte)((s >>> (15 - bOffset % 16)) & 476 0x0000001); 477 bOffset++; 478 } 479 eltOffset += lineStride; 480 } 481 } else if(dataBuffer instanceof DataBufferInt ) { 482 int[] data = ((DataBufferInt )dataBuffer).getData(); 483 for(int y = rectY; y < maxY; y++) { 484 int bOffset = eltOffset*32 + bitOffset; 485 for(int x = rectX; x < maxX; x++) { 486 int i = data[bOffset/32]; 487 bdata[k++] = 488 (byte)((i >>> (31 - bOffset % 32)) & 489 0x0000001); 490 bOffset++; 491 } 492 eltOffset += lineStride; 493 } 494 } 495 496 return bdata; 497 } 498 499 508 public static void setPackedBinaryData(byte[] binaryDataArray, 509 WritableRaster raster, 510 Rectangle rect) { 511 SampleModel sm = raster.getSampleModel(); 512 if(!isBinary(sm)) { 513 throw new IllegalArgumentException (I18N.getString("ImageUtil0")); 514 } 515 516 int rectX = rect.x; 517 int rectY = rect.y; 518 int rectWidth = rect.width; 519 int rectHeight = rect.height; 520 521 DataBuffer dataBuffer = raster.getDataBuffer(); 522 523 int dx = rectX - raster.getSampleModelTranslateX(); 524 int dy = rectY - raster.getSampleModelTranslateY(); 525 526 MultiPixelPackedSampleModel mpp = (MultiPixelPackedSampleModel )sm; 527 int lineStride = mpp.getScanlineStride(); 528 int eltOffset = dataBuffer.getOffset() + mpp.getOffset(dx, dy); 529 int bitOffset = mpp.getBitOffset(dx); 530 531 int b = 0; 532 533 if(bitOffset == 0) { 534 if(dataBuffer instanceof DataBufferByte ) { 535 byte[] data = ((DataBufferByte )dataBuffer).getData(); 536 if(data == binaryDataArray) { 537 return; 539 } 540 int stride = (rectWidth + 7)/8; 541 int offset = 0; 542 for(int y = 0; y < rectHeight; y++) { 543 System.arraycopy(binaryDataArray, offset, 544 data, eltOffset, 545 stride); 546 offset += stride; 547 eltOffset += lineStride; 548 } 549 } else if(dataBuffer instanceof DataBufferShort || 550 dataBuffer instanceof DataBufferUShort ) { 551 short[] data = dataBuffer instanceof DataBufferShort ? 552 ((DataBufferShort )dataBuffer).getData() : 553 ((DataBufferUShort )dataBuffer).getData(); 554 555 for(int y = 0; y < rectHeight; y++) { 556 int xRemaining = rectWidth; 557 int i = eltOffset; 558 while(xRemaining > 8) { 559 data[i++] = 560 (short)(((binaryDataArray[b++] & 0xFF) << 8) | 561 (binaryDataArray[b++] & 0xFF)); 562 xRemaining -= 16; 563 } 564 if(xRemaining > 0) { 565 data[i++] = 566 (short)((binaryDataArray[b++] & 0xFF) << 8); 567 } 568 eltOffset += lineStride; 569 } 570 } else if(dataBuffer instanceof DataBufferInt ) { 571 int[] data = ((DataBufferInt )dataBuffer).getData(); 572 573 for(int y = 0; y < rectHeight; y++) { 574 int xRemaining = rectWidth; 575 int i = eltOffset; 576 while(xRemaining > 24) { 577 data[i++] = 578 (int)(((binaryDataArray[b++] & 0xFF) << 24) | 579 ((binaryDataArray[b++] & 0xFF) << 16) | 580 ((binaryDataArray[b++] & 0xFF) << 8) | 581 (binaryDataArray[b++] & 0xFF)); 582 xRemaining -= 32; 583 } 584 int shift = 24; 585 while(xRemaining > 0) { 586 data[i] |= 587 (int)((binaryDataArray[b++] & 0xFF) << shift); 588 shift -= 8; 589 xRemaining -= 8; 590 } 591 eltOffset += lineStride; 592 } 593 } 594 } else { int stride = (rectWidth + 7)/8; 596 int offset = 0; 597 if(dataBuffer instanceof DataBufferByte ) { 598 byte[] data = ((DataBufferByte )dataBuffer).getData(); 599 600 if((bitOffset & 7) == 0) { 601 for(int y = 0; y < rectHeight; y++) { 602 System.arraycopy(binaryDataArray, offset, 603 data, eltOffset, 604 stride); 605 offset += stride; 606 eltOffset += lineStride; 607 } 608 } else { int rightShift = bitOffset & 7; 610 int leftShift = 8 - rightShift; 611 int leftShift8 = 8 + leftShift; 612 int mask = (byte)(255<<leftShift); 613 int mask1 = (byte)~mask; 614 615 for(int y = 0; y < rectHeight; y++) { 616 int i = eltOffset; 617 int xRemaining = rectWidth; 618 while(xRemaining > 0) { 619 byte datum = binaryDataArray[b++]; 620 621 if (xRemaining > leftShift8) { 622 data[i] = (byte)((data[i] & mask ) | 625 ((datum&0xFF) >>> rightShift)); 626 data[++i] = (byte)((datum & 0xFF) << leftShift); 627 } else if (xRemaining > leftShift) { 628 data[i] = (byte)((data[i] & mask ) | 632 ((datum&0xFF) >>> rightShift)); 633 i++; 634 data[i] = 635 (byte)((data[i] & mask1) | ((datum & 0xFF) << leftShift)); 636 } 637 else { 638 int remainMask = (1 << leftShift - xRemaining) - 1; 640 data[i] = 641 (byte)((data[i] & (mask | remainMask)) | 642 (datum&0xFF) >>> rightShift & ~remainMask); 643 } 644 xRemaining -= 8; 645 } 646 eltOffset += lineStride; 647 } 648 } 649 } else if(dataBuffer instanceof DataBufferShort || 650 dataBuffer instanceof DataBufferUShort ) { 651 short[] data = dataBuffer instanceof DataBufferShort ? 652 ((DataBufferShort )dataBuffer).getData() : 653 ((DataBufferUShort )dataBuffer).getData(); 654 655 int rightShift = bitOffset & 7; 656 int leftShift = 8 - rightShift; 657 int leftShift16 = 16 + leftShift; 658 int mask = (short)(~(255 << leftShift)); 659 int mask1 = (short)(65535 << leftShift); 660 int mask2 = (short)~mask1; 661 662 for(int y = 0; y < rectHeight; y++) { 663 int bOffset = bitOffset; 664 int xRemaining = rectWidth; 665 for(int x = 0; x < rectWidth; 666 x += 8, bOffset += 8, xRemaining -= 8) { 667 int i = eltOffset + (bOffset >> 4); 668 int mod = bOffset & 15; 669 int datum = binaryDataArray[b++] & 0xFF; 670 if(mod <= 8) { 671 if (xRemaining < 8) { 673 datum &= 255 << 8 - xRemaining; 675 } 676 data[i] = (short)((data[i] & mask) | (datum << leftShift)); 677 } else if (xRemaining > leftShift16) { 678 data[i] = (short)((data[i] & mask1) | ((datum >>> rightShift)&0xFFFF)); 680 data[++i] = 681 (short)((datum << leftShift)&0xFFFF); 682 } else if (xRemaining > leftShift) { 683 data[i] = (short)((data[i] & mask1) | ((datum >>> rightShift)&0xFFFF)); 686 i++; 687 data[i] = 688 (short)((data[i] & mask2) | ((datum << leftShift)&0xFFFF)); 689 } else { 690 int remainMask = (1 << leftShift - xRemaining) - 1; 693 data[i] = (short)((data[i] & (mask1 | remainMask)) | 694 ((datum >>> rightShift)&0xFFFF & ~remainMask)); 695 } 696 } 697 eltOffset += lineStride; 698 } 699 } else if(dataBuffer instanceof DataBufferInt ) { 700 int[] data = ((DataBufferInt )dataBuffer).getData(); 701 int rightShift = bitOffset & 7; 702 int leftShift = 8 - rightShift; 703 int leftShift32 = 32 + leftShift; 704 int mask = 0xFFFFFFFF << leftShift; 705 int mask1 = ~mask; 706 707 for(int y = 0; y < rectHeight; y++) { 708 int bOffset = bitOffset; 709 int xRemaining = rectWidth; 710 for(int x = 0; x < rectWidth; 711 x += 8, bOffset += 8, xRemaining -= 8) { 712 int i = eltOffset + (bOffset >> 5); 713 int mod = bOffset & 31; 714 int datum = binaryDataArray[b++] & 0xFF; 715 if(mod <= 24) { 716 int shift = 24 - mod; 718 if (xRemaining < 8) { 719 datum &= 255 << 8 - xRemaining; 721 } 722 data[i] = (data[i] & (~(255 << shift))) | (datum << shift); 723 } else if (xRemaining > leftShift32) { 724 data[i] = (data[i] & mask) | (datum >>> rightShift); 726 data[++i] = datum << leftShift; 727 } else if (xRemaining > leftShift) { 728 data[i] = (data[i] & mask) | (datum >>> rightShift); 731 i++; 732 data[i] = (data[i] & mask1) | (datum << leftShift); 733 } else { 734 int remainMask = (1 << leftShift - xRemaining) - 1; 736 data[i] = (data[i] & (mask | remainMask)) | 737 (datum >>> rightShift & ~remainMask); 738 } 739 } 740 eltOffset += lineStride; 741 } 742 } 743 } 744 } 745 746 758 public static void setUnpackedBinaryData(byte[] bdata, 759 WritableRaster raster, 760 Rectangle rect) { 761 SampleModel sm = raster.getSampleModel(); 762 if(!isBinary(sm)) { 763 throw new IllegalArgumentException (I18N.getString("ImageUtil0")); 764 } 765 766 int rectX = rect.x; 767 int rectY = rect.y; 768 int rectWidth = rect.width; 769 int rectHeight = rect.height; 770 771 DataBuffer dataBuffer = raster.getDataBuffer(); 772 773 int dx = rectX - raster.getSampleModelTranslateX(); 774 int dy = rectY - raster.getSampleModelTranslateY(); 775 776 MultiPixelPackedSampleModel mpp = (MultiPixelPackedSampleModel )sm; 777 int lineStride = mpp.getScanlineStride(); 778 int eltOffset = dataBuffer.getOffset() + mpp.getOffset(dx, dy); 779 int bitOffset = mpp.getBitOffset(dx); 780 781 int k = 0; 782 783 if(dataBuffer instanceof DataBufferByte ) { 784 byte[] data = ((DataBufferByte )dataBuffer).getData(); 785 for(int y = 0; y < rectHeight; y++) { 786 int bOffset = eltOffset*8 + bitOffset; 787 for(int x = 0; x < rectWidth; x++) { 788 if(bdata[k++] != (byte)0) { 789 data[bOffset/8] |= 790 (byte)(0x00000001 << (7 - bOffset & 7)); 791 } 792 bOffset++; 793 } 794 eltOffset += lineStride; 795 } 796 } else if(dataBuffer instanceof DataBufferShort || 797 dataBuffer instanceof DataBufferUShort ) { 798 short[] data = dataBuffer instanceof DataBufferShort ? 799 ((DataBufferShort )dataBuffer).getData() : 800 ((DataBufferUShort )dataBuffer).getData(); 801 for(int y = 0; y < rectHeight; y++) { 802 int bOffset = eltOffset*16 + bitOffset; 803 for(int x = 0; x < rectWidth; x++) { 804 if(bdata[k++] != (byte)0) { 805 data[bOffset/16] |= 806 (short)(0x00000001 << 807 (15 - bOffset % 16)); 808 } 809 bOffset++; 810 } 811 eltOffset += lineStride; 812 } 813 } else if(dataBuffer instanceof DataBufferInt ) { 814 int[] data = ((DataBufferInt )dataBuffer).getData(); 815 for(int y = 0; y < rectHeight; y++) { 816 int bOffset = eltOffset*32 + bitOffset; 817 for(int x = 0; x < rectWidth; x++) { 818 if(bdata[k++] != (byte)0) { 819 data[bOffset/32] |= 820 (int)(0x00000001 << 821 (31 - bOffset % 32)); 822 } 823 bOffset++; 824 } 825 eltOffset += lineStride; 826 } 827 } 828 } 829 830 public static boolean isBinary(SampleModel sm) { 831 return sm instanceof MultiPixelPackedSampleModel && 832 ((MultiPixelPackedSampleModel )sm).getPixelBitStride() == 1 && 833 sm.getNumBands() == 1; 834 } 835 836 public static ColorModel createColorModel(ColorSpace colorSpace, 837 SampleModel sampleModel) { 838 ColorModel colorModel = null; 839 840 if(sampleModel == null) { 841 throw new IllegalArgumentException (I18N.getString("ImageUtil1")); 842 } 843 844 int numBands = sampleModel.getNumBands(); 845 if (numBands < 1 || numBands > 4) { 846 return null; 847 } 848 849 int dataType = sampleModel.getDataType(); 850 if (sampleModel instanceof ComponentSampleModel ) { 851 if (dataType < DataBuffer.TYPE_BYTE || 852 dataType > DataBuffer.TYPE_DOUBLE) { 854 return null; 855 } 856 857 if (colorSpace == null) 858 colorSpace = 859 numBands <= 2 ? 860 ColorSpace.getInstance(ColorSpace.CS_GRAY) : 861 ColorSpace.getInstance(ColorSpace.CS_sRGB); 862 863 boolean useAlpha = (numBands == 2) || (numBands == 4); 864 int transparency = useAlpha ? 865 Transparency.TRANSLUCENT : Transparency.OPAQUE; 866 867 boolean premultiplied = false; 868 869 int dataTypeSize = DataBuffer.getDataTypeSize(dataType); 870 int[] bits = new int[numBands]; 871 for (int i = 0; i < numBands; i++) { 872 bits[i] = dataTypeSize; 873 } 874 875 colorModel = new ComponentColorModel (colorSpace, 876 bits, 877 useAlpha, 878 premultiplied, 879 transparency, 880 dataType); 881 } else if (sampleModel instanceof SinglePixelPackedSampleModel ) { 882 SinglePixelPackedSampleModel sppsm = 883 (SinglePixelPackedSampleModel )sampleModel; 884 885 int[] bitMasks = sppsm.getBitMasks(); 886 int rmask = 0; 887 int gmask = 0; 888 int bmask = 0; 889 int amask = 0; 890 891 numBands = bitMasks.length; 892 if (numBands <= 2) { 893 rmask = gmask = bmask = bitMasks[0]; 894 if (numBands == 2) { 895 amask = bitMasks[1]; 896 } 897 } else { 898 rmask = bitMasks[0]; 899 gmask = bitMasks[1]; 900 bmask = bitMasks[2]; 901 if (numBands == 4) { 902 amask = bitMasks[3]; 903 } 904 } 905 906 int[] sampleSize = sppsm.getSampleSize(); 907 int bits = 0; 908 for (int i = 0; i < sampleSize.length; i++) { 909 bits += sampleSize[i]; 910 } 911 912 if (colorSpace == null) 913 colorSpace = ColorSpace.getInstance(ColorSpace.CS_sRGB); 914 915 colorModel = 916 new DirectColorModel (colorSpace, 917 bits, rmask, gmask, bmask, amask, 918 false, 919 sampleModel.getDataType()); 920 } else if (sampleModel instanceof MultiPixelPackedSampleModel ) { 921 int bits = 922 ((MultiPixelPackedSampleModel )sampleModel).getPixelBitStride(); 923 int size = 1 << bits; 924 byte[] comp = new byte[size]; 925 926 for (int i = 0; i < size; i++) 927 comp[i] = (byte)(255 * i / (size - 1)); 928 929 colorModel = new IndexColorModel (bits, size, comp, comp, comp); 930 } 931 932 return colorModel; 933 } 934 935 public static int getElementSize(SampleModel sm) { 936 int elementSize = DataBuffer.getDataTypeSize(sm.getDataType()); 937 938 if (sm instanceof MultiPixelPackedSampleModel ) { 939 MultiPixelPackedSampleModel mppsm = 940 (MultiPixelPackedSampleModel )sm; 941 return mppsm.getSampleSize(0) * mppsm.getNumBands(); 942 } else if (sm instanceof ComponentSampleModel ) { 943 return sm.getNumBands() * elementSize; 944 } else if (sm instanceof SinglePixelPackedSampleModel ) { 945 return elementSize; 946 } 947 948 return elementSize * sm.getNumBands(); 949 950 } 951 952 public static long getTileSize(SampleModel sm) { 953 int elementSize = DataBuffer.getDataTypeSize(sm.getDataType()); 954 955 if (sm instanceof MultiPixelPackedSampleModel ) { 956 MultiPixelPackedSampleModel mppsm = 957 (MultiPixelPackedSampleModel )sm; 958 return (mppsm.getScanlineStride() * mppsm.getHeight() + 959 (mppsm.getDataBitOffset() + elementSize -1) / elementSize) * 960 ((elementSize + 7) / 8); 961 } else if (sm instanceof ComponentSampleModel ) { 962 ComponentSampleModel csm = (ComponentSampleModel )sm; 963 int[] bandOffsets = csm.getBandOffsets(); 964 int maxBandOff = bandOffsets[0]; 965 for (int i=1; i<bandOffsets.length; i++) 966 maxBandOff = Math.max(maxBandOff, bandOffsets[i]); 967 968 long size = 0; 969 int pixelStride = csm.getPixelStride(); 970 int scanlineStride = csm.getScanlineStride(); 971 if (maxBandOff >= 0) 972 size += maxBandOff + 1; 973 if (pixelStride > 0) 974 size += pixelStride * (sm.getWidth() - 1); 975 if (scanlineStride > 0) 976 size += scanlineStride * (sm.getHeight() - 1); 977 978 int[] bankIndices = csm.getBankIndices(); 979 maxBandOff = bankIndices[0]; 980 for (int i=1; i<bankIndices.length; i++) 981 maxBandOff = Math.max(maxBandOff, bankIndices[i]); 982 return size * (maxBandOff + 1) * ((elementSize + 7) / 8); 983 } else if (sm instanceof SinglePixelPackedSampleModel ) { 984 SinglePixelPackedSampleModel sppsm = 985 (SinglePixelPackedSampleModel )sm; 986 long size = sppsm.getScanlineStride() * (sppsm.getHeight() - 1) + 987 sppsm.getWidth(); 988 return size * ((elementSize + 7) / 8); 989 } 990 991 return 0; 992 } 993 994 public static long getBandSize(SampleModel sm) { 995 int elementSize = DataBuffer.getDataTypeSize(sm.getDataType()); 996 997 if (sm instanceof ComponentSampleModel ) { 998 ComponentSampleModel csm = (ComponentSampleModel )sm; 999 int pixelStride = csm.getPixelStride(); 1000 int scanlineStride = csm.getScanlineStride(); 1001 long size = Math.min(pixelStride, scanlineStride); 1002 1003 if (pixelStride > 0) 1004 size += pixelStride * (sm.getWidth() - 1); 1005 if (scanlineStride > 0) 1006 size += scanlineStride * (sm.getHeight() - 1); 1007 return size * ((elementSize + 7) / 8); 1008 } else 1009 return getTileSize(sm); 1010 } 1011 1020 public static boolean isIndicesForGrayscale(byte[] r, byte[] g, byte[] b) { 1021 if (r.length != g.length || r.length != b.length) 1022 return false; 1023 1024 int size = r.length; 1025 1026 if (size != 256) 1027 return false; 1028 1029 for (int i = 0; i < size; i++) { 1030 byte temp = (byte) i; 1031 1032 if (r[i] != temp || g[i] != temp || b[i] != temp) 1033 return false; 1034 } 1035 1036 return true; 1037 } 1038 1039 1040 public static String convertObjectToString(Object obj) { 1041 if (obj == null) 1042 return ""; 1043 1044 String s = ""; 1045 if (obj instanceof byte[]) { 1046 byte[] bArray = (byte[])obj; 1047 for (int i = 0; i < bArray.length; i++) 1048 s += bArray[i] + " "; 1049 return s; 1050 } 1051 1052 if (obj instanceof int[]) { 1053 int[] iArray = (int[])obj; 1054 for (int i = 0; i < iArray.length; i++) 1055 s += iArray[i] + " " ; 1056 return s; 1057 } 1058 1059 if (obj instanceof short[]) { 1060 short[] sArray = (short[])obj; 1061 for (int i = 0; i < sArray.length; i++) 1062 s += sArray[i] + " " ; 1063 return s; 1064 } 1065 1066 return obj.toString(); 1067 1068 } 1069 1070 1077 public static final void canEncodeImage(ImageWriter writer, 1078 ImageTypeSpecifier type) 1079 throws IIOException { 1080 ImageWriterSpi spi = writer.getOriginatingProvider(); 1081 1082 if(type != null && spi != null && !spi.canEncodeImage(type)) { 1083 throw new IIOException (I18N.getString("ImageUtil2")+" "+ 1084 writer.getClass().getName()); 1085 } 1086 } 1087 1088 1096 public static final void canEncodeImage(ImageWriter writer, 1097 ColorModel colorModel, 1098 SampleModel sampleModel) 1099 throws IIOException { 1100 ImageTypeSpecifier type = null; 1101 if (colorModel != null && sampleModel != null) 1102 type = new ImageTypeSpecifier (colorModel, sampleModel); 1103 canEncodeImage(writer, type); 1104 } 1105 1106 1109 public static final boolean imageIsContiguous(RenderedImage image) { 1110 SampleModel sm; 1111 if(image instanceof BufferedImage ) { 1112 WritableRaster ras = ((BufferedImage )image).getRaster(); 1113 sm = ras.getSampleModel(); 1114 } else { 1115 sm = image.getSampleModel(); 1116 } 1117 1118 if (sm instanceof ComponentSampleModel ) { 1119 ComponentSampleModel csm = (ComponentSampleModel )sm; 1122 1123 if (csm.getPixelStride() != csm.getNumBands()) { 1124 return false; 1125 } 1126 1127 int[] bandOffsets = csm.getBandOffsets(); 1128 for (int i = 0; i < bandOffsets.length; i++) { 1129 if (bandOffsets[i] != i) { 1130 return false; 1131 } 1132 } 1133 1134 int[] bankIndices = csm.getBankIndices(); 1135 for (int i = 0; i < bandOffsets.length; i++) { 1136 if (bankIndices[i] != 0) { 1137 return false; 1138 } 1139 } 1140 1141 return true; 1142 } 1143 1144 return ImageUtil.isBinary(sm); 1148 } 1149} 1150 1151 1152 1153 1154 | Popular Tags |