001: /*
002: * $RCSfile: ConstantOpImage.java,v $
003: *
004: * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
005: *
006: * Use is subject to license terms.
007: *
008: * $Revision: 1.1 $
009: * $Date: 2005/02/11 04:56:19 $
010: * $State: Exp $
011: */
012: package com.sun.media.jai.opimage;
013:
014: import java.awt.Point;
015: import java.awt.Rectangle;
016: import java.awt.image.ColorModel;
017: import java.awt.image.DataBuffer;
018: import java.awt.image.Raster;
019: import java.awt.image.RenderedImage;
020: import java.awt.image.Raster;
021: import java.awt.image.WritableRaster;
022: import java.awt.image.SampleModel;
023: import java.awt.image.renderable.ParameterBlock;
024: import javax.media.jai.ImageLayout;
025: import javax.media.jai.OpImage;
026: import javax.media.jai.PlanarImage;
027: import javax.media.jai.RasterFactory;
028: import com.sun.media.jai.util.ImageUtil;
029:
030: /**
031: * An OpImage class to generate an image of constant color.
032: *
033: * <p> ConstantOpImage defines a constant PlanarImage. It is implemented
034: * as a subclass of PatternOpImage with a constant-colored pattern.
035: *
036: */
037: final class ConstantOpImage extends PatternOpImage {
038:
039: /** Creates a Raster defining tile (0, 0) of the master pattern. */
040: private static Raster makePattern(SampleModel sampleModel,
041: Number[] bandValues) {
042: WritableRaster pattern = RasterFactory.createWritableRaster(
043: sampleModel, new Point(0, 0));
044:
045: int width = sampleModel.getWidth();
046: int height = sampleModel.getHeight();
047: int dataType = sampleModel.getTransferType();
048: int numBands = sampleModel.getNumBands();
049:
050: switch (dataType) {
051: case DataBuffer.TYPE_BYTE:
052: int[] bvalues = new int[numBands];
053: for (int i = 0; i < numBands; i++) {
054: bvalues[i] = bandValues[i].intValue()
055: & ImageUtil.BYTE_MASK;
056: }
057:
058: /* Put the first scanline in with setPixels. */
059: for (int x = 0; x < width; x++) {
060: pattern.setPixel(x, 0, bvalues);
061: }
062: break;
063:
064: case DataBuffer.TYPE_USHORT: // USHORT is less than 127
065: case DataBuffer.TYPE_SHORT:
066: case DataBuffer.TYPE_INT:
067: int[] ivalues = new int[numBands];
068: for (int i = 0; i < numBands; i++) {
069: ivalues[i] = bandValues[i].intValue();
070: }
071:
072: /* Put the first scanline in with setPixels. */
073: for (int x = 0; x < width; x++) {
074: pattern.setPixel(x, 0, ivalues);
075: }
076: break;
077:
078: case DataBuffer.TYPE_FLOAT:
079: float[] fvalues = new float[numBands];
080: for (int i = 0; i < numBands; i++) {
081: fvalues[i] = bandValues[i].floatValue();
082: }
083:
084: /* Put the first scanline in with setPixels. */
085: for (int x = 0; x < width; x++) {
086: pattern.setPixel(x, 0, fvalues);
087: }
088: break;
089:
090: case DataBuffer.TYPE_DOUBLE:
091: double[] dvalues = new double[numBands];
092: for (int i = 0; i < numBands; i++) {
093: dvalues[i] = bandValues[i].doubleValue();
094: }
095:
096: /* Put the first scanline in with setPixels. */
097: for (int x = 0; x < width; x++) {
098: pattern.setPixel(x, 0, dvalues);
099: }
100: break;
101: }
102:
103: /* Copy the first line out. */
104: Object odata = pattern.getDataElements(0, 0, width, 1, null);
105:
106: /* Use the first line to copy other rows. */
107: for (int y = 1; y < height; y++) {
108: pattern.setDataElements(0, y, width, 1, odata);
109: }
110:
111: return pattern;
112: }
113:
114: private static SampleModel makeSampleModel(int width, int height,
115: Number[] bandValues) {
116: int numBands = bandValues.length;
117: int dataType;
118:
119: if (bandValues instanceof Byte[]) {
120: dataType = DataBuffer.TYPE_BYTE;
121: } else if (bandValues instanceof Short[]) {
122: /* If all band values are positive, use UShort, else use Short. */
123: dataType = DataBuffer.TYPE_USHORT;
124:
125: Short[] shortValues = (Short[]) bandValues;
126: for (int i = 0; i < numBands; i++) {
127: if (shortValues[i].shortValue() < 0) {
128: dataType = DataBuffer.TYPE_SHORT;
129: break;
130: }
131: }
132: } else if (bandValues instanceof Integer[]) {
133: dataType = DataBuffer.TYPE_INT;
134: } else if (bandValues instanceof Float[]) {
135: dataType = DataBuffer.TYPE_FLOAT;
136: } else if (bandValues instanceof Double[]) {
137: dataType = DataBuffer.TYPE_DOUBLE;
138: } else {
139: dataType = DataBuffer.TYPE_UNDEFINED;
140: }
141:
142: return RasterFactory.createPixelInterleavedSampleModel(
143: dataType, width, height, numBands);
144:
145: }
146:
147: private static Raster patternHelper(int width, int height,
148: Number[] bandValues) {
149: SampleModel sampleModel = makeSampleModel(width, height,
150: bandValues);
151: return makePattern(sampleModel, bandValues);
152: }
153:
154: private static ColorModel colorModelHelper(Number[] bandValues) {
155: SampleModel sampleModel = makeSampleModel(1, 1, bandValues);
156: return PlanarImage.createColorModel(sampleModel);
157: }
158:
159: /**
160: * Constructs a ConstantOpImage from a set of sample values. The
161: * ImageLayout object must contain a complete set of information.
162: *
163: * @param layout an ImageLayout containing image bounds, tile
164: * layout, and SampleModel information.
165: * @param bandValues an array of Numbers representing the values of
166: * each image band.
167: */
168: public ConstantOpImage(int minX, int minY, int width, int height,
169: int tileWidth, int tileHeight, Number[] bandValues) {
170: super(patternHelper(tileWidth, tileHeight, bandValues),
171: colorModelHelper(bandValues), minX, minY, width, height);
172: }
173: }
|