001: /*
002: * $RCSfile: ImageScaler.java,v $
003: *
004: * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * Redistribution and use in source and binary forms, with or without
007: * modification, are permitted provided that the following conditions
008: * are met:
009: *
010: * - Redistribution of source code must retain the above copyright
011: * notice, this list of conditions and the following disclaimer.
012: *
013: * - Redistribution in binary form must reproduce the above copyright
014: * notice, this list of conditions and the following disclaimer in
015: * the documentation and/or other materials provided with the
016: * distribution.
017: *
018: * Neither the name of Sun Microsystems, Inc. or the names of
019: * contributors may be used to endorse or promote products derived
020: * from this software without specific prior written permission.
021: *
022: * This software is provided "AS IS," without a warranty of any
023: * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
024: * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
025: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
026: * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
027: * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
028: * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
029: * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
030: * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
031: * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
032: * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
033: * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
034: * POSSIBILITY OF SUCH DAMAGES.
035: *
036: * You acknowledge that this software is not designed, licensed or
037: * intended for use in the design, construction, operation or
038: * maintenance of any nuclear facility.
039: *
040: * $Revision: 1.4 $
041: * $Date: 2007/02/09 17:20:07 $
042: * $State: Exp $
043: */
044:
045: package com.sun.j3d.loaders.lw3d;
046:
047: import java.awt.Image;
048: import java.awt.image.BufferedImage;
049: import java.awt.image.DataBufferInt;
050:
051: /**
052: * This class resizes an image to be the nearest power of 2 wide and high.
053: * This facility now exists inside of the TextureLoader class, so
054: * ImageScaler should be eliminated at some point.
055: */
056:
057: class ImageScaler {
058:
059: int origW, origH;
060: Image origImage;
061:
062: ImageScaler(Image image, int w, int h) {
063: origImage = image;
064: origW = w;
065: origH = h;
066: }
067:
068: ImageScaler(BufferedImage image) {
069: origImage = image;
070: origW = image.getWidth();
071: origH = image.getHeight();
072: }
073:
074: /**
075: * Utility method to return closes poser of 2 to the given integer
076: */
077: int getClosestPowerOf2(int value) {
078:
079: if (value < 1)
080: return value;
081:
082: int powerValue = 1;
083: for (int i = 1; i < 20; ++i) {
084: powerValue *= 2;
085: if (value < powerValue) {
086: // Found max bound of power, determine which is closest
087: int minBound = powerValue / 2;
088: if ((powerValue - value) > (value - minBound))
089: return minBound;
090: else
091: return powerValue;
092: }
093: }
094: // shouldn't reach here...
095: return 1;
096: }
097:
098: /**
099: * Returns an Image that has been scaled from the original image to
100: * the closest power of 2
101: */
102: Image getScaledImage() {
103: int newWidth = getClosestPowerOf2(origW);
104: int newHeight = getClosestPowerOf2(origH);
105:
106: // If the image is already a power of 2 wide/tall, no need to scale
107: if (newWidth == origW && newHeight == origH)
108: return origImage;
109:
110: Image scaledImage = null;
111:
112: if (origImage instanceof BufferedImage) {
113: // If BufferedImage, then we have some work to do
114: BufferedImage origImageB = (BufferedImage) origImage;
115: scaledImage = new BufferedImage(newWidth, newHeight,
116: origImageB.getType());
117: BufferedImage scaledImageB = (BufferedImage) scaledImage;
118: float widthScale = (float) origW / (float) newWidth;
119: float heightScale = (float) origH / (float) newHeight;
120: int origPixels[] = ((DataBufferInt) origImageB.getRaster()
121: .getDataBuffer()).getData();
122: int newPixels[] = ((DataBufferInt) scaledImageB.getRaster()
123: .getDataBuffer()).getData();
124: for (int row = 0; row < newHeight; ++row) {
125: for (int column = 0; column < newWidth; ++column) {
126: int oldRow = Math.min(origH - 1,
127: (int) ((float) (row) * heightScale + .5f));
128: int oldColumn = Math.min(origW - 1,
129: (int) ((float) column * widthScale + .5f));
130: newPixels[row * newWidth + column] = origPixels[oldRow
131: * origW + oldColumn];
132: }
133: }
134: } else {
135: // If regular Image, then the work is done for us
136: scaledImage = origImage.getScaledInstance(newWidth,
137: newHeight, Image.SCALE_DEFAULT);
138: }
139: return scaledImage;
140: }
141: }
|