0001: /*
0002: * $RCSfile: RasterFactory.java,v $
0003: *
0004: * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
0005: *
0006: * Use is subject to license terms.
0007: *
0008: * $Revision: 1.2 $
0009: * $Date: 2006/02/28 00:16:11 $
0010: * $State: Exp $
0011: */
0012: package javax.media.jai;
0013:
0014: import java.awt.Point;
0015: import java.awt.Rectangle;
0016: import java.awt.Transparency;
0017: import java.awt.color.ColorSpace;
0018: import java.awt.image.ComponentColorModel;
0019: import java.awt.image.ComponentSampleModel;
0020: import java.awt.image.DataBuffer;
0021: import java.awt.image.DataBufferByte;
0022: import java.awt.image.DataBufferShort;
0023: import java.awt.image.DataBufferInt;
0024: import java.awt.image.DataBufferUShort;
0025: import java.awt.image.BandedSampleModel;
0026: import java.awt.image.PixelInterleavedSampleModel;
0027: import java.awt.image.Raster;
0028: import java.awt.image.RasterFormatException;
0029: import java.awt.image.SampleModel;
0030: import java.awt.image.WritableRaster;
0031: import com.sun.media.jai.util.DataBufferUtils;
0032:
0033: /**
0034: * A convenience class for the construction of various types of
0035: * <code>WritableRaster</code> and <code>SampleModel</code> objects.
0036: *
0037: * <p> This class provides the capability of creating
0038: * <code>Raster</code>s with the enumerated data types in the
0039: * java.awt.image.DataBuffer.
0040: *
0041: * <p> In some cases, instances of
0042: * <code>ComponentSampleModelJAI</code>, a subclass of
0043: * <code>java.awt.image.ComponentSampleModel</code> are instantiated
0044: * instead of <code>java.awt.image.BandedSampleModel</code> in order
0045: * to work around bugs in the current release of the Java 2 SDK.
0046: */
0047: public class RasterFactory {
0048:
0049: /**
0050: * Creates a <code>WritableRaster</code> based on a
0051: * <code>PixelInterleavedSampleModel</code> with the specified
0052: * data type, width, height, and number of bands.
0053: *
0054: * <p> The upper left corner of the <code>WritableRaster</code> is
0055: * given by the <code>location</code> argument. If
0056: * <code>location</code> is <code>null</code>, (0, 0) will be
0057: * used. The <code>dataType</code> parameter should be one of the
0058: * enumerated values defined in the <code>DataBuffer</code> class.
0059: *
0060: * @param dataType The data type of the <code>SampleModel</code>,
0061: * one of <code>DataBuffer.TYPE_BYTE</code>,
0062: * <code>TYPE_USHORT</code>,
0063: * <code>TYPE_SHORT</code>,
0064: * <code>TYPE_INT</code>,
0065: * <code>TYPE_FLOAT</code>, or
0066: * <code>TYPE_DOUBLE</code>.
0067: * @param width The desired width of the <code>WritableRaster</code>.
0068: * @param height The desired height of the <code>WritableRaster</code>.
0069: * @param numBands The desired number of bands.
0070: * @param location A <code>Point</code> indicating the starting
0071: * coordinates of the <code>WritableRaster</code>.
0072: *
0073: * @throws IllegalArgumentException if <code>numbands</code> is
0074: * <code><1</code>.
0075: */
0076: public static WritableRaster createInterleavedRaster(int dataType,
0077: int width, int height, int numBands, Point location) {
0078: if (numBands < 1) {
0079: throw new IllegalArgumentException(JaiI18N
0080: .getString("RasterFactory0"));
0081: }
0082: int[] bandOffsets = new int[numBands];
0083: for (int i = 0; i < numBands; i++) {
0084: bandOffsets[i] = numBands - 1 - i;
0085: }
0086: return createInterleavedRaster(dataType, width, height, width
0087: * numBands, numBands, bandOffsets, location);
0088: }
0089:
0090: /**
0091: * Creates a <code>WritableRaster</code> based on a
0092: * <code>PixelInterleavedSampleModel</code> with the specified
0093: * data type, width, height, scanline stride, pixel stride, and
0094: * band offsets. The number of bands is inferred from
0095: * bandOffsets.length.
0096: *
0097: * <p> The upper left corner of the <code>WritableRaster</code> is
0098: * given by the <code>location</code> argument. If
0099: * <code>location</code> is <code>null</code>, (0, 0) will be
0100: * used. The <code>dataType</code> parameter should be one of the
0101: * enumerated values defined in the <code>DataBuffer</code> class.
0102: *
0103: * @param dataType The data type of the <code>WritableRaster</code>,
0104: * one of the enumerated dataType values in
0105: * java.awt.image.DataBuffer.
0106: * @param width The desired width of the <code>WritableRaster</code>.
0107: * @param height The desired height of the <code>WritableRaster</code>.
0108: * @param scanlineStride The desired scanline stride.
0109: * @param pixelStride The desired pixel stride.
0110: * @param bandOffsets An array of <code>int</code>s indicating the
0111: * relative offsets of the bands within a pixel.
0112: * @param location A <code>Point</code> indicating the starting
0113: * coordinates of the <code>WritableRaster</code>.
0114: *
0115: * @throws IllegalArgumentException if <code>bandOffsets</code> is
0116: * <code>null</code>, <code>dataType</code> is not one of
0117: * the enumerated dataType value of java.awt.image.DataBuffer.
0118: *
0119: * @throws IllegalArgumentException if the number of array elements
0120: * required by the returned <code>WritableRaster</code>
0121: * would exceed <code>Integer.MAX_VALUE</code>.
0122: */
0123: public static WritableRaster createInterleavedRaster(int dataType,
0124: int width, int height, int scanlineStride, int pixelStride,
0125: int bandOffsets[], Point location) {
0126:
0127: if (bandOffsets == null) {
0128: throw new IllegalArgumentException(JaiI18N
0129: .getString("RasterFactory4"));
0130: }
0131:
0132: DataBuffer d;
0133: int bands = bandOffsets.length;
0134:
0135: int maxBandOff = bandOffsets[0];
0136: for (int i = 1; i < bands; i++) {
0137: if (bandOffsets[i] > maxBandOff) {
0138: maxBandOff = bandOffsets[i];
0139: }
0140: }
0141:
0142: long lsize = (long) maxBandOff + (long) scanlineStride
0143: * (height - 1) + (long) pixelStride * (width - 1) + 1L;
0144: if (lsize > (long) Integer.MAX_VALUE) {
0145: throw new IllegalArgumentException(JaiI18N
0146: .getString("RasterFactory16"));
0147: }
0148: int size = (int) lsize;
0149:
0150: switch (dataType) {
0151: case DataBuffer.TYPE_BYTE:
0152: d = new DataBufferByte(size);
0153: break;
0154:
0155: case DataBuffer.TYPE_USHORT:
0156: d = new DataBufferUShort(size);
0157: break;
0158:
0159: case DataBuffer.TYPE_SHORT:
0160: d = new DataBufferShort(size);
0161: break;
0162:
0163: case DataBuffer.TYPE_INT:
0164: d = new DataBufferInt(size);
0165: break;
0166:
0167: case DataBuffer.TYPE_FLOAT:
0168: d = DataBufferUtils.createDataBufferFloat(size);
0169: break;
0170:
0171: case DataBuffer.TYPE_DOUBLE:
0172: d = DataBufferUtils.createDataBufferDouble(size);
0173: break;
0174:
0175: default:
0176: throw new IllegalArgumentException(JaiI18N
0177: .getString("RasterFactory3"));
0178: }
0179:
0180: return createInterleavedRaster(d, width, height,
0181: scanlineStride, pixelStride, bandOffsets, location);
0182: }
0183:
0184: /**
0185: * Creates a <code>WritableRaster</code> based on a
0186: * <code>ComponentSampleModel</code> with the specified data type,
0187: * width, height, and number of bands.
0188: *
0189: * <p> Note that the <code>Raster</code>'s
0190: * <code>SampleModel</code> will be of type
0191: * <code>ComponentSampleModel</code>, not
0192: * <code>BandedSampleModel</code> as might be expected.
0193: *
0194: * <p> The upper left corner of the <code>WritableRaster</code> is
0195: * given by the <code>location</code> argument. If
0196: * <code>location</code> is <code>null</code>, (0, 0) will be
0197: * used. The <code>dataType</code> parameter should be one of the
0198: * enumerated values defined in the <code>DataBuffer</code> class.
0199: *
0200: * @param dataType The data type of the <code>WritableRaster</code>,
0201: * one of the enumerated dataType values in
0202: * java.awt.image.DataBuffer.
0203: * @param width The desired width of the <code>WritableRaster</code>.
0204: * @param height The desired height of the <code>WritableRaster</code>.
0205: * @param bands The desired number of bands.
0206: * @param location A <code>Point</code> indicating the starting
0207: * coordinates of the <code>WritableRaster</code>.
0208: *
0209: * @throws IllegalArgumentException if <code>bands</code> is
0210: * <code><1</code>.
0211: */
0212: public static WritableRaster createBandedRaster(int dataType,
0213: int width, int height, int bands, Point location) {
0214: if (bands < 1) {
0215: throw new IllegalArgumentException(JaiI18N
0216: .getString("RasterFactory0"));
0217: }
0218: int[] bankIndices = new int[bands];
0219: int[] bandOffsets = new int[bands];
0220: for (int i = 0; i < bands; i++) {
0221: bankIndices[i] = i;
0222: bandOffsets[i] = 0;
0223: }
0224:
0225: return createBandedRaster(dataType, width, height, width,
0226: bankIndices, bandOffsets, location);
0227: }
0228:
0229: /**
0230: * Creates a <code>WritableRaster</code> based on a
0231: * <code>ComponentSampleModel</code> with the specified data type,
0232: * width, height, scanline stride, bank indices and band offsets.
0233: * The number of bands is inferred from
0234: * <code>bankIndices.length</code> and
0235: * <code>bandOffsets.length</code>, which must be the same.
0236: *
0237: * <p> Note that the <code>Raster</code>'s
0238: * <code>SampleModel</code> will be of type
0239: * <code>ComponentSampleModel</code>, not
0240: * <code>BandedSampleModel</code> as might be expected.
0241: *
0242: * <p> The upper left corner of the <code>WritableRaster</code> is
0243: * given by the <code>location</code> argument. The
0244: * <code>dataType</code> parameter should be one of the enumerated
0245: * values defined in the <code>DataBuffer</code> class.
0246: *
0247: * @param dataType The data type of the <code>WritableRaster</code>,
0248: * one of the enumerated dataType values in
0249: * java.awt.image.DataBuffer.
0250: * @param width The desired width of the <code>WritableRaster</code>.
0251: * @param height The desired height of the <code>WritableRaster</code>.
0252: * @param scanlineStride The desired scanline stride.
0253: * @param bankIndices An array of <code>int</code>s indicating the
0254: * bank index for each band.
0255: * @param bandOffsets An array of <code>int</code>s indicating the
0256: * relative offsets of the bands within a pixel.
0257: * @param location A <code>Point</code> indicating the starting
0258: * coordinates of the <code>WritableRaster</code>.
0259: *
0260: * @throws IllegalArgumentException if <code>bankIndices</code> is
0261: * <code>null</code>, <code>bandOffsets</code> is
0262: * <code>null</code>, if <code>bandOffsets.length</code>
0263: * is <code>!=</code> <code>bankIndices.length</code>,
0264: * if <code>dataType</code> is not one of the enumerated
0265: * datatypes of java.awt.image.DataBuffer.
0266: */
0267: public static WritableRaster createBandedRaster(int dataType,
0268: int width, int height, int scanlineStride,
0269: int bankIndices[], int bandOffsets[], Point location) {
0270: DataBuffer d;
0271: int bands = bandOffsets.length;
0272:
0273: if (bankIndices == null) {
0274: throw new IllegalArgumentException(JaiI18N
0275: .getString("RasterFactory1"));
0276: }
0277: if (bandOffsets == null) {
0278: throw new IllegalArgumentException(JaiI18N
0279: .getString("RasterFactory4"));
0280: }
0281:
0282: if (bandOffsets.length != bankIndices.length) {
0283: throw new IllegalArgumentException(JaiI18N
0284: .getString("RasterFactory2"));
0285: }
0286:
0287: // Figure out the #banks and the largest band offset
0288: int maxBank = bankIndices[0];
0289: int maxBandOff = bandOffsets[0];
0290: for (int i = 1; i < bands; i++) {
0291: if (bankIndices[i] > maxBank) {
0292: maxBank = bankIndices[i];
0293: }
0294: if (bandOffsets[i] > maxBandOff) {
0295: maxBandOff = bandOffsets[i];
0296: }
0297: }
0298:
0299: int banks = maxBank + 1;
0300: long lsize = (long) maxBandOff + (long) scanlineStride
0301: * (height - 1) + (long) (width - 1) + 1L;
0302: if (lsize > (long) Integer.MAX_VALUE) {
0303: throw new IllegalArgumentException(JaiI18N
0304: .getString("RasterFactory16"));
0305: }
0306: int size = (int) lsize;
0307:
0308: switch (dataType) {
0309: case DataBuffer.TYPE_BYTE:
0310: d = new DataBufferByte(size, banks);
0311: break;
0312:
0313: case DataBuffer.TYPE_USHORT:
0314: d = new DataBufferUShort(size, banks);
0315: break;
0316:
0317: case DataBuffer.TYPE_SHORT:
0318: d = new DataBufferShort(size, banks);
0319: break;
0320:
0321: case DataBuffer.TYPE_INT:
0322: d = new DataBufferInt(size, banks);
0323: break;
0324:
0325: case DataBuffer.TYPE_FLOAT:
0326: d = DataBufferUtils.createDataBufferFloat(size, banks);
0327: break;
0328:
0329: case DataBuffer.TYPE_DOUBLE:
0330: d = DataBufferUtils.createDataBufferDouble(size, banks);
0331: break;
0332:
0333: default:
0334: throw new IllegalArgumentException(JaiI18N
0335: .getString("RasterFactory3"));
0336: }
0337:
0338: return createBandedRaster(d, width, height, scanlineStride,
0339: bankIndices, bandOffsets, location);
0340: }
0341:
0342: /**
0343: * Creates a <code>WritableRaster</code> based on a
0344: * <code>SinglePixelPackedSampleModel</code> with the specified
0345: * data type, width, height, and band masks. The number of bands
0346: * is inferred from <code>bandMasks.length</code>.
0347: *
0348: * <p> The upper left corner of the <code>WritableRaster</code> is
0349: * given by the <code>location</code> argument. If
0350: * <code>location</code> is <code>null</code>, (0, 0) will be
0351: * used. The <code>dataType</code> parameter should be one of the
0352: * enumerated values defined in the <code>DataBuffer</code> class.
0353: *
0354: * @param dataType The data type of the <code>WritableRaster</code>,
0355: * one of <code>DataBuffer.TYPE_BYTE</code>,
0356: * <code>TYPE_USHORT</code> or <code>TYPE_INT</code>.
0357: * @param width The desired width of the <code>WritableRaster</code>.
0358: * @param height The desired height of the <code>WritableRaster</code>.
0359: * @param location A <code>Point</code> indicating the starting
0360: * coordinates of the <code>WritableRaster</code>.
0361: *
0362: * @throws IllegalArgumentException is thrown if
0363: * the <code>dataType</code> is not of either TYPE_BYTE
0364: * or TYPE_USHORT or TYPE_INT.
0365: */
0366: public static WritableRaster createPackedRaster(int dataType,
0367: int width, int height, int bandMasks[], Point location) {
0368: return Raster.createPackedRaster(dataType, width, height,
0369: bandMasks, location);
0370: }
0371:
0372: /**
0373: * Creates a <code>WritableRaster</code> based on a packed
0374: * <code>SampleModel</code> with the specified data type, width,
0375: * height, number of bands, and bits per band. If the number of
0376: * bands is one, the <code>SampleModel</code> will be a
0377: * <code>MultiPixelPackedSampleModel</code>.
0378: *
0379: * <p> If the number of bands is more than one, the
0380: * <code>SampleModel</code> will be a
0381: * <code>SinglePixelPackedSampleModel</code>, with each band
0382: * having <code>bitsPerBand</code> bits. In either case, the
0383: * requirements on <code>dataType</code> and
0384: * <code>bitsPerBand</code> imposed by the corresponding
0385: * <code>SampleModel</code> must be met.
0386: *
0387: * <p> The upper left corner of the <code>WritableRaster</code> is
0388: * given by the <code>location</code> argument. If
0389: * <code>location</code> is <code>null</code>, (0, 0) will be
0390: * used. The <code>dataType</code> parameter should be one of the
0391: * enumerated values defined in the <code>DataBuffer</code> class.
0392: *
0393: * @param dataType The data type of the <code>WritableRaster</code>,
0394: * one of <code>DataBuffer.TYPE_BYTE</code>,
0395: * <code>TYPE_USHORT</code> or <code>TYPE_INT</code>.
0396: * @param width The desired width of the <code>WritableRaster</code>.
0397: * @param height The desired height of the <code>WritableRaster</code>.
0398: * @param numBands The desired number of bands.
0399: * @param bitsPerBand The number of bits per band.
0400: * @param location A <code>Point</code> indicating the starting
0401: * coordinates of the <code>WritableRaster</code>.
0402: *
0403: * @throws IllegalArgumentException is thrown if
0404: * the <code>dataType</code> is not of either TYPE_BYTE
0405: * or TYPE_USHORT or TYPE_INT.
0406: * @throws IllegalArgumentException is thrown if bitsPerBand
0407: * is negative or zero.
0408: */
0409: public static WritableRaster createPackedRaster(int dataType,
0410: int width, int height, int numBands, int bitsPerBand,
0411: Point location) {
0412: if (bitsPerBand <= 0) {
0413: throw new IllegalArgumentException(JaiI18N
0414: .getString("RasterFactory15"));
0415: }
0416:
0417: return Raster.createPackedRaster(dataType, width, height,
0418: numBands, bitsPerBand, location);
0419: }
0420:
0421: /**
0422: * Creates a <code>WritableRaster</code> based on a
0423: * <code>PixelInterleavedSampleModel</code> with the specified
0424: * <code>DataBuffer</code>, width, height, scanline stride, pixel
0425: * stride, and band offsets. The number of bands is inferred from
0426: * <code>bandOffsets.length</code>. The upper left corner of the
0427: * <code>WritableRaster</code> is given by the
0428: * <code>location</code> argument. If <code>location</code> is
0429: * <code>null</code>, (0, 0) will be used.
0430: *
0431: * @param dataBuffer The <code>DataBuffer</code> to be used.
0432: * @param width The desired width of the <code>WritableRaster</code>.
0433: * @param height The desired height of the <code>WritableRaster</code>.
0434: * @param scanlineStride The desired scanline stride.
0435: * @param pixelStride The desired pixel stride.
0436: * @param bandOffsets An array of <code>int</code>s indicating the
0437: * relative offsets of the bands within a pixel.
0438: * @param location A <code>Point</code> indicating the starting
0439: * coordinates of the <code>WritableRaster</code>.
0440: *
0441: * @throws IllegalArgumentException if <code>bandOffsets</code> is
0442: * <code>null</code>, if <code>pixelStride*width</code> is
0443: * <code>></code> <code>scanlineStride</code>,
0444: * if <code>dataType</code>of the DataBuffer is not one
0445: * the enumerated dataType value of java.awt.image.DataBuffer.
0446: */
0447: public static WritableRaster createInterleavedRaster(
0448: DataBuffer dataBuffer, int width, int height,
0449: int scanlineStride, int pixelStride, int bandOffsets[],
0450: Point location) {
0451:
0452: if (bandOffsets == null) {
0453: throw new IllegalArgumentException(JaiI18N
0454: .getString("RasterFactory4"));
0455: }
0456: if (location == null) {
0457: location = new Point(0, 0);
0458: }
0459: int dataType = dataBuffer.getDataType();
0460:
0461: switch (dataType) {
0462: case DataBuffer.TYPE_BYTE:
0463: case DataBuffer.TYPE_USHORT:
0464: PixelInterleavedSampleModel csm = new PixelInterleavedSampleModel(
0465: dataType, width, height, pixelStride,
0466: scanlineStride, bandOffsets);
0467: return Raster.createWritableRaster(csm, dataBuffer,
0468: location);
0469:
0470: case DataBuffer.TYPE_INT:
0471: case DataBuffer.TYPE_SHORT:
0472: case DataBuffer.TYPE_FLOAT:
0473: case DataBuffer.TYPE_DOUBLE:
0474: int minBandOff = bandOffsets[0];
0475: int maxBandOff = bandOffsets[0];
0476: for (int i = 1; i < bandOffsets.length; i++) {
0477: minBandOff = Math.min(minBandOff, bandOffsets[i]);
0478: maxBandOff = Math.max(maxBandOff, bandOffsets[i]);
0479: }
0480: maxBandOff -= minBandOff;
0481: if (maxBandOff > scanlineStride) {
0482: throw new IllegalArgumentException(JaiI18N
0483: .getString("RasterFactory5"));
0484:
0485: }
0486: if (pixelStride * width > scanlineStride) {
0487: throw new IllegalArgumentException(JaiI18N
0488: .getString("RasterFactory6"));
0489: }
0490: if (pixelStride < maxBandOff) {
0491: throw new IllegalArgumentException(JaiI18N
0492: .getString("RasterFactory7"));
0493: }
0494:
0495: SampleModel sm = new ComponentSampleModelJAI(dataType,
0496: width, height, pixelStride, scanlineStride,
0497: bandOffsets);
0498: return Raster
0499: .createWritableRaster(sm, dataBuffer, location);
0500:
0501: default:
0502: throw new IllegalArgumentException(JaiI18N
0503: .getString("RasterFactory3"));
0504: }
0505: }
0506:
0507: /**
0508: * Creates a <code>WritableRaster</code> based on a
0509: * <code>ComponentSampleModel</code> with the specified
0510: * <code>DataBuffer</code>, width, height, scanline stride, bank
0511: * indices, and band offsets. The number of bands is inferred
0512: * from <code>bankIndices.length</code> and
0513: * <code>bandOffsets.length</code>, which must be the same. The
0514: * upper left corner of the <code>WritableRaster</code> is given
0515: * by the <code>location</code> argument. If
0516: * <code>location</code> is <code>null</code>, (0, 0) will be
0517: * used.
0518: *
0519: * <p> Note that the <code>Raster</code>'s
0520: * <code>SampleModel</code> will be of type
0521: * <code>ComponentSampleModel</code>, not
0522: * <code>BandedSampleModel</code> as might be expected.
0523: *
0524: * @param dataBuffer The <code>DataBuffer</code> to be used.
0525: * @param width The desired width of the <code>WritableRaster</code>.
0526: * @param height The desired height of the <code>WritableRaster</code>.
0527: * @param scanlineStride The desired scanline stride.
0528: * @param bankIndices An array of <code>int</code>s indicating the
0529: * bank index for each band.
0530: * @param bandOffsets An array of <code>int</code>s indicating the
0531: * relative offsets of the bands within a pixel.
0532: * @param location A <code>Point</code> indicating the starting
0533: * coordinates of the <code>WritableRaster</code>.
0534: *
0535: * @throws IllegalArgumentException if <code>bankIndices</code> is
0536: * <code>null</code>, if <code>bandOffsets</code> is
0537: * <code>null</code>, if <code>bandOffsets.length</code>
0538: * is <code>!=</code> <code>bankIndices.length</code>,
0539: * if <code>dataType</code> is not one of the enumerated
0540: * datatypes of java.awt.image.DataBuffer.
0541: */
0542: public static WritableRaster createBandedRaster(
0543: DataBuffer dataBuffer, int width, int height,
0544: int scanlineStride, int bankIndices[], int bandOffsets[],
0545: Point location) {
0546: if (location == null) {
0547: location = new Point(0, 0);
0548: }
0549: int dataType = dataBuffer.getDataType();
0550:
0551: if (bankIndices == null) {
0552: throw new IllegalArgumentException(JaiI18N
0553: .getString("RasterFactory1"));
0554: }
0555: if (bandOffsets == null) {
0556: throw new IllegalArgumentException(JaiI18N
0557: .getString("RasterFactory4"));
0558: }
0559:
0560: int bands = bankIndices.length;
0561: if (bandOffsets.length != bands) {
0562: throw new IllegalArgumentException(JaiI18N
0563: .getString("RasterFactory2"));
0564: }
0565:
0566: SampleModel bsm = new ComponentSampleModelJAI(dataType, width,
0567: height, 1, scanlineStride, bankIndices, bandOffsets);
0568:
0569: switch (dataType) {
0570: case DataBuffer.TYPE_BYTE:
0571: case DataBuffer.TYPE_USHORT:
0572: case DataBuffer.TYPE_INT:
0573: case DataBuffer.TYPE_SHORT:
0574: case DataBuffer.TYPE_FLOAT:
0575: case DataBuffer.TYPE_DOUBLE:
0576: return Raster.createWritableRaster(bsm, dataBuffer,
0577: location);
0578:
0579: default:
0580: throw new IllegalArgumentException(JaiI18N
0581: .getString("RasterFactory3"));
0582: }
0583: }
0584:
0585: /**
0586: * Creates a <code>WritableRaster</code> based on a
0587: * <code>SinglePixelPackedSampleModel</code> with the specified
0588: * <code>DataBuffer</code>, width, height, scanline stride, and
0589: * band masks. The number of bands is inferred from
0590: * <code>bandMasks.length</code>. The upper left corner of the
0591: * <code>WritableRaster</code> is given by the
0592: * <code>location</code> argument. If <code>location</code> is
0593: * <code>null</code>, (0, 0) will be used.
0594: *
0595: * @param dataBuffer The <code>DataBuffer</code> to be used.
0596: * @param width The desired width of the <code>WritableRaster</code>.
0597: * @param height The desired height of the <code>WritableRaster</code>.
0598: * @param scanlineStride The desired scanline stride.
0599: * @param bandMasks An array of <code>int</code>s indicating the
0600: * bitmasks for each band within a pixel.
0601: * @param location A <code>Point</code> indicating the starting
0602: * coordinates of the <code>WritableRaster</code>.
0603: *
0604: * @throws IllegalArgumentException is thrown if
0605: * the <code>dataType</code> is not of either TYPE_BYTE
0606: * or TYPE_USHORT or TYPE_INT.
0607: */
0608: public static WritableRaster createPackedRaster(
0609: DataBuffer dataBuffer, int width, int height,
0610: int scanlineStride, int bandMasks[], Point location) {
0611: return Raster.createPackedRaster(dataBuffer, width, height,
0612: scanlineStride, bandMasks, location);
0613: }
0614:
0615: /**
0616: * Creates a <code>WritableRaster</code> based on a
0617: * <code>MultiPixelPackedSampleModel</code> with the specified
0618: * <code>DataBuffer</code>, width, height, and bits per pixel.
0619: * The upper left corner of the <code>WritableRaster</code> is
0620: * given by the <code>location</code> argument. If
0621: * <code>location</code> is <code>null</code>, (0, 0) will be
0622: * used.
0623: *
0624: * @param dataBuffer The <code>DataBuffer</code> to be used.
0625: * @param width The desired width of the <code>WritableRaster</code>.
0626: * @param height The desired height of the <code>WritableRaster</code>.
0627: * @param bitsPerPixel The desired pixel depth.
0628: * @param location A <code>Point</code> indicating the starting
0629: * coordinates of the <code>WritableRaster</code>.
0630: *
0631: * @throws IllegalArgumentException is thrown if
0632: * the <code>dataType</code> of the <code>dataBuffer</code>
0633: * is not of either TYPE_BYTE or TYPE_USHORT or TYPE_INT.
0634: */
0635: public static WritableRaster createPackedRaster(
0636: DataBuffer dataBuffer, int width, int height,
0637: int bitsPerPixel, Point location) {
0638: return Raster.createPackedRaster(dataBuffer, width, height,
0639: bitsPerPixel, location);
0640: }
0641:
0642: /**
0643: * Creates a <code>WritableRaster</code> with the specified
0644: * <code>SampleModel</code> and <code>DataBuffer</code>. The
0645: * upper left corner of the <code>WritableRaster</code> is given
0646: * by the <code>location</code> argument. If
0647: * <code>location</code> is <code>null</code>, (0, 0) will be
0648: * used.
0649: *
0650: * @param sampleModel The <code>SampleModel</code> to be used.
0651: * @param dataBuffer The <code>DataBuffer</code> to be used.
0652: * @param location A <code>Point</code> indicating the starting
0653: * coordinates of the <code>WritableRaster</code>.
0654: */
0655: public static Raster createRaster(SampleModel sampleModel,
0656: DataBuffer dataBuffer, Point location) {
0657: return Raster.createRaster(sampleModel, dataBuffer, location);
0658: }
0659:
0660: /**
0661: * Creates a <code>WritableRaster</code> with the specified
0662: * <code>SampleModel</code>. The upper left corner of the
0663: * <code>WritableRaster</code> is given by the
0664: * <code>location</code> argument. If <code>location</code> is
0665: * <code>null</code>, (0, 0) will be used.
0666: *
0667: * @param sampleModel The <code>SampleModel</code> to use.
0668: * @param location A <code>Point</code> indicating the starting
0669: * coordinates of the <code>WritableRaster</code>.
0670: */
0671: public static WritableRaster createWritableRaster(
0672: SampleModel sampleModel, Point location) {
0673: if (location == null) {
0674: location = new Point(0, 0);
0675: }
0676:
0677: return createWritableRaster(sampleModel, sampleModel
0678: .createDataBuffer(), location);
0679: }
0680:
0681: /**
0682: * Creates a <code>WritableRaster</code> with the specified
0683: * <code>SampleModel</code> and <code>DataBuffer</code>. The
0684: * upper left corner of the <code>WritableRaster</code> is given
0685: * by the <code>location</code> argument. If
0686: * <code>location</code> is <code>null</code>, (0, 0) will be
0687: * used.
0688: *
0689: * @param sampleModel The <code>SampleModel</code> to be used.
0690: * @param dataBuffer The <code>DataBuffer</code> to be used.
0691: * @param location A <code>Point</code> indicating the starting
0692: * coordinates of the <code>WritableRaster</code>.
0693: */
0694: public static WritableRaster createWritableRaster(
0695: SampleModel sampleModel, DataBuffer dataBuffer,
0696: Point location) {
0697: return Raster.createWritableRaster(sampleModel, dataBuffer,
0698: location);
0699: }
0700:
0701: /**
0702: * Returns a new WritableRaster which shares all or part of the
0703: * supplied WritableRaster's DataBuffer. The new WritableRaster will
0704: * possess a reference to the supplied WritableRaster, accessible
0705: * through its getParent() and getWritableParent() methods.
0706: *
0707: * <p> This method provides a workaround for a bug in the
0708: * implementation of WritableRaster.createWritableChild in
0709: * the initial relase of the Java2 platform.
0710: *
0711: * <p> The <code>parentX</code>, <code>parentY</code>,
0712: * <code>width</code> and <code>height</code> parameters form a
0713: * Rectangle in this WritableRaster's coordinate space, indicating
0714: * the area of pixels to be shared. An error will be thrown if
0715: * this Rectangle is not contained with the bounds of the supplied
0716: * WritableRaster.
0717: *
0718: * <p> The new WritableRaster may additionally be translated to a
0719: * different coordinate system for the plane than that used by the supplied
0720: * WritableRaster. The childMinX and childMinY parameters give
0721: * the new (x, y) coordinate of the upper-left pixel of the
0722: * returned WritableRaster; the coordinate (childMinX, childMinY)
0723: * in the new WritableRaster will map to the same pixel as the
0724: * coordinate (parentX, parentY) in the supplied WritableRaster.
0725: *
0726: * <p> The new WritableRaster may be defined to contain only a
0727: * subset of the bands of the supplied WritableRaster, possibly
0728: * reordered, by means of the bandList parameter. If bandList is
0729: * null, it is taken to include all of the bands of the supplied
0730: * WritableRaster in their current order.
0731: *
0732: * <p> To create a new WritableRaster that contains a subregion of
0733: * the supplied WritableRaster, but shares its coordinate system
0734: * and bands, this method should be called with childMinX equal to
0735: * parentX, childMinY equal to parentY, and bandList equal to
0736: * null.
0737: *
0738: * @param raster The parent WritableRaster.
0739: * @param parentX X coordinate of the upper left corner of the shared
0740: * rectangle in this WritableRaster's coordinates.
0741: * @param parentY Y coordinate of the upper left corner of the shared
0742: * rectangle in this WritableRaster's coordinates.
0743: * @param width Width of the shared rectangle starting at
0744: * (<code>parentX</code>, <code>parentY</code>).
0745: * @param height Height of the shared rectangle starting at
0746: * (<code>parentX</code>, <code>parentY</code>).
0747: * @param childMinX X coordinate of the upper left corner of
0748: * the returned WritableRaster.
0749: * @param childMinY Y coordinate of the upper left corner of
0750: * the returned WritableRaster.
0751: * @param bandList Array of band indices, or null to use all bands.
0752: *
0753: * @throws RasterFormatException if the subregion is outside of the
0754: * raster bounds.
0755: */
0756: public static WritableRaster createWritableChild(
0757: WritableRaster raster, int parentX, int parentY, int width,
0758: int height, int childMinX, int childMinY, int bandList[]) {
0759: // Simply forward the call to the equivalent WritableRaster method.
0760: // The WritableRaster bug referred to in the javadoc was 4212434
0761: // and was fixed in Java SE 1.3, which is the minimum version
0762: // required for JAI.
0763: return raster.createWritableChild(parentX, parentY, width,
0764: height, childMinX, childMinY, bandList);
0765: }
0766:
0767: /**
0768: * Creates a banded <code>SampleModel</code> with a given data
0769: * type, width, height, number of bands, bank indices, and band
0770: * offsets.
0771: *
0772: * <p> Note that the returned <code>SampleModel</code> will be of type
0773: * <code>ComponentSampleModel</code>, not
0774: * <code>BandedSampleModel</code> as might be expected. Its
0775: * behavior will be equivalent to that of a
0776: * <code>BandedSampleModel</code>, and in particular its pixel
0777: * stride will always be 1.
0778: *
0779: * @param dataType The data type of the <code>SampleModel</code>,
0780: * one of <code>DataBuffer.TYPE_BYTE</code>,
0781: * <code>TYPE_USHORT</code>,
0782: * <code>TYPE_SHORT</code>,
0783: * <code>TYPE_INT</code>,
0784: * <code>TYPE_FLOAT</code>, or
0785: * <code>TYPE_DOUBLE</code>.
0786: * @param width The desired width of the <code>SampleModel</code>.
0787: * @param height The desired height of the <code>SampleModel</code>.
0788: * @param numBands The desired number of bands.
0789: * @param bankIndices An array of <code>int</code>s indicating the
0790: * bank index for each band.
0791: * @param bandOffsets An array of <code>int</code>s indicating the
0792: * relative offsets of the bands within a pixel.
0793: *
0794: * @throws IllegalArgumentException if <code>numBands</code> is
0795: * <code><1</code>, if <code>bandOffsets.length</code> is
0796: * <code>!=</code> <code>bankIndices.length</code>.
0797: */
0798: public static SampleModel createBandedSampleModel(int dataType,
0799: int width, int height, int numBands, int bankIndices[],
0800: int bandOffsets[]) {
0801: if (numBands < 1) {
0802: throw new IllegalArgumentException(JaiI18N
0803: .getString("RasterFactory0"));
0804: }
0805: if (bankIndices == null) {
0806: bankIndices = new int[numBands];
0807: for (int i = 0; i < numBands; i++) {
0808: bankIndices[i] = i;
0809: }
0810: }
0811: if (bandOffsets == null) {
0812: bandOffsets = new int[numBands];
0813: for (int i = 0; i < numBands; i++) {
0814: bandOffsets[i] = 0;
0815: }
0816: }
0817: if (bandOffsets.length != bankIndices.length) {
0818: throw new IllegalArgumentException(JaiI18N
0819: .getString("RasterFactory2"));
0820: }
0821: return new ComponentSampleModelJAI(dataType, width, height, 1,
0822: width, bankIndices, bandOffsets);
0823: }
0824:
0825: /**
0826: * Creates a banded <code>SampleModel</code> with a given data
0827: * type, width, height, and number of bands. The bank indices and
0828: * band offsets are set to default values.
0829: *
0830: * <p> Note that the returned <code>SampleModel</code> will be of type
0831: * <code>ComponentSampleModel</code>, not
0832: * <code>BandedSampleModel</code> as might be expected. Its
0833: * behavior will be equivalent to that of a
0834: * <code>BandedSampleModel</code>, and in particular its pixel
0835: * stride will always be 1.
0836: *
0837: * @param dataType The data type of the <code>SampleModel</code>,
0838: * one of <code>DataBuffer.TYPE_BYTE</code>,
0839: * <code>TYPE_USHORT</code>,
0840: * <code>TYPE_SHORT</code>,
0841: * <code>TYPE_INT</code>,
0842: * <code>TYPE_FLOAT</code>, or
0843: * <code>TYPE_DOUBLE</code>.
0844: * @param width The desired width of the <code>SampleModel</code>.
0845: * @param height The desired height of the <code>SampleModel</code>.
0846: * @param numBands The desired number of bands.
0847: */
0848: public static SampleModel createBandedSampleModel(int dataType,
0849: int width, int height, int numBands) {
0850: return createBandedSampleModel(dataType, width, height,
0851: numBands, null, null);
0852: }
0853:
0854: /**
0855: * Creates a pixel interleaved <code>SampleModel</code> with a
0856: * given data type, width, height, pixel and scanline strides, and
0857: * band offsets.
0858: *
0859: * @param dataType The data type of the <code>SampleModel</code>,
0860: * one of <code>DataBuffer.TYPE_BYTE</code>,
0861: * <code>TYPE_USHORT</code>,
0862: * <code>TYPE_SHORT</code>,
0863: * <code>TYPE_INT</code>,
0864: * <code>TYPE_FLOAT</code>, or
0865: * <code>TYPE_DOUBLE</code>.
0866: * @param width The desired width of the <code>SampleModel</code>.
0867: * @param height The desired height of the <code>SampleModel</code>.
0868: * @param pixelStride The desired pixel stride.
0869: * @param scanlineStride The desired scanline stride.
0870: * @param bandOffsets An array of <code>int</code>s indicating the
0871: * relative offsets of the bands within a pixel.
0872: *
0873: * @throws IllegalArgumentException if <code>bandOffsets</code> is
0874: * <code>null</code>, if the <code>pixelStride*width</code>
0875: * is <code>></code> than <code>scanlineStride</code>,
0876: * if the <code>dataType</code> is not one of the above
0877: * mentioned datatypes.
0878: */
0879: public static SampleModel createPixelInterleavedSampleModel(
0880: int dataType, int width, int height, int pixelStride,
0881: int scanlineStride, int bandOffsets[]) {
0882: if (bandOffsets == null) {
0883: throw new IllegalArgumentException(JaiI18N
0884: .getString("RasterFactory4"));
0885: }
0886: int minBandOff = bandOffsets[0];
0887: int maxBandOff = bandOffsets[0];
0888: for (int i = 1; i < bandOffsets.length; i++) {
0889: minBandOff = Math.min(minBandOff, bandOffsets[i]);
0890: maxBandOff = Math.max(maxBandOff, bandOffsets[i]);
0891: }
0892: maxBandOff -= minBandOff;
0893: if (maxBandOff > scanlineStride) {
0894: throw new IllegalArgumentException(JaiI18N
0895: .getString("RasterFactory5"));
0896:
0897: }
0898: if (pixelStride * width > scanlineStride) {
0899: throw new IllegalArgumentException(JaiI18N
0900: .getString("RasterFactory6"));
0901: }
0902: if (pixelStride < maxBandOff) {
0903: throw new IllegalArgumentException(JaiI18N
0904: .getString("RasterFactory7"));
0905: }
0906:
0907: switch (dataType) {
0908: case DataBuffer.TYPE_BYTE:
0909: case DataBuffer.TYPE_USHORT:
0910: return new PixelInterleavedSampleModel(dataType, width,
0911: height, pixelStride, scanlineStride, bandOffsets);
0912: case DataBuffer.TYPE_INT:
0913: case DataBuffer.TYPE_SHORT:
0914: case DataBuffer.TYPE_FLOAT:
0915: case DataBuffer.TYPE_DOUBLE:
0916: return new ComponentSampleModelJAI(dataType, width, height,
0917: pixelStride, scanlineStride, bandOffsets);
0918: default:
0919: throw new IllegalArgumentException(JaiI18N
0920: .getString("RasterFactory3"));
0921: }
0922: }
0923:
0924: /**
0925: * Creates a pixel interleaved <code>SampleModel</code> with a
0926: * given data type, width, height, and number of bands. The pixel
0927: * stride, scanline stride, and band offsets are set to default
0928: * values.
0929: *
0930: * @param dataType The data type of the <code>SampleModel</code>,
0931: * one of <code>DataBuffer.TYPE_BYTE</code>,
0932: * <code>TYPE_USHORT</code>,
0933: * <code>TYPE_SHORT</code>,
0934: * <code>TYPE_INT</code>,
0935: * <code>TYPE_FLOAT</code>, or
0936: * <code>TYPE_DOUBLE</code>.
0937: * @param width The desired width of the <code>SampleModel</code>.
0938: * @param height The desired height of the <code>SampleModel</code>.
0939: * @param numBands The desired number of bands.
0940: *
0941: * @throws IllegalArgumentException if <code>numBands</code> is
0942: * <code><1</code>.
0943: */
0944: public static SampleModel createPixelInterleavedSampleModel(
0945: int dataType, int width, int height, int numBands) {
0946: if (numBands < 1) {
0947: throw new IllegalArgumentException(JaiI18N
0948: .getString("RasterFactory0"));
0949: }
0950: int[] bandOffsets = new int[numBands];
0951: for (int i = 0; i < numBands; i++) {
0952: bandOffsets[i] = numBands - 1 - i;
0953: }
0954:
0955: return createPixelInterleavedSampleModel(dataType, width,
0956: height, numBands, numBands * width, bandOffsets);
0957: }
0958:
0959: /**
0960: * Creates a component <code>SampleModel</code> with a given data
0961: * type, width, height, and number of bands that is "compatible"
0962: * with a given SampleModel.
0963: *
0964: * @param sm The <code>SampleModel</code> to be compatible with.
0965: * @param dataType The data type of the <code>SampleModel</code>,
0966: * one of <code>DataBuffer.TYPE_BYTE</code>,
0967: * <code>TYPE_USHORT</code>,
0968: * <code>TYPE_SHORT</code>,
0969: * <code>TYPE_INT</code>,
0970: * <code>TYPE_FLOAT</code>, or
0971: * <code>TYPE_DOUBLE</code>.
0972: * @param width The desired width of the <code>SampleModel</code>.
0973: * @param height The desired height of the <code>SampleModel</code>.
0974: * @param numBands The desired number of bands.
0975: */
0976: public static SampleModel createComponentSampleModel(
0977: SampleModel sm, int dataType, int width, int height,
0978: int numBands) {
0979: if (sm instanceof BandedSampleModel) {
0980: return createBandedSampleModel(dataType, width, height,
0981: numBands);
0982: } else { // default SampleModel
0983: return createPixelInterleavedSampleModel(dataType, width,
0984: height, numBands);
0985: }
0986: }
0987:
0988: /**
0989: * Creates a component-based <code>ColorModel</code> with a given
0990: * data type, color space, and transparency type. Currently this
0991: * method does not support data type <code>DataBuffer.TYPE_SHORT</code>.
0992: * If useAlpha is false, both premultiplied and transparency input
0993: * are ignored and they are set to be <code> false</code> and
0994: * <code> Transparency.OPQAUE </code>, respectively.
0995: *
0996: * @param dataType The data type of the <code>ColorModel</code>,
0997: * one of <code>DataBuffer.TYPE_BYTE</code>,
0998: * <code>TYPE_USHORT</code>,
0999: * <code>TYPE_INT</code>,
1000: * <code>TYPE_FLOAT</code>, or
1001: * <code>TYPE_DOUBLE</code>.
1002: * @param colorSpace An instance of <code>ColorSpace</code>.
1003: * @param useAlpha <code>true</code> if alpha is to be used.
1004: * @param premultiplied <code>true</code> if alpha values are
1005: * premultiplied. If <code>useAlpha</code> is
1006: * <code>false</code>, the value of
1007: * <code>premultiplied</code> is ignored.
1008: * @param transparency One of <code>Transparency.OPAQUE</code>,
1009: * <code>Transparency.BITMASK</code>, or
1010: * <code>Transparency.TRANSLUCENT</code>. If
1011: * <code>useAlpha</code> is <code>false</code>, the value of
1012: * <code>transparency</code> is ignored. If <code>useAlpha</code>
1013: * is <code>true</code>, <code>transparency</code> must not equal
1014: * <code>Transparency.OPQAUE</code>.
1015: *
1016: * @throws IllegalArgumentExceptionException if <code>colorSpace</code> is
1017: * <code>null</code>.
1018: * @throws IllegalArgumentException if <code>transparency</code>
1019: * has an unknown value, if <code>useAlpha == true</code> but
1020: * <code>transparency == Transparency.OPAQUE</code>, or if
1021: * <code>dataType</code> is not one of the standard types listed
1022: * above.
1023: */
1024: public static ComponentColorModel createComponentColorModel(
1025: int dataType, ColorSpace colorSpace, boolean useAlpha,
1026: boolean premultiplied, int transparency) {
1027:
1028: if (colorSpace == null) {
1029: throw new IllegalArgumentException(JaiI18N
1030: .getString("Generic0"));
1031: }
1032:
1033: if ((transparency != Transparency.OPAQUE)
1034: && (transparency != Transparency.BITMASK)
1035: && (transparency != Transparency.TRANSLUCENT)) {
1036: // Illegal value for transparency
1037: throw new IllegalArgumentException(JaiI18N
1038: .getString("RasterFactory13"));
1039: }
1040:
1041: if (useAlpha && (transparency == Transparency.OPAQUE)) {
1042: throw new IllegalArgumentException(JaiI18N
1043: .getString("RasterFactory14"));
1044: }
1045:
1046: if (!useAlpha) {
1047: premultiplied = false;
1048: transparency = Transparency.OPAQUE;
1049: }
1050:
1051: int bands = colorSpace.getNumComponents();
1052: if (useAlpha) {
1053: ++bands;
1054: }
1055:
1056: int dataTypeSize = DataBuffer.getDataTypeSize(dataType);
1057: int[] bits = new int[bands];
1058: for (int i = 0; i < bands; i++) {
1059: bits[i] = dataTypeSize;
1060: }
1061:
1062: switch (dataType) {
1063: case DataBuffer.TYPE_BYTE:
1064: return new ComponentColorModel(colorSpace, bits, useAlpha,
1065: premultiplied, transparency, dataType);
1066: case DataBuffer.TYPE_USHORT:
1067: return new ComponentColorModel(colorSpace, bits, useAlpha,
1068: premultiplied, transparency, dataType);
1069: /// case DataBuffer.TYPE_SHORT:
1070: /// return new ShortComponentColorModel(colorSpace,
1071: /// bits,
1072: /// useAlpha,
1073: /// premultiplied,
1074: /// transparency);
1075: case DataBuffer.TYPE_INT:
1076: return new ComponentColorModel(colorSpace, bits, useAlpha,
1077: premultiplied, transparency, dataType);
1078: case DataBuffer.TYPE_FLOAT:
1079: return new FloatDoubleColorModel(colorSpace, useAlpha,
1080: premultiplied, transparency, dataType);
1081: case DataBuffer.TYPE_DOUBLE:
1082: return new FloatDoubleColorModel(colorSpace, useAlpha,
1083: premultiplied, transparency, dataType);
1084: default:
1085: throw new IllegalArgumentException(JaiI18N
1086: .getString("RasterFactory8"));
1087: }
1088: }
1089: }
|