89 0x0000ff00, 90 0x000000ff, 91 DataBuffer.TYPE_BYTE, 92 false); 93 94 SampleModel bandedSM = 95 new java.awt.image.BandedSampleModel(DataBuffer.TYPE_BYTE, 96 1, 1, 15); 97 98 System.out.println(createColorModel(bilevel.getSampleModel())); 99 System.out.println(createColorModel(gray.getSampleModel())); 100 System.out.println(createColorModel(grayAlpha.getSampleModel())); 101 System.out.println(createColorModel(rgb.getSampleModel())); 102 System.out.println(createColorModel(rgba.getSampleModel())); 103 System.out.println(createColorModel(packed.getSampleModel())); 104 System.out.println(createColorModel(bandedSM)); 105 } 106 */ 107 108 /** 109 * Creates a <code>ColorModel</code> that may be used with the 110 * specified <code>SampleModel</code>. If a suitable 111 * <code>ColorModel</code> cannot be found, this method returns 112 * <code>null</code>. 113 * 114 * <p> Suitable <code>ColorModel</code>s are guaranteed to exist 115 * for all instances of <code>ComponentSampleModel</code>. 116 * For 1- and 3- banded <code>SampleModel</code>s, the returned 117 * <code>ColorModel</code> will be opaque. For 2- and 4-banded 118 * <code>SampleModel</code>s, the output will use alpha transparency 119 * which is not premultiplied. 1- and 2-banded data will use a 120 * grayscale <code>ColorSpace</code>, and 3- and 4-banded data a sRGB 121 * <code>ColorSpace</code>. Data with 5 or more bands will have a 122 * <code>BogusColorSpace</code>.</p> 123 * 124 * <p>An instance of <code>DirectColorModel</code> will be created for 125 * instances of <code>SinglePixelPackedSampleModel</code> with no more 126 * than 4 bands.</p> 127 * 128 * <p>An instance of <code>IndexColorModel</code> will be created for 129 * instances of <code>MultiPixelPackedSampleModel</code>. The colormap 130 * will be a grayscale ramp with <code>1 << numberOfBits</code> 131 * entries ranging from zero to at most 255.</p> 132 * 133 * @return An instance of <code>ColorModel</code> that is suitable for 134 * the supplied <code>SampleModel</code>, or <code>null</code>. 135 * 136 * @throws IllegalArgumentException If <code>sampleModel</code> is 137 * <code>null</code>. 138 */ 139 public static final ColorModel createColorModel(SampleModel sampleModel) { 140 // Check the parameter. 141 if(sampleModel == null) { 142 throw new IllegalArgumentException("sampleModel == null!"); 143 } 144 145 // Get the data type. 146 int dataType = sampleModel.getDataType(); 147 148 // Check the data type 149 switch(dataType) { 150 case DataBuffer.TYPE_BYTE: 151 case DataBuffer.TYPE_USHORT: 152 case DataBuffer.TYPE_SHORT: 153 case DataBuffer.TYPE_INT: 154 case DataBuffer.TYPE_FLOAT: 155 case DataBuffer.TYPE_DOUBLE: 156 break; 157 default: 225 return new DirectColorModel(bits, rmask, gmask, bmask, amask); 226 227 } else if(sampleModel instanceof MultiPixelPackedSampleModel) { 228 // Load the colormap with a ramp. 229 int bitsPerSample = sampleSize[0]; 230 int numEntries = 1 << bitsPerSample; 231 byte[] map = new byte[numEntries]; 232 for (int i = 0; i < numEntries; i++) { 233 map[i] = (byte)(i*255/(numEntries - 1)); 234 } 235 236 colorModel = new IndexColorModel(bitsPerSample, numEntries, 237 map, map, map); 238 239 } 240 241 return colorModel; 242 } 243 244 /** 245 * For the case of binary data (<code>isBinary()</code> returns 246 * <code>true</code>), return the binary data as a packed byte array. 247 * The data will be packed as eight bits per byte with no bit offset, 248 * i.e., the first bit in each image line will be the left-most of the 249 * first byte of the line. The line stride in bytes will be 250 * <code>(int)((getWidth()+7)/8)</code>. The length of the returned 251 * array will be the line stride multiplied by <code>getHeight()</code> 252 * 253 * @return the binary data as a packed array of bytes with zero offset 254 * of <code>null</code> if the data are not binary. 255 * @throws IllegalArgumentException if <code>isBinary()</code> returns 256 * <code>false</code> with the <code>SampleModel</code> of the 257 * supplied <code>Raster</code> as argument. 258 */ 259 public static byte[] getPackedBinaryData(Raster raster, 260 Rectangle rect) { 261 SampleModel sm = raster.getSampleModel(); 262 if(!isBinary(sm)) { 263 throw new IllegalArgumentException(I18N.getString("ImageUtil0")); 264 } 265 266 int rectX = rect.x; 267 int rectY = rect.y; 268 int rectWidth = rect.width; 269 int rectHeight = rect.height; 270 271 DataBuffer dataBuffer = raster.getDataBuffer(); 272 273 int dx = rectX - raster.getSampleModelTranslateX(); 274 int dy = rectY - raster.getSampleModelTranslateY(); 275 276 MultiPixelPackedSampleModel mpp = (MultiPixelPackedSampleModel)sm; 277 int lineStride = mpp.getScanlineStride(); 418 binaryDataArray[b++] = 419 (byte)(left >>> (24 - mod)); 420 } else { 421 int delta = mod - 24; 422 int right = data[i+1]; 423 binaryDataArray[b++] = 424 (byte)((left << delta) | 425 (right >>> (32 - delta))); 426 } 427 } 428 eltOffset += lineStride; 429 } 430 } 431 } 432 433 return binaryDataArray; 434 } 435 436 /** 437 * Returns the binary data unpacked into an array of bytes. 438 * The line stride will be the width of the <code>Raster</code>. 439 * 440 * @throws IllegalArgumentException if <code>isBinary()</code> returns 441 * <code>false</code> with the <code>SampleModel</code> of the 442 * supplied <code>Raster</code> as argument. 443 */ 444 public static byte[] getUnpackedBinaryData(Raster raster, 445 Rectangle rect) { 446 SampleModel sm = raster.getSampleModel(); 447 if(!isBinary(sm)) { 448 throw new IllegalArgumentException(I18N.getString("ImageUtil0")); 449 } 450 451 int rectX = rect.x; 452 int rectY = rect.y; 453 int rectWidth = rect.width; 454 int rectHeight = rect.height; 455 456 DataBuffer dataBuffer = raster.getDataBuffer(); 457 458 int dx = rectX - raster.getSampleModelTranslateX(); 459 int dy = rectY - raster.getSampleModelTranslateY(); 460 461 MultiPixelPackedSampleModel mpp = (MultiPixelPackedSampleModel)sm; 462 int lineStride = mpp.getScanlineStride(); 498 } 499 } else if(dataBuffer instanceof DataBufferInt) { 500 int[] data = ((DataBufferInt)dataBuffer).getData(); 501 for(int y = rectY; y < maxY; y++) { 502 int bOffset = eltOffset*32 + bitOffset; 503 for(int x = rectX; x < maxX; x++) { 504 int i = data[bOffset/32]; 505 bdata[k++] = 506 (byte)((i >>> (31 - bOffset % 32)) & 507 0x0000001); 508 bOffset++; 509 } 510 eltOffset += lineStride; 511 } 512 } 513 514 return bdata; 515 } 516 517 /** 518 * Sets the supplied <code>Raster</code>'s data from an array 519 * of packed binary data of the form returned by 520 * <code>getPackedBinaryData()</code>. 521 * 522 * @throws IllegalArgumentException if <code>isBinary()</code> returns 523 * <code>false</code> with the <code>SampleModel</code> of the 524 * supplied <code>Raster</code> as argument. 525 */ 526 public static void setPackedBinaryData(byte[] binaryDataArray, 527 WritableRaster raster, 528 Rectangle rect) { 529 SampleModel sm = raster.getSampleModel(); 530 if(!isBinary(sm)) { 531 throw new IllegalArgumentException(I18N.getString("ImageUtil0")); 532 } 533 534 int rectX = rect.x; 535 int rectY = rect.y; 536 int rectWidth = rect.width; 537 int rectHeight = rect.height; 538 539 DataBuffer dataBuffer = raster.getDataBuffer(); 540 541 int dx = rectX - raster.getSampleModelTranslateX(); 542 int dy = rectY - raster.getSampleModelTranslateY(); 543 544 MultiPixelPackedSampleModel mpp = (MultiPixelPackedSampleModel)sm; 744 } else if (xRemaining > leftShift) { 745 // This BYTE will be set into two INTs; 746 // But not all the low bits will be set into INT 747 data[i] = (data[i] & mask) | (datum >>> rightShift); 748 i++; 749 data[i] = (data[i] & mask1) | (datum << leftShift); 750 } else { 751 // Only some of the high bits will be set into INT 752 int remainMask = (1 << leftShift - xRemaining) - 1; 753 data[i] = (data[i] & (mask | remainMask)) | 754 (datum >>> rightShift & ~remainMask); 755 } 756 } 757 eltOffset += lineStride; 758 } 759 } 760 } 761 } 762 763 /** 764 * Copies data into the packed array of the <code>Raster</code> 765 * from an array of unpacked data of the form returned by 766 * <code>getUnpackedBinaryData()</code>. 767 * 768 * <p> If the data are binary, then the target bit will be set if 769 * and only if the corresponding byte is non-zero. 770 * 771 * @throws IllegalArgumentException if <code>isBinary()</code> returns 772 * <code>false</code> with the <code>SampleModel</code> of the 773 * supplied <code>Raster</code> as argument. 774 */ 775 public static void setUnpackedBinaryData(byte[] bdata, 776 WritableRaster raster, 777 Rectangle rect) { 778 SampleModel sm = raster.getSampleModel(); 779 if(!isBinary(sm)) { 780 throw new IllegalArgumentException(I18N.getString("ImageUtil0")); 781 } 782 783 int rectX = rect.x; 784 int rectY = rect.y; 785 int rectWidth = rect.width; 786 int rectHeight = rect.height; 787 788 DataBuffer dataBuffer = raster.getDataBuffer(); 789 790 int dx = rectX - raster.getSampleModelTranslateX(); 791 int dy = rectY - raster.getSampleModelTranslateY(); 792 793 MultiPixelPackedSampleModel mpp = (MultiPixelPackedSampleModel)sm; 1014 ComponentSampleModel csm = (ComponentSampleModel)sm; 1015 int pixelStride = csm.getPixelStride(); 1016 int scanlineStride = csm.getScanlineStride(); 1017 long size = Math.min(pixelStride, scanlineStride); 1018 1019 if (pixelStride > 0) 1020 size += pixelStride * (sm.getWidth() - 1); 1021 if (scanlineStride > 0) 1022 size += scanlineStride * (sm.getHeight() - 1); 1023 return size * ((elementSize + 7) / 8); 1024 } else 1025 return getTileSize(sm); 1026 } 1027 /** 1028 * Tests whether the color indices represent a gray-scale image. 1029 * 1030 * @param r The red channel color indices. 1031 * @param g The green channel color indices. 1032 * @param b The blue channel color indices. 1033 * @return If all the indices have 256 entries, and are identical mappings, 1034 * return <code>true</code>; otherwise, return <code>false</code>. 1035 */ 1036 public static boolean isIndicesForGrayscale(byte[] r, byte[] g, byte[] b) { 1037 if (r.length != g.length || r.length != b.length) 1038 return false; 1039 1040 int size = r.length; 1041 1042 if (size != 256) 1043 return false; 1044 1045 for (int i = 0; i < size; i++) { 1046 byte temp = (byte) i; 1047 1048 if (r[i] != temp || g[i] != temp || b[i] != temp) 1049 return false; 1050 } 1051 1052 return true; 1053 } 1054 1055 /** Converts the provided object to <code>String</code> */ 1056 public static String convertObjectToString(Object obj) { 1057 if (obj == null) 1058 return ""; 1059 1060 String s = ""; 1061 if (obj instanceof byte[]) { 1062 byte[] bArray = (byte[])obj; 1063 for (int i = 0; i < bArray.length; i++) 1064 s += bArray[i] + " "; 1065 return s; 1066 } 1067 1068 if (obj instanceof int[]) { 1069 int[] iArray = (int[])obj; 1070 for (int i = 0; i < iArray.length; i++) 1071 s += iArray[i] + " " ; 1072 return s; 1073 } 1074 1075 if (obj instanceof short[]) { 1076 short[] sArray = (short[])obj; 1077 for (int i = 0; i < sArray.length; i++) 1078 s += sArray[i] + " " ; 1079 return s; 1080 } 1081 1082 return obj.toString(); 1083 1084 } 1085 1086 /** Checks that the provided <code>ImageWriter</code> can encode 1087 * the provided <code>ImageTypeSpecifier</code> or not. If not, an 1088 * <code>IIOException</code> will be thrown. 1089 * @param writer The provided <code>ImageWriter</code>. 1090 * @param type The image to be tested. 1091 * @throws IIOException If the writer cannot encoded the provided image. 1092 */ 1093 public static final void canEncodeImage(ImageWriter writer, 1094 ImageTypeSpecifier type) 1095 throws IIOException { 1096 ImageWriterSpi spi = writer.getOriginatingProvider(); 1097 1098 if(type != null && spi != null && !spi.canEncodeImage(type)) { 1099 throw new IIOException(I18N.getString("ImageUtil2")+" "+ 1100 writer.getClass().getName()); 1101 } 1102 } 1103 1104 /** Checks that the provided <code>ImageWriter</code> can encode 1105 * the provided <code>ColorModel</code> and <code>SampleModel</code>. 1106 * If not, an <code>IIOException</code> will be thrown. 1107 * @param writer The provided <code>ImageWriter</code>. 1108 * @param colorModel The provided <code>ColorModel</code>. 1109 * @param sampleModel The provided <code>SampleModel</code>. 1110 * @throws IIOException If the writer cannot encoded the provided image. 1111 */ 1112 public static final void canEncodeImage(ImageWriter writer, 1113 ColorModel colorModel, 1114 SampleModel sampleModel) 1115 throws IIOException { 1116 ImageTypeSpecifier type = null; 1117 if (colorModel != null && sampleModel != null) 1118 type = new ImageTypeSpecifier(colorModel, sampleModel); 1119 canEncodeImage(writer, type); 1120 } 1121 1122 /** 1123 * Returns whether the image has contiguous data across rows. 1124 */ 1125 public static final boolean imageIsContiguous(RenderedImage image) { 1126 SampleModel sm; 1127 if(image instanceof BufferedImage) { 1128 WritableRaster ras = ((BufferedImage)image).getRaster(); 1129 sm = ras.getSampleModel(); | 89 0x0000ff00, 90 0x000000ff, 91 DataBuffer.TYPE_BYTE, 92 false); 93 94 SampleModel bandedSM = 95 new java.awt.image.BandedSampleModel(DataBuffer.TYPE_BYTE, 96 1, 1, 15); 97 98 System.out.println(createColorModel(bilevel.getSampleModel())); 99 System.out.println(createColorModel(gray.getSampleModel())); 100 System.out.println(createColorModel(grayAlpha.getSampleModel())); 101 System.out.println(createColorModel(rgb.getSampleModel())); 102 System.out.println(createColorModel(rgba.getSampleModel())); 103 System.out.println(createColorModel(packed.getSampleModel())); 104 System.out.println(createColorModel(bandedSM)); 105 } 106 */ 107 108 /** 109 * Creates a {@code ColorModel} that may be used with the 110 * specified {@code SampleModel}. If a suitable 111 * {@code ColorModel} cannot be found, this method returns 112 * {@code null}. 113 * 114 * <p> Suitable {@code ColorModel}s are guaranteed to exist 115 * for all instances of {@code ComponentSampleModel}. 116 * For 1- and 3- banded {@code SampleModel}s, the returned 117 * {@code ColorModel} will be opaque. For 2- and 4-banded 118 * {@code SampleModel}s, the output will use alpha transparency 119 * which is not premultiplied. 1- and 2-banded data will use a 120 * grayscale {@code ColorSpace}, and 3- and 4-banded data a sRGB 121 * {@code ColorSpace}. Data with 5 or more bands will have a 122 * {@code BogusColorSpace}.</p> 123 * 124 * <p>An instance of {@code DirectColorModel} will be created for 125 * instances of {@code SinglePixelPackedSampleModel} with no more 126 * than 4 bands.</p> 127 * 128 * <p>An instance of {@code IndexColorModel} will be created for 129 * instances of {@code MultiPixelPackedSampleModel}. The colormap 130 * will be a grayscale ramp with <code>1 << numberOfBits</code> 131 * entries ranging from zero to at most 255.</p> 132 * 133 * @return An instance of {@code ColorModel} that is suitable for 134 * the supplied {@code SampleModel}, or {@code null}. 135 * 136 * @throws IllegalArgumentException If {@code sampleModel} is 137 * {@code null}. 138 */ 139 public static final ColorModel createColorModel(SampleModel sampleModel) { 140 // Check the parameter. 141 if(sampleModel == null) { 142 throw new IllegalArgumentException("sampleModel == null!"); 143 } 144 145 // Get the data type. 146 int dataType = sampleModel.getDataType(); 147 148 // Check the data type 149 switch(dataType) { 150 case DataBuffer.TYPE_BYTE: 151 case DataBuffer.TYPE_USHORT: 152 case DataBuffer.TYPE_SHORT: 153 case DataBuffer.TYPE_INT: 154 case DataBuffer.TYPE_FLOAT: 155 case DataBuffer.TYPE_DOUBLE: 156 break; 157 default: 225 return new DirectColorModel(bits, rmask, gmask, bmask, amask); 226 227 } else if(sampleModel instanceof MultiPixelPackedSampleModel) { 228 // Load the colormap with a ramp. 229 int bitsPerSample = sampleSize[0]; 230 int numEntries = 1 << bitsPerSample; 231 byte[] map = new byte[numEntries]; 232 for (int i = 0; i < numEntries; i++) { 233 map[i] = (byte)(i*255/(numEntries - 1)); 234 } 235 236 colorModel = new IndexColorModel(bitsPerSample, numEntries, 237 map, map, map); 238 239 } 240 241 return colorModel; 242 } 243 244 /** 245 * For the case of binary data ({@code isBinary()} returns 246 * {@code true}), return the binary data as a packed byte array. 247 * The data will be packed as eight bits per byte with no bit offset, 248 * i.e., the first bit in each image line will be the left-most of the 249 * first byte of the line. The line stride in bytes will be 250 * {@code (int)((getWidth()+7)/8)}. The length of the returned 251 * array will be the line stride multiplied by {@code getHeight()} 252 * 253 * @return the binary data as a packed array of bytes with zero offset 254 * of {@code null} if the data are not binary. 255 * @throws IllegalArgumentException if {@code isBinary()} returns 256 * {@code false} with the {@code SampleModel} of the 257 * supplied {@code Raster} as argument. 258 */ 259 public static byte[] getPackedBinaryData(Raster raster, 260 Rectangle rect) { 261 SampleModel sm = raster.getSampleModel(); 262 if(!isBinary(sm)) { 263 throw new IllegalArgumentException(I18N.getString("ImageUtil0")); 264 } 265 266 int rectX = rect.x; 267 int rectY = rect.y; 268 int rectWidth = rect.width; 269 int rectHeight = rect.height; 270 271 DataBuffer dataBuffer = raster.getDataBuffer(); 272 273 int dx = rectX - raster.getSampleModelTranslateX(); 274 int dy = rectY - raster.getSampleModelTranslateY(); 275 276 MultiPixelPackedSampleModel mpp = (MultiPixelPackedSampleModel)sm; 277 int lineStride = mpp.getScanlineStride(); 418 binaryDataArray[b++] = 419 (byte)(left >>> (24 - mod)); 420 } else { 421 int delta = mod - 24; 422 int right = data[i+1]; 423 binaryDataArray[b++] = 424 (byte)((left << delta) | 425 (right >>> (32 - delta))); 426 } 427 } 428 eltOffset += lineStride; 429 } 430 } 431 } 432 433 return binaryDataArray; 434 } 435 436 /** 437 * Returns the binary data unpacked into an array of bytes. 438 * The line stride will be the width of the {@code Raster}. 439 * 440 * @throws IllegalArgumentException if {@code isBinary()} returns 441 * {@code false} with the {@code SampleModel} of the 442 * supplied {@code Raster} as argument. 443 */ 444 public static byte[] getUnpackedBinaryData(Raster raster, 445 Rectangle rect) { 446 SampleModel sm = raster.getSampleModel(); 447 if(!isBinary(sm)) { 448 throw new IllegalArgumentException(I18N.getString("ImageUtil0")); 449 } 450 451 int rectX = rect.x; 452 int rectY = rect.y; 453 int rectWidth = rect.width; 454 int rectHeight = rect.height; 455 456 DataBuffer dataBuffer = raster.getDataBuffer(); 457 458 int dx = rectX - raster.getSampleModelTranslateX(); 459 int dy = rectY - raster.getSampleModelTranslateY(); 460 461 MultiPixelPackedSampleModel mpp = (MultiPixelPackedSampleModel)sm; 462 int lineStride = mpp.getScanlineStride(); 498 } 499 } else if(dataBuffer instanceof DataBufferInt) { 500 int[] data = ((DataBufferInt)dataBuffer).getData(); 501 for(int y = rectY; y < maxY; y++) { 502 int bOffset = eltOffset*32 + bitOffset; 503 for(int x = rectX; x < maxX; x++) { 504 int i = data[bOffset/32]; 505 bdata[k++] = 506 (byte)((i >>> (31 - bOffset % 32)) & 507 0x0000001); 508 bOffset++; 509 } 510 eltOffset += lineStride; 511 } 512 } 513 514 return bdata; 515 } 516 517 /** 518 * Sets the supplied {@code Raster}'s data from an array 519 * of packed binary data of the form returned by 520 * {@code getPackedBinaryData()}. 521 * 522 * @throws IllegalArgumentException if {@code isBinary()} returns 523 * {@code false} with the {@code SampleModel} of the 524 * supplied {@code Raster} as argument. 525 */ 526 public static void setPackedBinaryData(byte[] binaryDataArray, 527 WritableRaster raster, 528 Rectangle rect) { 529 SampleModel sm = raster.getSampleModel(); 530 if(!isBinary(sm)) { 531 throw new IllegalArgumentException(I18N.getString("ImageUtil0")); 532 } 533 534 int rectX = rect.x; 535 int rectY = rect.y; 536 int rectWidth = rect.width; 537 int rectHeight = rect.height; 538 539 DataBuffer dataBuffer = raster.getDataBuffer(); 540 541 int dx = rectX - raster.getSampleModelTranslateX(); 542 int dy = rectY - raster.getSampleModelTranslateY(); 543 544 MultiPixelPackedSampleModel mpp = (MultiPixelPackedSampleModel)sm; 744 } else if (xRemaining > leftShift) { 745 // This BYTE will be set into two INTs; 746 // But not all the low bits will be set into INT 747 data[i] = (data[i] & mask) | (datum >>> rightShift); 748 i++; 749 data[i] = (data[i] & mask1) | (datum << leftShift); 750 } else { 751 // Only some of the high bits will be set into INT 752 int remainMask = (1 << leftShift - xRemaining) - 1; 753 data[i] = (data[i] & (mask | remainMask)) | 754 (datum >>> rightShift & ~remainMask); 755 } 756 } 757 eltOffset += lineStride; 758 } 759 } 760 } 761 } 762 763 /** 764 * Copies data into the packed array of the {@code Raster} 765 * from an array of unpacked data of the form returned by 766 * {@code getUnpackedBinaryData()}. 767 * 768 * <p> If the data are binary, then the target bit will be set if 769 * and only if the corresponding byte is non-zero. 770 * 771 * @throws IllegalArgumentException if {@code isBinary()} returns 772 * {@code false} with the {@code SampleModel} of the 773 * supplied {@code Raster} as argument. 774 */ 775 public static void setUnpackedBinaryData(byte[] bdata, 776 WritableRaster raster, 777 Rectangle rect) { 778 SampleModel sm = raster.getSampleModel(); 779 if(!isBinary(sm)) { 780 throw new IllegalArgumentException(I18N.getString("ImageUtil0")); 781 } 782 783 int rectX = rect.x; 784 int rectY = rect.y; 785 int rectWidth = rect.width; 786 int rectHeight = rect.height; 787 788 DataBuffer dataBuffer = raster.getDataBuffer(); 789 790 int dx = rectX - raster.getSampleModelTranslateX(); 791 int dy = rectY - raster.getSampleModelTranslateY(); 792 793 MultiPixelPackedSampleModel mpp = (MultiPixelPackedSampleModel)sm; 1014 ComponentSampleModel csm = (ComponentSampleModel)sm; 1015 int pixelStride = csm.getPixelStride(); 1016 int scanlineStride = csm.getScanlineStride(); 1017 long size = Math.min(pixelStride, scanlineStride); 1018 1019 if (pixelStride > 0) 1020 size += pixelStride * (sm.getWidth() - 1); 1021 if (scanlineStride > 0) 1022 size += scanlineStride * (sm.getHeight() - 1); 1023 return size * ((elementSize + 7) / 8); 1024 } else 1025 return getTileSize(sm); 1026 } 1027 /** 1028 * Tests whether the color indices represent a gray-scale image. 1029 * 1030 * @param r The red channel color indices. 1031 * @param g The green channel color indices. 1032 * @param b The blue channel color indices. 1033 * @return If all the indices have 256 entries, and are identical mappings, 1034 * return {@code true}; otherwise, return {@code false}. 1035 */ 1036 public static boolean isIndicesForGrayscale(byte[] r, byte[] g, byte[] b) { 1037 if (r.length != g.length || r.length != b.length) 1038 return false; 1039 1040 int size = r.length; 1041 1042 if (size != 256) 1043 return false; 1044 1045 for (int i = 0; i < size; i++) { 1046 byte temp = (byte) i; 1047 1048 if (r[i] != temp || g[i] != temp || b[i] != temp) 1049 return false; 1050 } 1051 1052 return true; 1053 } 1054 1055 /** Converts the provided object to {@code String} */ 1056 public static String convertObjectToString(Object obj) { 1057 if (obj == null) 1058 return ""; 1059 1060 String s = ""; 1061 if (obj instanceof byte[]) { 1062 byte[] bArray = (byte[])obj; 1063 for (int i = 0; i < bArray.length; i++) 1064 s += bArray[i] + " "; 1065 return s; 1066 } 1067 1068 if (obj instanceof int[]) { 1069 int[] iArray = (int[])obj; 1070 for (int i = 0; i < iArray.length; i++) 1071 s += iArray[i] + " " ; 1072 return s; 1073 } 1074 1075 if (obj instanceof short[]) { 1076 short[] sArray = (short[])obj; 1077 for (int i = 0; i < sArray.length; i++) 1078 s += sArray[i] + " " ; 1079 return s; 1080 } 1081 1082 return obj.toString(); 1083 1084 } 1085 1086 /** Checks that the provided {@code ImageWriter} can encode 1087 * the provided {@code ImageTypeSpecifier} or not. If not, an 1088 * {@code IIOException} will be thrown. 1089 * @param writer The provided {@code ImageWriter}. 1090 * @param type The image to be tested. 1091 * @throws IIOException If the writer cannot encoded the provided image. 1092 */ 1093 public static final void canEncodeImage(ImageWriter writer, 1094 ImageTypeSpecifier type) 1095 throws IIOException { 1096 ImageWriterSpi spi = writer.getOriginatingProvider(); 1097 1098 if(type != null && spi != null && !spi.canEncodeImage(type)) { 1099 throw new IIOException(I18N.getString("ImageUtil2")+" "+ 1100 writer.getClass().getName()); 1101 } 1102 } 1103 1104 /** Checks that the provided {@code ImageWriter} can encode 1105 * the provided {@code ColorModel} and {@code SampleModel}. 1106 * If not, an {@code IIOException} will be thrown. 1107 * @param writer The provided {@code ImageWriter}. 1108 * @param colorModel The provided {@code ColorModel}. 1109 * @param sampleModel The provided {@code SampleModel}. 1110 * @throws IIOException If the writer cannot encoded the provided image. 1111 */ 1112 public static final void canEncodeImage(ImageWriter writer, 1113 ColorModel colorModel, 1114 SampleModel sampleModel) 1115 throws IIOException { 1116 ImageTypeSpecifier type = null; 1117 if (colorModel != null && sampleModel != null) 1118 type = new ImageTypeSpecifier(colorModel, sampleModel); 1119 canEncodeImage(writer, type); 1120 } 1121 1122 /** 1123 * Returns whether the image has contiguous data across rows. 1124 */ 1125 public static final boolean imageIsContiguous(RenderedImage image) { 1126 SampleModel sm; 1127 if(image instanceof BufferedImage) { 1128 WritableRaster ras = ((BufferedImage)image).getRaster(); 1129 sm = ras.getSampleModel(); |