1 7 8 package java.awt.image; 9 10 import java.awt.color.ColorSpace ; 11 import java.awt.geom.Rectangle2D ; 12 import java.awt.Rectangle ; 13 import java.awt.geom.Point2D ; 14 import java.awt.RenderingHints ; 15 import sun.awt.image.ImagingLib; 16 17 66 public class RescaleOp implements BufferedImageOp , RasterOp { 67 float[] scaleFactors; 68 float[] offsets; 69 int length = 0; 70 RenderingHints hints; 71 72 private int srcNbits; 73 private int dstNbits; 74 75 76 86 public RescaleOp (float[] scaleFactors, float[] offsets, 87 RenderingHints hints) { 88 length = scaleFactors.length; 89 if (length > offsets.length) length = offsets.length; 90 91 this.scaleFactors = new float[length]; 92 this.offsets = new float[length]; 93 for (int i=0; i < length; i++) { 94 this.scaleFactors[i] = scaleFactors[i]; 95 this.offsets[i] = offsets[i]; 96 } 97 this.hints = hints; 98 } 99 100 111 public RescaleOp (float scaleFactor, float offset, RenderingHints hints) { 112 length = 1; 113 this.scaleFactors = new float[1]; 114 this.offsets = new float[1]; 115 this.scaleFactors[0] = scaleFactor; 116 this.offsets[0] = offset; 117 this.hints = hints; 118 } 119 120 128 final public float[] getScaleFactors (float scaleFactors[]) { 129 if (scaleFactors == null) { 130 return (float[]) this.scaleFactors.clone(); 131 } 132 System.arraycopy (this.scaleFactors, 0, scaleFactors, 0, 133 Math.min(this.scaleFactors.length, 134 scaleFactors.length)); 135 return scaleFactors; 136 } 137 138 146 final public float[] getOffsets(float offsets[]) { 147 if (offsets == null) { 148 return (float[]) this.offsets.clone(); 149 } 150 151 System.arraycopy (this.offsets, 0, offsets, 0, 152 Math.min(this.offsets.length, offsets.length)); 153 return offsets; 154 } 155 156 162 final public int getNumFactors() { 163 return length; 164 } 165 166 167 174 private ByteLookupTable createByteLut(float scale[], 175 float off[], 176 int nBands, 177 int nElems) { 178 179 byte[][] lutData = new byte[scale.length][nElems]; 180 181 for (int band=0; band<scale.length; band++) { 182 float bandScale = scale[band]; 183 float bandOff = off[band]; 184 byte[] bandLutData = lutData[band]; 185 for (int i=0; i<nElems; i++) { 186 int val = (int)(i*bandScale + bandOff); 187 if ((val & 0xffffff00) != 0) { 188 if (val < 0) { 189 val = 0; 190 } else { 191 val = 255; 192 } 193 } 194 bandLutData[i] = (byte)val; 195 } 196 197 } 198 199 return new ByteLookupTable (0, lutData); 200 } 201 202 209 private ShortLookupTable createShortLut(float scale[], 210 float off[], 211 int nBands, 212 int nElems) { 213 214 short[][] lutData = new short[scale.length][nElems]; 215 216 for (int band=0; band<scale.length; band++) { 217 float bandScale = scale[band]; 218 float bandOff = off[band]; 219 short[] bandLutData = lutData[band]; 220 for (int i=0; i<nElems; i++) { 221 int val = (int)(i*bandScale + bandOff); 222 if ((val & 0xffff0000) != 0) { 223 if (val < 0) { 224 val = 0; 225 } else { 226 val = 65535; 227 } 228 } 229 bandLutData[i] = (short)val; 230 } 231 } 232 233 return new ShortLookupTable (0, lutData); 234 } 235 236 237 244 private boolean canUseLookup(Raster src, Raster dst) { 245 246 int datatype = src.getDataBuffer().getDataType(); 250 if(datatype != DataBuffer.TYPE_BYTE && 251 datatype != DataBuffer.TYPE_USHORT) { 252 return false; 253 } 254 255 SampleModel dstSM = dst.getSampleModel(); 259 dstNbits = dstSM.getSampleSize(0); 260 261 if (!(dstNbits == 8 || dstNbits == 16)) { 262 return false; 263 } 264 for (int i=1; i<src.getNumBands(); i++) { 265 int bandSize = dstSM.getSampleSize(i); 266 if (bandSize != dstNbits) { 267 return false; 268 } 269 } 270 271 SampleModel srcSM = src.getSampleModel(); 275 srcNbits = srcSM.getSampleSize(0); 276 if (srcNbits > 16) { 277 return false; 278 } 279 for (int i=1; i<src.getNumBands(); i++) { 280 int bandSize = srcSM.getSampleSize(i); 281 if (bandSize != srcNbits) { 282 return false; 283 } 284 } 285 286 return true; 287 } 288 289 309 public final BufferedImage filter (BufferedImage src, BufferedImage dst) { 310 ColorModel srcCM = src.getColorModel(); 311 ColorModel dstCM; 312 int numBands = srcCM.getNumColorComponents(); 313 314 315 if (srcCM instanceof IndexColorModel ) { 316 throw new 317 IllegalArgumentException ("Rescaling cannot be "+ 318 "performed on an indexed image"); 319 } 320 if (length != 1 && length != numBands && 321 length != srcCM.getNumComponents()) 322 { 323 throw new IllegalArgumentException ("Number of scaling constants "+ 324 "does not equal the number of"+ 325 " of color or color/alpha "+ 326 " components"); 327 } 328 329 boolean needToConvert = false; 330 331 if (length > numBands && srcCM.hasAlpha()) { 333 length = numBands+1; 334 } 335 336 int width = src.getWidth(); 337 int height = src.getHeight(); 338 339 if (dst == null) { 340 dst = createCompatibleDestImage(src, null); 341 dstCM = srcCM; 342 } 343 else { 344 if (width != dst.getWidth()) { 345 throw new 346 IllegalArgumentException ("Src width ("+width+ 347 ") not equal to dst width ("+ 348 dst.getWidth()+")"); 349 } 350 if (height != dst.getHeight()) { 351 throw new 352 IllegalArgumentException ("Src height ("+height+ 353 ") not equal to dst height ("+ 354 dst.getHeight()+")"); 355 } 356 357 dstCM = dst.getColorModel(); 358 if(srcCM.getColorSpace().getType() != 359 dstCM.getColorSpace().getType()) { 360 needToConvert = true; 361 dst = createCompatibleDestImage(src, null); 362 } 363 364 } 365 366 BufferedImage origDst = dst; 367 368 if (ImagingLib.filter(this, src, dst) == null) { 372 WritableRaster srcRaster = src.getRaster(); 376 WritableRaster dstRaster = dst.getRaster(); 377 378 if (srcCM.hasAlpha()) { 379 if (numBands-1 == length || length == 1) { 380 int minx = srcRaster.getMinX(); 381 int miny = srcRaster.getMinY(); 382 int[] bands = new int[numBands-1]; 383 for (int i=0; i < numBands-1; i++) { 384 bands[i] = i; 385 } 386 srcRaster = 387 srcRaster.createWritableChild(minx, miny, 388 srcRaster.getWidth(), 389 srcRaster.getHeight(), 390 minx, miny, 391 bands); 392 } 393 } 394 if (dstCM.hasAlpha()) { 395 int dstNumBands = dstRaster.getNumBands(); 396 if (dstNumBands-1 == length || length == 1) { 397 int minx = dstRaster.getMinX(); 398 int miny = dstRaster.getMinY(); 399 int[] bands = new int[numBands-1]; 400 for (int i=0; i < numBands-1; i++) { 401 bands[i] = i; 402 } 403 dstRaster = 404 dstRaster.createWritableChild(minx, miny, 405 dstRaster.getWidth(), 406 dstRaster.getHeight(), 407 minx, miny, 408 bands); 409 } 410 } 411 412 filter(srcRaster, dstRaster); 416 417 } 418 419 if (needToConvert) { 420 ColorConvertOp ccop = new ColorConvertOp (hints); 422 ccop.filter(dst, origDst); 423 } 424 425 return origDst; 426 } 427 428 446 public final WritableRaster filter (Raster src, WritableRaster dst) { 447 int numBands = src.getNumBands(); 448 int width = src.getWidth(); 449 int height = src.getHeight(); 450 int[] srcPix = null; 451 int step = 0; 452 int tidx = 0; 453 454 if (dst == null) { 456 dst = createCompatibleDestRaster(src); 457 } 458 else if (height != dst.getHeight() || width != dst.getWidth()) { 459 throw new 460 IllegalArgumentException ("Width or height of Rasters do not "+ 461 "match"); 462 } 463 else if (numBands != dst.getNumBands()) { 464 throw new IllegalArgumentException ("Number of bands in src " 466 + numBands 467 + " does not equal number of bands in dest " 468 + dst.getNumBands()); 469 } 470 if (length != 1 && length != src.getNumBands()) { 473 throw new IllegalArgumentException ("Number of scaling constants "+ 474 "does not equal the number of"+ 475 " of bands in the src raster"); 476 } 477 478 479 if (ImagingLib.filter(this, src, dst) != null) { 483 return dst; 484 } 485 486 if (canUseLookup(src, dst)) { 491 int srcNgray = (1 << srcNbits); 492 int dstNgray = (1 << dstNbits); 493 494 if (dstNgray == 256) { 495 ByteLookupTable lut = createByteLut(scaleFactors, offsets, 496 numBands, srcNgray); 497 LookupOp op = new LookupOp (lut, hints); 498 op.filter(src, dst); 499 } else { 500 ShortLookupTable lut = createShortLut(scaleFactors, offsets, 501 numBands, srcNgray); 502 LookupOp op = new LookupOp (lut, hints); 503 op.filter(src, dst); 504 } 505 } else { 506 if (length > 1) { 510 step = 1; 511 } 512 513 int sminX = src.getMinX(); 514 int sY = src.getMinY(); 515 int dminX = dst.getMinX(); 516 int dY = dst.getMinY(); 517 int sX; 518 int dX; 519 520 int nbits; 526 int dstMax[] = new int[numBands]; 527 int dstMask[] = new int[numBands]; 528 SampleModel dstSM = dst.getSampleModel(); 529 for (int z=0; z<numBands; z++) { 530 nbits = dstSM.getSampleSize(z); 531 dstMax[z] = (1 << nbits) - 1; 532 dstMask[z] = ~(dstMax[z]); 533 } 534 535 int val; 536 for (int y=0; y < height; y++, sY++, dY++) { 537 dX = dminX; 538 sX = sminX; 539 for (int x = 0; x < width; x++, sX++, dX++) { 540 srcPix = src.getPixel(sX, sY, srcPix); 542 tidx = 0; 543 for (int z=0; z<numBands; z++, tidx += step) { 544 val = (int)(srcPix[z]*scaleFactors[tidx] 545 + offsets[tidx]); 546 if ((val & dstMask[z]) != 0) { 548 if (val < 0) { 549 val = 0; 550 } else { 551 val = dstMax[z]; 552 } 553 } 554 srcPix[z] = val; 555 556 } 557 558 dst.setPixel(dX, dY, srcPix); 560 } 561 } 562 } 563 return dst; 564 } 565 566 571 public final Rectangle2D getBounds2D (BufferedImage src) { 572 return getBounds2D(src.getRaster()); 573 } 574 575 582 public final Rectangle2D getBounds2D (Raster src) { 583 return src.getBounds(); 584 } 585 586 594 public BufferedImage createCompatibleDestImage (BufferedImage src, 595 ColorModel destCM) { 596 BufferedImage image; 597 if (destCM == null) { 598 ColorModel cm = src.getColorModel(); 599 image = new BufferedImage (cm, 600 src.getRaster().createCompatibleWritableRaster(), 601 cm.isAlphaPremultiplied(), 602 null); 603 } 604 else { 605 int w = src.getWidth(); 606 int h = src.getHeight(); 607 image = new BufferedImage (destCM, 608 destCM.createCompatibleWritableRaster(w, h), 609 destCM.isAlphaPremultiplied(), null); 610 } 611 612 return image; 613 } 614 615 621 public WritableRaster createCompatibleDestRaster (Raster src) { 622 return src.createCompatibleWritableRaster(src.getWidth(), src.getHeight()); 623 } 624 625 634 public final Point2D getPoint2D (Point2D srcPt, Point2D dstPt) { 635 if (dstPt == null) { 636 dstPt = new Point2D.Float (); 637 } 638 dstPt.setLocation(srcPt.getX(), srcPt.getY()); 639 return dstPt; 640 } 641 642 646 public final RenderingHints getRenderingHints() { 647 return hints; 648 } 649 } 650 | Popular Tags |