1 /* Copyright (C) 2005-2011 Fabio Riccardi */ 2 3 /* 4 * $RCSfile: AddOpImage.java,v $ 5 * 6 * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved. 7 * 8 * Use is subject to license terms. 9 * 10 * $Revision: 1.1 $ 11 * $Date: 2005/02/11 04:56:12 $ 12 * $State: Exp $ 13 */ 14 package com.lightcrafts.jai.opimage; 15 16 import java.awt.Rectangle; 17 import java.awt.image.DataBuffer; 18 import java.awt.image.Raster; 19 import java.awt.image.RenderedImage; 20 import java.awt.image.SampleModel; 21 import java.awt.image.WritableRaster; 22 import com.lightcrafts.mediax.jai.ImageLayout; 23 import com.lightcrafts.mediax.jai.PointOpImage; 24 import com.lightcrafts.mediax.jai.RasterAccessor; 25 import com.lightcrafts.mediax.jai.RasterFormatTag; 26 import com.lightcrafts.mediax.jai.RasterFactory; 27 import java.util.Map; 28 import com.lightcrafts.media.jai.util.ImageUtil; 29 import com.lightcrafts.media.jai.util.JDKWorkarounds; 30 /// import com.lightcrafts.media.jai.test.OpImageTester; 31 32 /** 33 * An <code>OpImage</code> implementing the "Add" operation as 34 * described in <code>com.lightcrafts.mediax.jai.operator.AddDescriptor</code>. 35 * 36 * <p>This <code>OpImage</code> adds the pixel values of two source 37 * images on a per-band basis. In case the two source images have different 38 * number of bands, the number of bands for the destination image is the 39 * smaller band number of the two source images. That is 40 * <code>dstNumBands = Math.min(src1NumBands, src2NumBands)</code>. 41 * In case the two source images have different data types, the data type 42 * for the destination image is the higher data type of the two source 43 * images. 44 * 45 * <p>The value of the pixel (x, y) in the destination image is defined as: 46 * <pre> 47 * for (b = 0; b < numBands; b++) { 48 * dst[y][x][b] = src1[y][x][b] + src2[y][x][b]; 49 * } 50 * </pre> 51 * 52 * <p>If the result of the addition overflows/underflows the 53 * maximum/minimum value supported by the destination image, then it 54 * will be clamped to the maximum/minimum value respectively. The 55 * data type <code>byte</code> is treated as unsigned, with maximum 56 * value as 255 and minimum value as 0. 57 * 58 * @see com.lightcrafts.mediax.jai.operator.AddDescriptor 59 * @see AddCRIF 60 * 61 */ 62 final class MultiplyAddOpImage extends PointOpImage { 63 64 /* Source 1 band increment */ 65 private int s1bd = 1; 66 67 /* Source 2 band increment */ 68 private int s2bd = 1; 69 70 protected double[] constants; 71 72 /** 73 * Constructs an <code>AddOpImage</code>. 74 * 75 * <p>The <code>layout</code> parameter may optionally contains the 76 * tile grid layout, sample model, and/or color model. The image 77 * dimension is determined by the intersection of the bounding boxes 78 * of the two source images. 79 * 80 * <p>The image layout of the first source image, <code>source1</code>, 81 * is used as the fall-back for the image layout of the destination 82 * image. Any layout parameters not specified in the <code>layout</code> 83 * argument are set to the same value as that of <code>source1</code>. 84 * 85 * @param source1 The first source image. 86 * @param source2 The second source image. 87 * @param layout The destination image layout. 88 */ MultiplyAddOpImage(RenderedImage source1, RenderedImage source2, Map config, ImageLayout layout, double[] constants)89 public MultiplyAddOpImage(RenderedImage source1, 90 RenderedImage source2, 91 Map config, 92 ImageLayout layout, 93 double[] constants) { 94 super(source1, source2, layout, config, true); 95 96 // Get the source band counts. 97 int numBands1 = source1.getSampleModel().getNumBands(); 98 int numBands2 = source2.getSampleModel().getNumBands(); 99 100 // Handle the special case of adding a single band image to 101 // each band of a multi-band image. 102 int numBandsDst; 103 if (layout != null && layout.isValid(ImageLayout.SAMPLE_MODEL_MASK)) { 104 SampleModel sm = layout.getSampleModel(null); 105 numBandsDst = sm.getNumBands(); 106 107 // One of the sources must be single-banded and the other must 108 // have at most the number of bands in the SampleModel hint. 109 if (numBandsDst > 1 && 110 ((numBands1 == 1 && numBands2 > 1) || 111 (numBands2 == 1 && numBands1 > 1))) { 112 // Clamp the destination band count to the number of 113 // bands in the multi-band source. 114 numBandsDst = Math.min(Math.max(numBands1, numBands2), 115 numBandsDst); 116 117 // Create a new SampleModel if necessary. 118 if (numBandsDst != sampleModel.getNumBands()) { 119 sampleModel = 120 RasterFactory.createComponentSampleModel(sm, 121 sampleModel.getTransferType(), 122 sampleModel.getWidth(), 123 sampleModel.getHeight(), 124 numBandsDst); 125 126 if (colorModel != null && 127 !JDKWorkarounds.areCompatibleDataModels(sampleModel, 128 colorModel)) { 129 colorModel = 130 ImageUtil.getCompatibleColorModel(sampleModel, 131 config); 132 } 133 } 134 135 if (constants.length < numBandsDst) { 136 this.constants = new double[numBandsDst]; 137 for (int i = 0; i < numBandsDst; i++) { 138 this.constants[i] = constants[0]; 139 } 140 } else { 141 this.constants = constants.clone(); 142 } 143 144 // Set the source band increments. 145 s1bd = numBands1 == 1 ? 0 : 1; 146 s2bd = numBands2 == 1 ? 0 : 1; 147 } 148 } 149 150 // Set flag to permit in-place operation. 151 permitInPlaceOperation(); 152 } 153 154 /** 155 * Adds the pixel values of two source images within a specified 156 * rectangle. 157 * 158 * @param sources Cobbled sources, guaranteed to provide all the 159 * source data necessary for computing the rectangle. 160 * @param dest The tile containing the rectangle to be computed. 161 * @param destRect The rectangle within the tile to be computed. 162 */ computeRect(Raster[] sources, WritableRaster dest, Rectangle destRect)163 protected void computeRect(Raster[] sources, 164 WritableRaster dest, 165 Rectangle destRect) { 166 // Retrieve format tags. 167 RasterFormatTag[] formatTags = getFormatTags(); 168 169 RasterAccessor s1 = new RasterAccessor(sources[0], destRect, 170 formatTags[0], 171 getSourceImage(0).getColorModel()); 172 RasterAccessor s2 = new RasterAccessor(sources[1], destRect, 173 formatTags[1], 174 getSourceImage(1).getColorModel()); 175 RasterAccessor d = new RasterAccessor(dest, destRect, 176 formatTags[2], getColorModel()); 177 178 switch (d.getDataType()) { 179 case DataBuffer.TYPE_BYTE: 180 computeRectByte(s1, s2, d); 181 break; 182 case DataBuffer.TYPE_USHORT: 183 computeRectUShort(s1, s2, d); 184 break; 185 case DataBuffer.TYPE_SHORT: 186 computeRectShort(s1, s2, d); 187 break; 188 case DataBuffer.TYPE_INT: 189 computeRectInt(s1, s2, d); 190 break; 191 case DataBuffer.TYPE_FLOAT: 192 computeRectFloat(s1, s2, d); 193 break; 194 case DataBuffer.TYPE_DOUBLE: 195 computeRectDouble(s1, s2, d); 196 break; 197 } 198 199 if (d.needsClamping()) { 200 d.clampDataArrays(); 201 } 202 d.copyDataToRaster(); 203 } 204 computeRectByte(RasterAccessor src1, RasterAccessor src2, RasterAccessor dst)205 private void computeRectByte(RasterAccessor src1, 206 RasterAccessor src2, 207 RasterAccessor dst) { 208 int s1LineStride = src1.getScanlineStride(); 209 int s1PixelStride = src1.getPixelStride(); 210 int[] s1BandOffsets = src1.getBandOffsets(); 211 byte[][] s1Data = src1.getByteDataArrays(); 212 213 int s2LineStride = src2.getScanlineStride(); 214 int s2PixelStride = src2.getPixelStride(); 215 int[] s2BandOffsets = src2.getBandOffsets(); 216 byte[][] s2Data = src2.getByteDataArrays(); 217 218 int dwidth = dst.getWidth(); 219 int dheight = dst.getHeight(); 220 int bands = dst.getNumBands(); 221 int dLineStride = dst.getScanlineStride(); 222 int dPixelStride = dst.getPixelStride(); 223 int[] dBandOffsets = dst.getBandOffsets(); 224 byte[][] dData = dst.getByteDataArrays(); 225 226 for (int b = 0, s1b = 0, s2b = 0; b < bands; 227 b++, s1b += s1bd, s2b += s2bd) { 228 byte[] s1 = s1Data[s1b]; 229 byte[] s2 = s2Data[s2b]; 230 byte[] d = dData[b]; 231 double c = constants[b]; 232 233 int s1LineOffset = s1BandOffsets[s1b]; 234 int s2LineOffset = s2BandOffsets[s2b]; 235 int dLineOffset = dBandOffsets[b]; 236 237 for (int h = 0; h < dheight; h++) { 238 int s1PixelOffset = s1LineOffset; 239 int s2PixelOffset = s2LineOffset; 240 int dPixelOffset = dLineOffset; 241 242 s1LineOffset += s1LineStride; 243 s2LineOffset += s2LineStride; 244 dLineOffset += dLineStride; 245 246 for (int w = 0; w < dwidth; w++) { 247 d[dPixelOffset] = ImageUtil.clampRoundByte((s1[s1PixelOffset] & 0xFF) + 248 c * (s2[s2PixelOffset] & 0xFF)); 249 250 s1PixelOffset += s1PixelStride; 251 s2PixelOffset += s2PixelStride; 252 dPixelOffset += dPixelStride; 253 } 254 } 255 } 256 } 257 computeRectUShort(RasterAccessor src1, RasterAccessor src2, RasterAccessor dst)258 private void computeRectUShort(RasterAccessor src1, 259 RasterAccessor src2, 260 RasterAccessor dst) { 261 int s1LineStride = src1.getScanlineStride(); 262 int s1PixelStride = src1.getPixelStride(); 263 int[] s1BandOffsets = src1.getBandOffsets(); 264 short[][] s1Data = src1.getShortDataArrays(); 265 266 int s2LineStride = src2.getScanlineStride(); 267 int s2PixelStride = src2.getPixelStride(); 268 int[] s2BandOffsets = src2.getBandOffsets(); 269 short[][] s2Data = src2.getShortDataArrays(); 270 271 int dwidth = dst.getWidth(); 272 int dheight = dst.getHeight(); 273 int bands = dst.getNumBands(); 274 int dLineStride = dst.getScanlineStride(); 275 int dPixelStride = dst.getPixelStride(); 276 int[] dBandOffsets = dst.getBandOffsets(); 277 short[][] dData = dst.getShortDataArrays(); 278 279 for (int b = 0, s1b = 0, s2b = 0; b < bands; 280 b++, s1b += s1bd, s2b += s2bd) { 281 short[] s1 = s1Data[s1b]; 282 short[] s2 = s2Data[s2b]; 283 short[] d = dData[b]; 284 double c = constants[b]; 285 286 int s1LineOffset = s1BandOffsets[s1b]; 287 int s2LineOffset = s2BandOffsets[s2b]; 288 int dLineOffset = dBandOffsets[b]; 289 290 for (int h = 0; h < dheight; h++) { 291 int s1PixelOffset = s1LineOffset; 292 int s2PixelOffset = s2LineOffset; 293 int dPixelOffset = dLineOffset; 294 295 s1LineOffset += s1LineStride; 296 s2LineOffset += s2LineStride; 297 dLineOffset += dLineStride; 298 299 for (int w = 0; w < dwidth; w++) { 300 d[dPixelOffset] = ImageUtil.clampRoundUShort((s1[s1PixelOffset] & 0xFFFF) + 301 c * (s2[s2PixelOffset] & 0xFFFF)); 302 303 s1PixelOffset += s1PixelStride; 304 s2PixelOffset += s2PixelStride; 305 dPixelOffset += dPixelStride; 306 } 307 } 308 } 309 } 310 computeRectShort(RasterAccessor src1, RasterAccessor src2, RasterAccessor dst)311 private void computeRectShort(RasterAccessor src1, 312 RasterAccessor src2, 313 RasterAccessor dst) { 314 int s1LineStride = src1.getScanlineStride(); 315 int s1PixelStride = src1.getPixelStride(); 316 int[] s1BandOffsets = src1.getBandOffsets(); 317 short[][] s1Data = src1.getShortDataArrays(); 318 319 int s2LineStride = src2.getScanlineStride(); 320 int s2PixelStride = src2.getPixelStride(); 321 int[] s2BandOffsets = src2.getBandOffsets(); 322 short[][] s2Data = src2.getShortDataArrays(); 323 324 int dwidth = dst.getWidth(); 325 int dheight = dst.getHeight(); 326 int bands = dst.getNumBands(); 327 int dLineStride = dst.getScanlineStride(); 328 int dPixelStride = dst.getPixelStride(); 329 int[] dBandOffsets = dst.getBandOffsets(); 330 short[][] dData = dst.getShortDataArrays(); 331 332 for (int b = 0, s1b = 0, s2b = 0; b < bands; 333 b++, s1b += s1bd, s2b += s2bd) { 334 short[] s1 = s1Data[s1b]; 335 short[] s2 = s2Data[s2b]; 336 short[] d = dData[b]; 337 double c = constants[b]; 338 339 int s1LineOffset = s1BandOffsets[s1b]; 340 int s2LineOffset = s2BandOffsets[s2b]; 341 int dLineOffset = dBandOffsets[b]; 342 343 for (int h = 0; h < dheight; h++) { 344 int s1PixelOffset = s1LineOffset; 345 int s2PixelOffset = s2LineOffset; 346 int dPixelOffset = dLineOffset; 347 348 s1LineOffset += s1LineStride; 349 s2LineOffset += s2LineStride; 350 dLineOffset += dLineStride; 351 352 for (int w = 0; w < dwidth; w++) { 353 d[dPixelOffset] = ImageUtil.clampRoundShort(s1[s1PixelOffset] + c * s2[s2PixelOffset]); 354 355 s1PixelOffset += s1PixelStride; 356 s2PixelOffset += s2PixelStride; 357 dPixelOffset += dPixelStride; 358 } 359 } 360 } 361 } 362 computeRectInt(RasterAccessor src1, RasterAccessor src2, RasterAccessor dst)363 private void computeRectInt(RasterAccessor src1, 364 RasterAccessor src2, 365 RasterAccessor dst) { 366 int s1LineStride = src1.getScanlineStride(); 367 int s1PixelStride = src1.getPixelStride(); 368 int[] s1BandOffsets = src1.getBandOffsets(); 369 int[][] s1Data = src1.getIntDataArrays(); 370 371 int s2LineStride = src2.getScanlineStride(); 372 int s2PixelStride = src2.getPixelStride(); 373 int[] s2BandOffsets = src2.getBandOffsets(); 374 int[][] s2Data = src2.getIntDataArrays(); 375 376 int dwidth = dst.getWidth(); 377 int dheight = dst.getHeight(); 378 int bands = dst.getNumBands(); 379 int dLineStride = dst.getScanlineStride(); 380 int dPixelStride = dst.getPixelStride(); 381 int[] dBandOffsets = dst.getBandOffsets(); 382 int[][] dData = dst.getIntDataArrays(); 383 384 /* 385 * The destination data type may be any of the integral data types. 386 * The "clamp" function must clamp to the appropriate range for 387 * that data type. 388 */ 389 switch (sampleModel.getTransferType()) { 390 case DataBuffer.TYPE_BYTE: 391 for (int b = 0, s1b = 0, s2b = 0; b < bands; 392 b++, s1b += s1bd, s2b += s2bd) { 393 int[] s1 = s1Data[s1b]; 394 int[] s2 = s2Data[s2b]; 395 int[] d = dData[b]; 396 double c = constants[b]; 397 398 int s1LineOffset = s1BandOffsets[s1b]; 399 int s2LineOffset = s2BandOffsets[s2b]; 400 int dLineOffset = dBandOffsets[b]; 401 402 for (int h = 0; h < dheight; h++) { 403 int s1PixelOffset = s1LineOffset; 404 int s2PixelOffset = s2LineOffset; 405 int dPixelOffset = dLineOffset; 406 407 s1LineOffset += s1LineStride; 408 s2LineOffset += s2LineStride; 409 dLineOffset += dLineStride; 410 411 for (int w = 0; w < dwidth; w++) { 412 d[dPixelOffset] = ImageUtil.clampRoundByte((s1[s1PixelOffset] & 0xFF) + 413 c * (s2[s2PixelOffset] & 0xFF)); 414 415 s1PixelOffset += s1PixelStride; 416 s2PixelOffset += s2PixelStride; 417 dPixelOffset += dPixelStride; 418 } 419 } 420 } 421 break; 422 423 case DataBuffer.TYPE_USHORT: 424 for (int b = 0, s1b = 0, s2b = 0; b < bands; 425 b++, s1b += s1bd, s2b += s2bd) { 426 int[] s1 = s1Data[s1b]; 427 int[] s2 = s2Data[s2b]; 428 int[] d = dData[b]; 429 double c = constants[b]; 430 431 int s1LineOffset = s1BandOffsets[s1b]; 432 int s2LineOffset = s2BandOffsets[s2b]; 433 int dLineOffset = dBandOffsets[b]; 434 435 for (int h = 0; h < dheight; h++) { 436 int s1PixelOffset = s1LineOffset; 437 int s2PixelOffset = s2LineOffset; 438 int dPixelOffset = dLineOffset; 439 440 s1LineOffset += s1LineStride; 441 s2LineOffset += s2LineStride; 442 dLineOffset += dLineStride; 443 444 for (int w = 0; w < dwidth; w++) { 445 d[dPixelOffset] = ImageUtil.clampRoundUShort((s1[s1PixelOffset] & 0xFFFF) + 446 c * (s2[s2PixelOffset] & 0xFFFF)); 447 448 s1PixelOffset += s1PixelStride; 449 s2PixelOffset += s2PixelStride; 450 dPixelOffset += dPixelStride; 451 } 452 } 453 } 454 break; 455 456 case DataBuffer.TYPE_SHORT: 457 for (int b = 0, s1b = 0, s2b = 0; b < bands; 458 b++, s1b += s1bd, s2b += s2bd) { 459 int[] s1 = s1Data[s1b]; 460 int[] s2 = s2Data[s2b]; 461 int[] d = dData[b]; 462 double c = constants[b]; 463 464 int s1LineOffset = s1BandOffsets[s1b]; 465 int s2LineOffset = s2BandOffsets[s2b]; 466 int dLineOffset = dBandOffsets[b]; 467 468 for (int h = 0; h < dheight; h++) { 469 int s1PixelOffset = s1LineOffset; 470 int s2PixelOffset = s2LineOffset; 471 int dPixelOffset = dLineOffset; 472 473 s1LineOffset += s1LineStride; 474 s2LineOffset += s2LineStride; 475 dLineOffset += dLineStride; 476 477 for (int w = 0; w < dwidth; w++) { 478 d[dPixelOffset] = ImageUtil.clampRoundShort(s1[s1PixelOffset] + c * s2[s2PixelOffset]); 479 480 s1PixelOffset += s1PixelStride; 481 s2PixelOffset += s2PixelStride; 482 dPixelOffset += dPixelStride; 483 } 484 } 485 } 486 break; 487 488 case DataBuffer.TYPE_INT: 489 for (int b = 0, s1b = 0, s2b = 0; b < bands; 490 b++, s1b += s1bd, s2b += s2bd) { 491 int[] s1 = s1Data[s1b]; 492 int[] s2 = s2Data[s2b]; 493 int[] d = dData[b]; 494 double c = constants[b]; 495 496 int s1LineOffset = s1BandOffsets[s1b]; 497 int s2LineOffset = s2BandOffsets[s2b]; 498 int dLineOffset = dBandOffsets[b]; 499 500 for (int h = 0; h < dheight; h++) { 501 int s1PixelOffset = s1LineOffset; 502 int s2PixelOffset = s2LineOffset; 503 int dPixelOffset = dLineOffset; 504 505 s1LineOffset += s1LineStride; 506 s2LineOffset += s2LineStride; 507 dLineOffset += dLineStride; 508 509 for (int w = 0; w < dwidth; w++) { 510 d[dPixelOffset] = ImageUtil.clampRoundInt(s1[s1PixelOffset] + c * s2[s2PixelOffset]); 511 512 s1PixelOffset += s1PixelStride; 513 s2PixelOffset += s2PixelStride; 514 dPixelOffset += dPixelStride; 515 } 516 } 517 } 518 break; 519 } 520 } 521 computeRectFloat(RasterAccessor src1, RasterAccessor src2, RasterAccessor dst)522 private void computeRectFloat(RasterAccessor src1, 523 RasterAccessor src2, 524 RasterAccessor dst) { 525 int s1LineStride = src1.getScanlineStride(); 526 int s1PixelStride = src1.getPixelStride(); 527 int[] s1BandOffsets = src1.getBandOffsets(); 528 float[][] s1Data = src1.getFloatDataArrays(); 529 530 int s2LineStride = src2.getScanlineStride(); 531 int s2PixelStride = src2.getPixelStride(); 532 int[] s2BandOffsets = src2.getBandOffsets(); 533 float[][] s2Data = src2.getFloatDataArrays(); 534 535 int dwidth = dst.getWidth(); 536 int dheight = dst.getHeight(); 537 int bands = dst.getNumBands(); 538 int dLineStride = dst.getScanlineStride(); 539 int dPixelStride = dst.getPixelStride(); 540 int[] dBandOffsets = dst.getBandOffsets(); 541 float[][] dData = dst.getFloatDataArrays(); 542 543 for (int b = 0, s1b = 0, s2b = 0; b < bands; 544 b++, s1b += s1bd, s2b += s2bd) { 545 float[] s1 = s1Data[s1b]; 546 float[] s2 = s2Data[s2b]; 547 float[] d = dData[b]; 548 float c = (float) constants[b]; 549 550 int s1LineOffset = s1BandOffsets[s1b]; 551 int s2LineOffset = s2BandOffsets[s2b]; 552 int dLineOffset = dBandOffsets[b]; 553 554 for (int h = 0; h < dheight; h++) { 555 int s1PixelOffset = s1LineOffset; 556 int s2PixelOffset = s2LineOffset; 557 int dPixelOffset = dLineOffset; 558 559 s1LineOffset += s1LineStride; 560 s2LineOffset += s2LineStride; 561 dLineOffset += dLineStride; 562 563 for (int w = 0; w < dwidth; w++) { 564 d[dPixelOffset] = s1[s1PixelOffset] + c * s2[s2PixelOffset]; 565 566 s1PixelOffset += s1PixelStride; 567 s2PixelOffset += s2PixelStride; 568 dPixelOffset += dPixelStride; 569 } 570 } 571 } 572 } 573 computeRectDouble(RasterAccessor src1, RasterAccessor src2, RasterAccessor dst)574 private void computeRectDouble(RasterAccessor src1, 575 RasterAccessor src2, 576 RasterAccessor dst) { 577 int s1LineStride = src1.getScanlineStride(); 578 int s1PixelStride = src1.getPixelStride(); 579 int[] s1BandOffsets = src1.getBandOffsets(); 580 double[][] s1Data = src1.getDoubleDataArrays(); 581 582 int s2LineStride = src2.getScanlineStride(); 583 int s2PixelStride = src2.getPixelStride(); 584 int[] s2BandOffsets = src2.getBandOffsets(); 585 double[][] s2Data = src2.getDoubleDataArrays(); 586 587 int dwidth = dst.getWidth(); 588 int dheight = dst.getHeight(); 589 int bands = dst.getNumBands(); 590 int dLineStride = dst.getScanlineStride(); 591 int dPixelStride = dst.getPixelStride(); 592 int[] dBandOffsets = dst.getBandOffsets(); 593 double[][] dData = dst.getDoubleDataArrays(); 594 595 for (int b = 0, s1b = 0, s2b = 0; b < bands; 596 b++, s1b += s1bd, s2b += s2bd) { 597 double[] s1 = s1Data[s1b]; 598 double[] s2 = s2Data[s2b]; 599 double[] d = dData[b]; 600 double c = constants[b]; 601 602 int s1LineOffset = s1BandOffsets[s1b]; 603 int s2LineOffset = s2BandOffsets[s2b]; 604 int dLineOffset = dBandOffsets[b]; 605 606 for (int h = 0; h < dheight; h++) { 607 int s1PixelOffset = s1LineOffset; 608 int s2PixelOffset = s2LineOffset; 609 int dPixelOffset = dLineOffset; 610 611 s1LineOffset += s1LineStride; 612 s2LineOffset += s2LineStride; 613 dLineOffset += dLineStride; 614 615 for (int w = 0; w < dwidth; w++) { 616 d[dPixelOffset] = s1[s1PixelOffset] + c * s2[s2PixelOffset]; 617 618 s1PixelOffset += s1PixelStride; 619 s2PixelOffset += s2PixelStride; 620 dPixelOffset += dPixelStride; 621 } 622 } 623 } 624 } 625 626 // public static void main(String args[]) { 627 // System.out.println("AddOpImage Test"); 628 // ImageLayout layout; 629 // OpImage src1, src2, dst; 630 // Rectangle rect = new Rectangle(0, 0, 5, 5); 631 632 // System.out.println("1. PixelInterleaved byte 3-band"); 633 // layout = OpImageTester.createImageLayout( 634 // 0, 0, 800, 800, 0, 0, 200, 200, DataBuffer.TYPE_BYTE, 3, false); 635 // src1 = OpImageTester.createRandomOpImage(layout); 636 // src2 = OpImageTester.createRandomOpImage(layout); 637 // dst = new AddOpImage(src1, src2, null, null); 638 // OpImageTester.testOpImage(dst, rect); 639 // OpImageTester.timeOpImage(dst, 10); 640 641 // System.out.println("2. Banded byte 3-band"); 642 // layout = OpImageTester.createImageLayout( 643 // 0, 0, 800, 800, 0, 0, 200, 200, DataBuffer.TYPE_BYTE, 3, true); 644 // src1 = OpImageTester.createRandomOpImage(layout); 645 // src2 = OpImageTester.createRandomOpImage(layout); 646 // dst = new AddOpImage(src1, src2, null, null); 647 // OpImageTester.testOpImage(dst, rect); 648 // OpImageTester.timeOpImage(dst, 10); 649 650 // System.out.println("3. PixelInterleaved int 3-band"); 651 // layout = OpImageTester.createImageLayout( 652 // 0, 0, 512, 512, 0, 0, 200, 200, DataBuffer.TYPE_INT, 3, false); 653 // src1 = OpImageTester.createRandomOpImage(layout); 654 // src2 = OpImageTester.createRandomOpImage(layout); 655 // dst = new AddOpImage(src1, src2, null, null); 656 // OpImageTester.testOpImage(dst, rect); 657 // OpImageTester.timeOpImage(dst, 10); 658 659 // System.out.println("4. Banded int 3-band"); 660 // layout = OpImageTester.createImageLayout( 661 // 0, 0, 512, 512, 0, 0, 200, 200, DataBuffer.TYPE_INT, 3, true); 662 // src1 = OpImageTester.createRandomOpImage(layout); 663 // src2 = OpImageTester.createRandomOpImage(layout); 664 // dst = new AddOpImage(src1, src2, null, null); 665 // OpImageTester.testOpImage(dst, rect); 666 // OpImageTester.timeOpImage(dst, 10); 667 668 // System.out.println("5. PixelInterleaved float 3-band"); 669 // layout = OpImageTester.createImageLayout( 670 // 0, 0, 512, 512, 0, 0, 200, 200, DataBuffer.TYPE_FLOAT, 3, false); 671 // src1 = OpImageTester.createRandomOpImage(layout); 672 // src2 = OpImageTester.createRandomOpImage(layout); 673 // dst = new AddOpImage(src1, src2, null, null); 674 // OpImageTester.testOpImage(dst, rect); 675 // OpImageTester.timeOpImage(dst, 10); 676 677 // System.out.println("6. Banded float 3-band"); 678 // layout = OpImageTester.createImageLayout( 679 // 0, 0, 512, 512, 0, 0, 200, 200, DataBuffer.TYPE_FLOAT, 3, true); 680 // src1 = OpImageTester.createRandomOpImage(layout); 681 // src2 = OpImageTester.createRandomOpImage(layout); 682 // dst = new AddOpImage(src1, src2, null, null); 683 // OpImageTester.testOpImage(dst, rect); 684 // OpImageTester.timeOpImage(dst, 10); 685 686 // System.out.println("7. PixelInterleaved double 3-band"); 687 // layout = OpImageTester.createImageLayout( 688 // 0, 0, 512, 512, 0, 0, 200, 200, DataBuffer.TYPE_DOUBLE, 3, false); 689 // src1 = OpImageTester.createRandomOpImage(layout); 690 // src2 = OpImageTester.createRandomOpImage(layout); 691 // dst = new AddOpImage(src1, src2, null, null); 692 // OpImageTester.testOpImage(dst, rect); 693 // OpImageTester.timeOpImage(dst, 10); 694 695 // System.out.println("8. Banded double 3-band"); 696 // layout = OpImageTester.createImageLayout( 697 // 0, 0, 512, 512, 0, 0, 200, 200, DataBuffer.TYPE_DOUBLE, 3, true); 698 // src1 = OpImageTester.createRandomOpImage(layout); 699 // src2 = OpImageTester.createRandomOpImage(layout); 700 // dst = new AddOpImage(src1, src2, null, null); 701 // OpImageTester.testOpImage(dst, rect); 702 // OpImageTester.timeOpImage(dst, 10); 703 // } 704 } 705