1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 /** 18 * @author Igor V. Stolyarov 19 * @version $Revision$ 20 */ 21 22 package java.awt.image; 23 24 import java.awt.Point; 25 import java.awt.Rectangle; 26 27 import org.apache.harmony.awt.internal.nls.Messages; 28 29 /** 30 * The WritableRaster class provides functionality for writing samples and pixel 31 * capabilities to the Raster. 32 * 33 * @since Android 1.0 34 */ 35 public class WritableRaster extends Raster { 36 37 /** 38 * Instantiates a new WritableRaster object with the specified SampleModel, 39 * DataBuffer, rectangular region and parent WritableRaster. 40 * 41 * @param sampleModel 42 * the specified SampleModel. 43 * @param dataBuffer 44 * the specified DataBuffer. 45 * @param aRegion 46 * the rectangular region which defines the new image bounds. 47 * @param sampleModelTranslate 48 * this point defines the translation point from the SampleModel 49 * to the new WritableRaster coordinates. 50 * @param parent 51 * the parent of this WritableRaster. 52 */ 53 protected WritableRaster(SampleModel sampleModel, DataBuffer dataBuffer, Rectangle aRegion, 54 Point sampleModelTranslate, WritableRaster parent) { 55 super(sampleModel, dataBuffer, aRegion, sampleModelTranslate, parent); 56 } 57 58 /** 59 * Instantiates a new WritableRaster object with the specified SampleModel 60 * which defines a layout of this WritableRaster and DataBuffer objects 61 * which defines the image data. 62 * 63 * @param sampleModel 64 * the specified SampleModel. 65 * @param dataBuffer 66 * the specified DataBuffer. 67 * @param origin 68 * the point of origin. 69 */ 70 protected WritableRaster(SampleModel sampleModel, DataBuffer dataBuffer, Point origin) { 71 this(sampleModel, dataBuffer, new Rectangle(origin.x, origin.y, sampleModel.width, 72 sampleModel.height), origin, null); 73 } 74 75 /** 76 * Instantiates a new WritableRaster with the specified SampleModel. 77 * 78 * @param sampleModel 79 * the specified SampleModel. 80 * @param origin 81 * the origin. 82 */ 83 protected WritableRaster(SampleModel sampleModel, Point origin) { 84 this(sampleModel, sampleModel.createDataBuffer(), new Rectangle(origin.x, origin.y, 85 sampleModel.width, sampleModel.height), origin, null); 86 } 87 88 /** 89 * Sets the data for a single pixel from an input Object which represents an 90 * array of primitive types: DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT, 91 * DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT, DataBuffer.TYPE_FLOAT, or 92 * DataBuffer.TYPE_DOUBLE. 93 * 94 * @param x 95 * the X coordinate of the pixel. 96 * @param y 97 * the Y coordinate of the pixel. 98 * @param inData 99 * the input data. 100 */ 101 public void setDataElements(int x, int y, Object inData) { 102 sampleModel.setDataElements(x - sampleModelTranslateX, y - sampleModelTranslateY, inData, 103 dataBuffer); 104 } 105 106 /** 107 * Sets the data elements which represent pixel data to the specified 108 * rectangle area as a primitive array. The following image data types are 109 * supported: DataBuffer.TYPE_BYTE, DataBuffer.TYPE_USHORT, 110 * DataBuffer.TYPE_INT, DataBuffer.TYPE_SHORT, DataBuffer.TYPE_FLOAT, or 111 * DataBuffer.TYPE_DOUBLE. 112 * 113 * @param x 114 * the X coordinate of the rectangle of pixels. 115 * @param y 116 * the Y coordinate of the rectangle of pixels. 117 * @param w 118 * the width of the rectangle of pixels. 119 * @param h 120 * the height of the rectangle of pixels. 121 * @param inData 122 * the array of primitive type data to be set to the specified 123 * area. 124 */ 125 public void setDataElements(int x, int y, int w, int h, Object inData) { 126 sampleModel.setDataElements(x - sampleModelTranslateX, y - sampleModelTranslateY, w, h, 127 inData, dataBuffer); 128 } 129 130 /** 131 * Creates the child of this WritableRaster by sharing the specified 132 * rectangular area in this WritableRaster. The parentX, parentY, width and 133 * height parameters specify rectangular area to be shared. 134 * 135 * @param parentX 136 * the X coordinate of the upper left corner of the shared 137 * rectangle with respect to this WritableRaster' coordinates. 138 * @param parentY 139 * the Y coordinate of the upper left corner of the shared 140 * rectangle with respect to this WritableRaster' coordinates. 141 * @param w 142 * the width of the child area. 143 * @param h 144 * the height of the child area. 145 * @param childMinX 146 * the X coordinate of child area mapped to the parentX 147 * coordinate. 148 * @param childMinY 149 * the Y coordinate of child area mapped to the parentY 150 * coordinate. 151 * @param bandList 152 * the array of band indices. 153 * @return the child WritableRaster. 154 */ 155 public WritableRaster createWritableChild(int parentX, int parentY, int w, int h, 156 int childMinX, int childMinY, int bandList[]) { 157 if (w <= 0 || h <= 0) { 158 // awt.244=Width or Height of child Raster is less than or equal to 159 // zero 160 throw new RasterFormatException(Messages.getString("awt.244")); //$NON-NLS-1$ 161 } 162 163 if (parentX < this.minX || parentX + w > this.minX + this.width) { 164 // awt.245=parentX disposes outside Raster 165 throw new RasterFormatException(Messages.getString("awt.245")); //$NON-NLS-1$ 166 } 167 168 if (parentY < this.minY || parentY + h > this.minY + this.height) { 169 // awt.246=parentY disposes outside Raster 170 throw new RasterFormatException(Messages.getString("awt.246")); //$NON-NLS-1$ 171 } 172 173 if ((long)parentX + w > Integer.MAX_VALUE) { 174 // awt.247=parentX + w results in integer overflow 175 throw new RasterFormatException(Messages.getString("awt.247")); //$NON-NLS-1$ 176 } 177 178 if ((long)parentY + h > Integer.MAX_VALUE) { 179 // awt.248=parentY + h results in integer overflow 180 throw new RasterFormatException(Messages.getString("awt.248")); //$NON-NLS-1$ 181 } 182 183 if ((long)childMinX + w > Integer.MAX_VALUE) { 184 // awt.249=childMinX + w results in integer overflow 185 throw new RasterFormatException(Messages.getString("awt.249")); //$NON-NLS-1$ 186 } 187 188 if ((long)childMinY + h > Integer.MAX_VALUE) { 189 // awt.24A=childMinY + h results in integer overflow 190 throw new RasterFormatException(Messages.getString("awt.24A")); //$NON-NLS-1$ 191 } 192 193 SampleModel childModel; 194 195 if (bandList == null) { 196 childModel = sampleModel; 197 } else { 198 childModel = sampleModel.createSubsetSampleModel(bandList); 199 } 200 201 int childTranslateX = childMinX - parentX; 202 int childTranslateY = childMinY - parentY; 203 204 return new WritableRaster(childModel, dataBuffer, 205 new Rectangle(childMinX, childMinY, w, h), new Point(childTranslateX 206 + sampleModelTranslateX, childTranslateY + sampleModelTranslateY), this); 207 } 208 209 /** 210 * Creates the translated child of this WritableRaster. New WritableRaster 211 * object is a reference to the this WritableRaster and with different 212 * location. 213 * 214 * @param childMinX 215 * the X coordinate of the new WritableRaster. 216 * @param childMinY 217 * the Y coordinate of the new WritableRaster. 218 * @return the WritableRaster. 219 */ 220 public WritableRaster createWritableTranslatedChild(int childMinX, int childMinY) { 221 return createWritableChild(minX, minY, width, height, childMinX, childMinY, null); 222 } 223 224 /** 225 * Gets the parent WritableRaster for this WritableRaster object. 226 * 227 * @return the parent WritableRaster for this WritableRaster object. 228 */ 229 public WritableRaster getWritableParent() { 230 return (WritableRaster)parent; 231 } 232 233 /** 234 * Sets pixels from the specified source Raster srcRaster to this 235 * WritableRaster. 236 * 237 * @param srcRaster 238 * the source Raster. 239 */ 240 public void setRect(Raster srcRaster) { 241 setRect(0, 0, srcRaster); 242 } 243 244 /** 245 * Sets pixels from the specified source Raster srcRaster to this 246 * WritableRaster. Each pixel with (x, y) coordinates from the source Raster 247 * is copied to pixel with (x+dx, y+dy) coordinates in this WritableRaster. 248 * The pixels with (x+dx, y+dy) coordinates which are out the bounds of this 249 * raster are ignored. 250 * 251 * @param dx 252 * the distance the pixel's X coordinate in the source Raster is 253 * translated when writtien to this WritableRaster. 254 * @param dy 255 * the distance the pixel's Y coordinate in the source Raster is 256 * translated when writtien to this WritableRaster. 257 * @param srcRaster 258 * the source Raster. 259 */ 260 public void setRect(int dx, int dy, Raster srcRaster) { 261 int w = srcRaster.getWidth(); 262 int h = srcRaster.getHeight(); 263 264 int srcX = srcRaster.getMinX(); 265 int srcY = srcRaster.getMinY(); 266 267 int dstX = srcX + dx; 268 int dstY = srcY + dy; 269 270 if (dstX < this.minX) { 271 int minOffX = this.minX - dstX; 272 w -= minOffX; 273 dstX = this.minX; 274 srcX += minOffX; 275 } 276 277 if (dstY < this.minY) { 278 int minOffY = this.minY - dstY; 279 h -= minOffY; 280 dstY = this.minY; 281 srcY += minOffY; 282 } 283 284 if (dstX + w > this.minX + this.width) { 285 int maxOffX = (dstX + w) - (this.minX + this.width); 286 w -= maxOffX; 287 } 288 289 if (dstY + h > this.minY + this.height) { 290 int maxOffY = (dstY + h) - (this.minY + this.height); 291 h -= maxOffY; 292 } 293 294 if (w <= 0 || h <= 0) { 295 return; 296 } 297 298 switch (sampleModel.getDataType()) { 299 case DataBuffer.TYPE_BYTE: 300 case DataBuffer.TYPE_SHORT: 301 case DataBuffer.TYPE_USHORT: 302 case DataBuffer.TYPE_INT: 303 int iPixelsLine[] = null; 304 for (int i = 0; i < h; i++) { 305 iPixelsLine = srcRaster.getPixels(srcX, srcY + i, w, 1, iPixelsLine); 306 setPixels(dstX, dstY + i, w, 1, iPixelsLine); 307 } 308 break; 309 310 case DataBuffer.TYPE_FLOAT: 311 float fPixelsLine[] = null; 312 for (int i = 0; i < h; i++) { 313 fPixelsLine = srcRaster.getPixels(srcX, srcY + i, w, 1, fPixelsLine); 314 setPixels(dstX, dstY + i, w, 1, fPixelsLine); 315 } 316 break; 317 318 case DataBuffer.TYPE_DOUBLE: 319 double dPixelsLine[] = null; 320 for (int i = 0; i < h; i++) { 321 dPixelsLine = srcRaster.getPixels(srcX, srcY + i, w, 1, dPixelsLine); 322 setPixels(dstX, dstY + i, w, 1, dPixelsLine); 323 } 324 break; 325 } 326 } 327 328 /** 329 * Sets the data for a rectangle of pixels from an input Raster to this 330 * WritableRaster. 331 * 332 * @param x 333 * the X coordinate of the point where the data of the input 334 * Raster is to be written. 335 * @param y 336 * the Y coordinate of the point where the data of the input 337 * Raster is to be written. 338 * @param inRaster 339 * the input Raster. 340 */ 341 public void setDataElements(int x, int y, Raster inRaster) { 342 int dstX = x + inRaster.getMinX(); 343 int dstY = y + inRaster.getMinY(); 344 345 int w = inRaster.getWidth(); 346 int h = inRaster.getHeight(); 347 348 if (dstX < this.minX || dstX + w > this.minX + this.width || dstY < this.minY 349 || dstY + h > this.minY + this.height) { 350 // awt.63=Coordinates are not in bounds 351 throw new ArrayIndexOutOfBoundsException(Messages.getString("awt.63")); //$NON-NLS-1$ 352 } 353 354 int srcX = inRaster.getMinX(); 355 int srcY = inRaster.getMinY(); 356 Object line = null; 357 358 for (int i = 0; i < h; i++) { 359 line = inRaster.getDataElements(srcX, srcY + i, w, 1, line); 360 setDataElements(dstX, dstY + i, w, 1, line); 361 } 362 } 363 364 /** 365 * Sets an integer array of samples for the specified pixel in this 366 * WritableRaster. 367 * 368 * @param x 369 * the pixel's X coordinate. 370 * @param y 371 * the pixel's Y coordinate. 372 * @param iArray 373 * the integer array of samples. 374 */ 375 public void setPixel(int x, int y, int iArray[]) { 376 sampleModel.setPixel(x - sampleModelTranslateX, y - sampleModelTranslateY, iArray, 377 dataBuffer); 378 } 379 380 /** 381 * Sets a float array of samples for the specified pixel in this 382 * WritableRaster. 383 * 384 * @param x 385 * the pixel's X coordinate. 386 * @param y 387 * the pixel's Y coordinate. 388 * @param fArray 389 * the float array of samples. 390 */ 391 public void setPixel(int x, int y, float fArray[]) { 392 sampleModel.setPixel(x - sampleModelTranslateX, y - sampleModelTranslateY, fArray, 393 dataBuffer); 394 } 395 396 /** 397 * Sets a double array of samples for the specified pixel in this 398 * WritableRaster. 399 * 400 * @param x 401 * the pixel's X coordinate. 402 * @param y 403 * the pixel's Y coordinate. 404 * @param dArray 405 * the double array of samples. 406 */ 407 public void setPixel(int x, int y, double dArray[]) { 408 sampleModel.setPixel(x - sampleModelTranslateX, y - sampleModelTranslateY, dArray, 409 dataBuffer); 410 } 411 412 /** 413 * Sets a integer array of samples for the specified rectangular area of 414 * pixels in this WritableRaster. 415 * 416 * @param x 417 * the X coordinate of rectangular area. 418 * @param y 419 * the Y coordinate of rectangular area. 420 * @param w 421 * the width of rectangular area. 422 * @param h 423 * the height of rectangular area. 424 * @param iArray 425 * the integer array of samples. 426 */ 427 public void setPixels(int x, int y, int w, int h, int iArray[]) { 428 sampleModel.setPixels(x - sampleModelTranslateX, y - sampleModelTranslateY, w, h, iArray, 429 dataBuffer); 430 } 431 432 /** 433 * Sets a float array of samples for the specified rectangular area of 434 * pixels in this WritableRaster. 435 * 436 * @param x 437 * the X coordinate of rectangular area. 438 * @param y 439 * the Y coordinate of rectangular area. 440 * @param w 441 * the width of rectangular area. 442 * @param h 443 * the height of rectangular area. 444 * @param fArray 445 * the float array of samples. 446 */ 447 public void setPixels(int x, int y, int w, int h, float fArray[]) { 448 sampleModel.setPixels(x - sampleModelTranslateX, y - sampleModelTranslateY, w, h, fArray, 449 dataBuffer); 450 } 451 452 /** 453 * Sets a double array of samples for the specified rectangular area of 454 * pixels in this WritableRaster. 455 * 456 * @param x 457 * the X coordinate of rectangular area. 458 * @param y 459 * the Y coordinate of rectangular area. 460 * @param w 461 * the width of rectangular area. 462 * @param h 463 * the height of rectangular area. 464 * @param dArray 465 * the double array of samples. 466 */ 467 public void setPixels(int x, int y, int w, int h, double dArray[]) { 468 sampleModel.setPixels(x - sampleModelTranslateX, y - sampleModelTranslateY, w, h, dArray, 469 dataBuffer); 470 } 471 472 /** 473 * Sets the samples for the specified band and the specified rectangular 474 * area of pixels with an integer array of samples. 475 * 476 * @param x 477 * the X coordinate of the area of pixels. 478 * @param y 479 * the Y coordinate of the area of pixels. 480 * @param w 481 * the width of the area of pixels. 482 * @param h 483 * the height of the area of pixels. 484 * @param b 485 * the specified band. 486 * @param iArray 487 * the integer array of samples. 488 */ 489 public void setSamples(int x, int y, int w, int h, int b, int iArray[]) { 490 sampleModel.setSamples(x - sampleModelTranslateX, y - sampleModelTranslateY, w, h, b, 491 iArray, dataBuffer); 492 } 493 494 /** 495 * Sets the samples for the specified band and the specified rectangular 496 * area of pixels with a float array of samples. 497 * 498 * @param x 499 * the X coordinate of the area of pixels. 500 * @param y 501 * the Y coordinate of the area of pixels. 502 * @param w 503 * the width of the area of pixels. 504 * @param h 505 * the height of the area of pixels. 506 * @param b 507 * the specified band. 508 * @param fArray 509 * the float array of samples. 510 */ 511 public void setSamples(int x, int y, int w, int h, int b, float fArray[]) { 512 sampleModel.setSamples(x - sampleModelTranslateX, y - sampleModelTranslateY, w, h, b, 513 fArray, dataBuffer); 514 } 515 516 /** 517 * Sets the samples for the specified band and the specified rectangular 518 * area of pixels with a double array of samples. 519 * 520 * @param x 521 * the X coordinate of the area of pixels. 522 * @param y 523 * the Y coordinate of the area of pixels. 524 * @param w 525 * the width of the area of pixels. 526 * @param h 527 * the height of the area of pixels. 528 * @param b 529 * the specified band. 530 * @param dArray 531 * the double array of samples. 532 */ 533 public void setSamples(int x, int y, int w, int h, int b, double dArray[]) { 534 sampleModel.setSamples(x - sampleModelTranslateX, y - sampleModelTranslateY, w, h, b, 535 dArray, dataBuffer); 536 } 537 538 /** 539 * Sets the sample for the specified band and the specified pixel with an 540 * integer sample. 541 * 542 * @param x 543 * the X coordinate of the pixel. 544 * @param y 545 * the Y coordinate of the pixel. 546 * @param b 547 * the specified band. 548 * @param s 549 * the sample to be set. 550 */ 551 public void setSample(int x, int y, int b, int s) { 552 sampleModel.setSample(x - sampleModelTranslateX, y - sampleModelTranslateY, b, s, 553 dataBuffer); 554 } 555 556 /** 557 * Sets the sample for the specified band and the specified pixel with a 558 * float sample. 559 * 560 * @param x 561 * the X coordinate of the pixel. 562 * @param y 563 * the Y coordinate of the pixel. 564 * @param b 565 * the specified band. 566 * @param s 567 * the sample to be set. 568 */ 569 public void setSample(int x, int y, int b, float s) { 570 sampleModel.setSample(x - sampleModelTranslateX, y - sampleModelTranslateY, b, s, 571 dataBuffer); 572 } 573 574 /** 575 * Sets the sample for the specified band and the specified pixel with an 576 * integer sample. 577 * 578 * @param x 579 * the X coordinate of the pixel. 580 * @param y 581 * the Y coordinate of the pixel. 582 * @param b 583 * the specified band. 584 * @param s 585 * the sample to be set. 586 */ 587 public void setSample(int x, int y, int b, double s) { 588 sampleModel.setSample(x - sampleModelTranslateX, y - sampleModelTranslateY, b, s, 589 dataBuffer); 590 } 591 592 } 593