0001: /*
0002: * $RCSfile: LookupTableJAI.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.1 $
0009: * $Date: 2005/02/11 04:57:12 $
0010: * $State: Exp $
0011: */
0012: package javax.media.jai;
0013:
0014: import java.awt.Rectangle;
0015: import java.awt.Point;
0016: import java.awt.image.BandedSampleModel;
0017: import java.awt.image.DataBuffer;
0018: import java.awt.image.DataBufferByte;
0019: import java.awt.image.DataBufferInt;
0020: import java.awt.image.DataBufferShort;
0021: import java.awt.image.DataBufferUShort;
0022: import java.awt.image.Raster;
0023: import java.awt.image.SampleModel;
0024: import java.awt.image.WritableRaster;
0025: import java.io.IOException;
0026: import java.io.ObjectInputStream;
0027: import java.io.ObjectOutputStream;
0028: import java.io.Serializable;
0029: import javax.media.jai.remote.SerializableState;
0030: import javax.media.jai.remote.SerializerFactory;
0031: import com.sun.media.jai.util.DataBufferUtils;
0032:
0033: /**
0034: * A lookup table object associated with the "Lookup" operation. The
0035: * "Lookup" operation is described in
0036: * <code>javax.media.jai.operator.LookupDescriptor</code>.
0037: *
0038: * <p>This object represents a single- or multi-banded table of any
0039: * JAI supported data type. A single- or multi-banded source image
0040: * of integral data types is passed through the table and transformed
0041: * into a single- or multi-banded destination image of either integral
0042: * and floating point data types.
0043: *
0044: * <p>The table data may cover only a subrange of the legal range of the
0045: * input data type. The subrange is selected by means of an offset parameter
0046: * which is to be subtracted from the input value before indexing into the
0047: * table array. When only a subranged table is used with a source image, it
0048: * is up to the user to make certain that the source image does not have
0049: * pixel values outside of the table range. Otherwise,
0050: * an ArrayIndexOutOfBoundsException can occur.
0051: *
0052: * <p>The table data is saved by reference only.
0053: *
0054: * @see javax.media.jai.operator.LookupDescriptor
0055: *
0056: */
0057: public class LookupTableJAI extends Object implements Serializable {
0058:
0059: /** The table data. */
0060: transient DataBuffer data;
0061:
0062: /** The band offset values */
0063: private int[] tableOffsets;
0064:
0065: /**
0066: * Constructs a single-banded byte lookup table. The index offset is 0.
0067: *
0068: * @param data The single-banded byte data.
0069: * @throws IllegalArgumentException if data is null.
0070: */
0071: public LookupTableJAI(byte[] data) {
0072: if (data == null) {
0073: throw new IllegalArgumentException(JaiI18N
0074: .getString("Generic0"));
0075: }
0076:
0077: this .data = new DataBufferByte(data, data.length);
0078: this .initOffsets(1, 0);
0079: }
0080:
0081: /**
0082: * Constructs a single-banded byte lookup table with an index offset.
0083: *
0084: * @param data The single-banded byte data.
0085: * @param offset The offset.
0086: * @throws IllegalArgumentException if data is null.
0087: */
0088: public LookupTableJAI(byte[] data, int offset) {
0089: if (data == null) {
0090: throw new IllegalArgumentException(JaiI18N
0091: .getString("Generic0"));
0092: }
0093:
0094: this .initOffsets(1, offset);
0095: this .data = new DataBufferByte(data, data.length);
0096: }
0097:
0098: /**
0099: * Constructs a multi-banded byte lookup table. The index offset for
0100: * each band is 0.
0101: *
0102: * @param data The multi-banded byte data in [band][index] format.
0103: * @throws IllegalArgumentException if data is null.
0104: */
0105: public LookupTableJAI(byte[][] data) {
0106: if (data == null) {
0107: throw new IllegalArgumentException(JaiI18N
0108: .getString("Generic0"));
0109: }
0110:
0111: this .initOffsets(data.length, 0);
0112: this .data = new DataBufferByte(data, data[0].length);
0113: }
0114:
0115: /**
0116: * Constructs a multi-banded byte lookup table where all bands have
0117: * the same index offset.
0118: *
0119: * @param data The multi-banded byte data in [band][index] format.
0120: * @param offset The common offset for all bands.
0121: * @throws IllegalArgumentException if data is null.
0122: */
0123: public LookupTableJAI(byte[][] data, int offset) {
0124: if (data == null) {
0125: throw new IllegalArgumentException(JaiI18N
0126: .getString("Generic0"));
0127: }
0128:
0129: this .initOffsets(data.length, offset);
0130: this .data = new DataBufferByte(data, data[0].length);
0131: }
0132:
0133: /**
0134: * Constructs a multi-banded byte lookup table where each band has
0135: * a different index offset.
0136: *
0137: * @param data The multi-banded byte data in [band][index] format.
0138: * @param offsets The offsets for the bands.
0139: * @throws IllegalArgumentException if data is null.
0140: */
0141: public LookupTableJAI(byte[][] data, int[] offsets) {
0142: if (data == null) {
0143: throw new IllegalArgumentException(JaiI18N
0144: .getString("Generic0"));
0145: }
0146:
0147: this .initOffsets(data.length, offsets);
0148: this .data = new DataBufferByte(data, data[0].length);
0149: }
0150:
0151: /**
0152: * Constructs a single-banded short or unsigned short lookup table.
0153: * The index offset is 0.
0154: *
0155: * @param data The single-banded short data.
0156: * @param isUShort True if data type is DataBuffer.TYPE_USHORT;
0157: * false if data type is DataBuffer.TYPE_SHORT.
0158: * @throws IllegalArgumentException if data is null.
0159: */
0160: public LookupTableJAI(short[] data, boolean isUShort) {
0161: if (data == null) {
0162: throw new IllegalArgumentException(JaiI18N
0163: .getString("Generic0"));
0164: }
0165:
0166: this .initOffsets(1, 0);
0167: if (isUShort) {
0168: this .data = new DataBufferUShort(data, data.length);
0169: } else {
0170: this .data = new DataBufferShort(data, data.length);
0171: }
0172: }
0173:
0174: /**
0175: * Constructs a single-banded short or unsigned short lookup table with
0176: * an index offset.
0177: *
0178: * @param data The single-banded short data.
0179: * @param offset The offset.
0180: * @param isUShort True if data type is DataBuffer.TYPE_USHORT;
0181: * false if data type is DataBuffer.TYPE_SHORT.
0182: * @throws IllegalArgumentException if data is null.
0183: */
0184: public LookupTableJAI(short[] data, int offset, boolean isUShort) {
0185: if (data == null) {
0186: throw new IllegalArgumentException(JaiI18N
0187: .getString("Generic0"));
0188: }
0189:
0190: this .initOffsets(1, offset);
0191: if (isUShort) {
0192: this .data = new DataBufferUShort(data, data.length);
0193: } else {
0194: this .data = new DataBufferShort(data, data.length);
0195: }
0196: }
0197:
0198: /**
0199: * Constructs a multi-banded short or unsigned short lookup table.
0200: * The index offset for each band is 0.
0201: *
0202: * @param data The multi-banded short data in [band][index] format.
0203: * @param isUShort True if data type is DataBuffer.TYPE_USHORT;
0204: * false if data type is DataBuffer.TYPE_SHORT.
0205: * @throws IllegalArgumentException if data is null.
0206: */
0207: public LookupTableJAI(short[][] data, boolean isUShort) {
0208: if (data == null) {
0209: throw new IllegalArgumentException(JaiI18N
0210: .getString("Generic0"));
0211: }
0212:
0213: this .initOffsets(data.length, 0);
0214: if (isUShort) {
0215: this .data = new DataBufferUShort(data, data[0].length);
0216: } else {
0217: this .data = new DataBufferShort(data, data[0].length);
0218: }
0219: }
0220:
0221: /**
0222: * Constructs a multi-banded short or unsigned short lookup table where all
0223: * bands have the same index offset.
0224: *
0225: * @param data The multi-banded short data in [band][index] format.
0226: * @param offset The common offset for all bands.
0227: * @param isUShort True if data type is DataBuffer.TYPE_USHORT;
0228: * false if data type is DataBuffer.TYPE_SHORT.
0229: * @throws IllegalArgumentException if data is null.
0230: */
0231: public LookupTableJAI(short[][] data, int offset, boolean isUShort) {
0232: if (data == null) {
0233: throw new IllegalArgumentException(JaiI18N
0234: .getString("Generic0"));
0235: }
0236:
0237: this .initOffsets(data.length, offset);
0238: if (isUShort) {
0239: this .data = new DataBufferUShort(data, data[0].length);
0240: } else {
0241: this .data = new DataBufferShort(data, data[0].length);
0242: }
0243: }
0244:
0245: /**
0246: * Constructs a multi-banded short or unsigned short lookup table where
0247: * each band has a different index offset.
0248: *
0249: * @param data The multi-banded short data in [band][index] format.
0250: * @param offsets The offsets for the bands.
0251: * @param isUShort True if data type is DataBuffer.TYPE_USHORT;
0252: * false if data type is DataBuffer.TYPE_SHORT.
0253: * @throws IllegalArgumentException if data is null.
0254: */
0255: public LookupTableJAI(short[][] data, int[] offsets,
0256: boolean isUShort) {
0257: if (data == null) {
0258: throw new IllegalArgumentException(JaiI18N
0259: .getString("Generic0"));
0260: }
0261:
0262: this .initOffsets(data.length, offsets);
0263:
0264: if (isUShort) {
0265: this .data = new DataBufferUShort(data, data[0].length);
0266: } else {
0267: this .data = new DataBufferShort(data, data[0].length);
0268: }
0269: }
0270:
0271: /**
0272: * Constructs a single-banded int lookup table. The index offset is 0.
0273: *
0274: * @param data The single-banded int data.
0275: * @throws IllegalArgumentException if data is null.
0276: */
0277: public LookupTableJAI(int[] data) {
0278: if (data == null) {
0279: throw new IllegalArgumentException(JaiI18N
0280: .getString("Generic0"));
0281: }
0282:
0283: this .initOffsets(1, 0);
0284: this .data = new DataBufferInt(data, data.length);
0285: }
0286:
0287: /**
0288: * Constructs a single-banded int lookup table with an index offset.
0289: *
0290: * @param data The single-banded int data.
0291: * @param offset The offset.
0292: * @throws IllegalArgumentException if data is null.
0293: */
0294: public LookupTableJAI(int[] data, int offset) {
0295: if (data == null) {
0296: throw new IllegalArgumentException(JaiI18N
0297: .getString("Generic0"));
0298: }
0299:
0300: this .initOffsets(1, offset);
0301: this .data = new DataBufferInt(data, data.length);
0302: }
0303:
0304: /**
0305: * Constructs a multi-banded int lookup table. The index offset for
0306: * each band is 0.
0307: *
0308: * @param data The multi-banded int data in [band][index] format.
0309: * @throws IllegalArgumentException if data is null.
0310: */
0311: public LookupTableJAI(int[][] data) {
0312: if (data == null) {
0313: throw new IllegalArgumentException(JaiI18N
0314: .getString("Generic0"));
0315: }
0316:
0317: this .initOffsets(data.length, 0);
0318: this .data = new DataBufferInt(data, data[0].length);
0319: }
0320:
0321: /**
0322: * Constructs a multi-banded int lookup table where all bands have
0323: * the same index offset.
0324: *
0325: * @param data The multi-banded int data in [band][index] format.
0326: * @param offset The common offset for all bands.
0327: * @throws IllegalArgumentException if data is null.
0328: */
0329: public LookupTableJAI(int[][] data, int offset) {
0330: if (data == null) {
0331: throw new IllegalArgumentException(JaiI18N
0332: .getString("Generic0"));
0333: }
0334:
0335: this .initOffsets(data.length, offset);
0336: this .data = new DataBufferInt(data, data[0].length);
0337: }
0338:
0339: /**
0340: * Constructs a multi-banded int lookup table where each band has
0341: * a different index offset.
0342: *
0343: * @param data The multi-banded int data in [band][index] format.
0344: * @param offsets The offsets for the bands.
0345: * @throws IllegalArgumentException if data is null.
0346: */
0347: public LookupTableJAI(int[][] data, int[] offsets) {
0348: if (data == null) {
0349: throw new IllegalArgumentException(JaiI18N
0350: .getString("Generic0"));
0351: }
0352:
0353: this .initOffsets(data.length, offsets);
0354: this .data = new DataBufferInt(data, data[0].length);
0355: }
0356:
0357: /**
0358: * Constructs a single-banded float lookup table. The index offset is 0.
0359: *
0360: * @param data The single-banded float data.
0361: * @throws IllegalArgumentException if data is null.
0362: */
0363: public LookupTableJAI(float[] data) {
0364: if (data == null) {
0365: throw new IllegalArgumentException(JaiI18N
0366: .getString("Generic0"));
0367: }
0368:
0369: this .initOffsets(1, 0);
0370: this .data = DataBufferUtils.createDataBufferFloat(data,
0371: data.length);
0372: }
0373:
0374: /**
0375: * Constructs a single-banded float lookup table with an index offset.
0376: *
0377: * @param data The single-banded float data.
0378: * @param offset The offset.
0379: * @throws IllegalArgumentException if data is null.
0380: */
0381: public LookupTableJAI(float[] data, int offset) {
0382: if (data == null) {
0383: throw new IllegalArgumentException(JaiI18N
0384: .getString("Generic0"));
0385: }
0386:
0387: this .initOffsets(1, offset);
0388: this .data = DataBufferUtils.createDataBufferFloat(data,
0389: data.length);
0390: }
0391:
0392: /**
0393: * Constructs a multi-banded float lookup table. The index offset for
0394: * each band is 0.
0395: *
0396: * @param data The multi-banded float data in [band][index] format.
0397: * @throws IllegalArgumentException if data is null.
0398: */
0399: public LookupTableJAI(float[][] data) {
0400: if (data == null) {
0401: throw new IllegalArgumentException(JaiI18N
0402: .getString("Generic0"));
0403: }
0404:
0405: this .initOffsets(data.length, 0);
0406: this .data = DataBufferUtils.createDataBufferFloat(data,
0407: data[0].length);
0408: }
0409:
0410: /**
0411: * Constructs a multi-banded float lookup table where all bands have
0412: * the same index offset.
0413: *
0414: * @param data The multi-banded float data in [band][index] format.
0415: * @param offset The common offset for all bands.
0416: * @throws IllegalArgumentException if data is null.
0417: */
0418: public LookupTableJAI(float[][] data, int offset) {
0419: if (data == null) {
0420: throw new IllegalArgumentException(JaiI18N
0421: .getString("Generic0"));
0422: }
0423:
0424: this .initOffsets(data.length, offset);
0425: this .data = DataBufferUtils.createDataBufferFloat(data,
0426: data[0].length);
0427: }
0428:
0429: /**
0430: * Constructs a multi-banded float lookup table where each band has
0431: * a different index offset.
0432: *
0433: * @param data The multi-banded float data in [band][index] format.
0434: * @param offsets The offsets for the bands.
0435: * @throws IllegalArgumentException if data is null.
0436: */
0437: public LookupTableJAI(float[][] data, int[] offsets) {
0438: if (data == null) {
0439: throw new IllegalArgumentException(JaiI18N
0440: .getString("Generic0"));
0441: }
0442:
0443: this .initOffsets(data.length, offsets);
0444: this .data = DataBufferUtils.createDataBufferFloat(data,
0445: data[0].length);
0446: }
0447:
0448: /**
0449: * Constructs a single-banded double lookup table. The index offset is 0.
0450: *
0451: * @param data The single-banded double data.
0452: * @throws IllegalArgumentException if data is null.
0453: */
0454: public LookupTableJAI(double[] data) {
0455: if (data == null) {
0456: throw new IllegalArgumentException(JaiI18N
0457: .getString("Generic0"));
0458: }
0459:
0460: this .initOffsets(1, 0);
0461: this .data = DataBufferUtils.createDataBufferDouble(data,
0462: data.length);
0463: }
0464:
0465: /**
0466: * Constructs a single-banded double lookup table with an index offset.
0467: *
0468: * @param data The single-banded double data.
0469: * @param offset The offset.
0470: * @throws IllegalArgumentException if data is null.
0471: */
0472: public LookupTableJAI(double[] data, int offset) {
0473: if (data == null) {
0474: throw new IllegalArgumentException(JaiI18N
0475: .getString("Generic0"));
0476: }
0477:
0478: this .initOffsets(1, offset);
0479: this .data = DataBufferUtils.createDataBufferDouble(data,
0480: data.length);
0481: }
0482:
0483: /**
0484: * Constructs a multi-banded double lookup table. The index offset for
0485: * each band is 0.
0486: *
0487: * @param data The multi-banded double data in [band][index] format.
0488: * @throws IllegalArgumentException if data is null.
0489: */
0490: public LookupTableJAI(double[][] data) {
0491: if (data == null) {
0492: throw new IllegalArgumentException(JaiI18N
0493: .getString("Generic0"));
0494: }
0495:
0496: this .initOffsets(data.length, 0);
0497: this .data = DataBufferUtils.createDataBufferDouble(data,
0498: data[0].length);
0499: }
0500:
0501: /**
0502: * Constructs a multi-banded double lookup table where all bands have
0503: * the same index offset.
0504: *
0505: * @param data The multi-banded double data in [band][index] format.
0506: * @param offset The common offset for all bands.
0507: * @throws IllegalArgumentException if data is null.
0508: */
0509: public LookupTableJAI(double[][] data, int offset) {
0510: if (data == null) {
0511: throw new IllegalArgumentException(JaiI18N
0512: .getString("Generic0"));
0513: }
0514:
0515: this .initOffsets(data.length, offset);
0516: this .data = DataBufferUtils.createDataBufferDouble(data,
0517: data[0].length);
0518: }
0519:
0520: /**
0521: * Constructs a multi-banded double lookup table where each band has
0522: * a different index offset.
0523: *
0524: * @param data The multi-banded double data in [band][index] format.
0525: * @param offsets The offsets for the bands.
0526: * @throws IllegalArgumentException if data is null.
0527: */
0528: public LookupTableJAI(double[][] data, int[] offsets) {
0529: if (data == null) {
0530: throw new IllegalArgumentException(JaiI18N
0531: .getString("Generic0"));
0532: }
0533:
0534: this .initOffsets(data.length, offsets);
0535: this .data = DataBufferUtils.createDataBufferDouble(data,
0536: data[0].length);
0537: }
0538:
0539: /**
0540: * Returns the table data as a DataBuffer.
0541: */
0542: public DataBuffer getData() {
0543: return data;
0544: }
0545:
0546: /**
0547: * Returns the byte table data in array format, or null if the
0548: * table's data type is not byte.
0549: */
0550: public byte[][] getByteData() {
0551: return data instanceof DataBufferByte ? ((DataBufferByte) data)
0552: .getBankData() : null;
0553: }
0554:
0555: /**
0556: * Returns the byte table data of a specific band in array format,
0557: * or null if the table's data type is not byte.
0558: */
0559: public byte[] getByteData(int band) {
0560: return data instanceof DataBufferByte ? ((DataBufferByte) data)
0561: .getData(band) : null;
0562: }
0563:
0564: /**
0565: * Returns the short table data in array format, or null if the
0566: * table's data type is not short. This includes both signed and
0567: * unsigned short table data.
0568: *
0569: */
0570: public short[][] getShortData() {
0571: if (data instanceof DataBufferUShort) {
0572: return ((DataBufferUShort) data).getBankData();
0573: } else if (data instanceof DataBufferShort) {
0574: return ((DataBufferShort) data).getBankData();
0575: } else {
0576: return null;
0577: }
0578: }
0579:
0580: /**
0581: * Returns the short table data of a specific band in array format,
0582: * or null if the table's data type is not short.
0583: *
0584: */
0585: public short[] getShortData(int band) {
0586: if (data instanceof DataBufferUShort) {
0587: return ((DataBufferUShort) data).getData(band);
0588: } else if (data instanceof DataBufferShort) {
0589: return ((DataBufferShort) data).getData(band);
0590: } else {
0591: return null;
0592: }
0593: }
0594:
0595: /**
0596: * Returns the integer table data in array format, or null if the
0597: * table's data type is not int.
0598: *
0599: */
0600: public int[][] getIntData() {
0601: return data instanceof DataBufferInt ? ((DataBufferInt) data)
0602: .getBankData() : null;
0603: }
0604:
0605: /**
0606: * Returns the integer table data of a specific band in array format,
0607: * or null if table's data type is not int.
0608: *
0609: */
0610: public int[] getIntData(int band) {
0611: return data instanceof DataBufferInt ? ((DataBufferInt) data)
0612: .getData(band) : null;
0613: }
0614:
0615: /**
0616: * Returns the float table data in array format, or null if the
0617: * table's data type is not float.
0618: *
0619: */
0620: public float[][] getFloatData() {
0621: return data.getDataType() == DataBuffer.TYPE_FLOAT ? DataBufferUtils
0622: .getBankDataFloat(data)
0623: : null;
0624: }
0625:
0626: /**
0627: * Returns the float table data of a specific band in array format,
0628: * or null if table's data type is not float.
0629: *
0630: */
0631: public float[] getFloatData(int band) {
0632: return data.getDataType() == DataBuffer.TYPE_FLOAT ? DataBufferUtils
0633: .getDataFloat(data, band)
0634: : null;
0635: }
0636:
0637: /**
0638: * Returns the double table data in array format, or null if the
0639: * table's data type is not double.
0640: *
0641: */
0642: public double[][] getDoubleData() {
0643: return data.getDataType() == DataBuffer.TYPE_DOUBLE ? DataBufferUtils
0644: .getBankDataDouble(data)
0645: : null;
0646: }
0647:
0648: /**
0649: * Returns the double table data of a specific band in array format,
0650: * or null if table's data type is not double.
0651: *
0652: */
0653: public double[] getDoubleData(int band) {
0654: return data.getDataType() == DataBuffer.TYPE_DOUBLE ? DataBufferUtils
0655: .getDataDouble(data, band)
0656: : null;
0657: }
0658:
0659: /** Returns the index offsets of entry 0 for all bands. */
0660: public int[] getOffsets() {
0661: return tableOffsets;
0662: }
0663:
0664: /**
0665: * Returns the index offset of entry 0 for the default band.
0666: *
0667: */
0668: public int getOffset() {
0669: return tableOffsets[0];
0670: }
0671:
0672: /**
0673: * Returns the index offset of entry 0 for a specific band.
0674: *
0675: */
0676: public int getOffset(int band) {
0677: return tableOffsets[band];
0678: }
0679:
0680: /** Returns the number of bands of the table. */
0681: public int getNumBands() {
0682: return data.getNumBanks();
0683: }
0684:
0685: /**
0686: * Returns the number of entries per band of the table.
0687: *
0688: */
0689: public int getNumEntries() {
0690: return data.getSize();
0691: }
0692:
0693: /** Returns the data type of the table data.
0694: *
0695: */
0696: public int getDataType() {
0697: return data.getDataType();
0698: }
0699:
0700: /**
0701: * Returns the number of bands of the destination image, based on
0702: * the number of bands of the source image and lookup table.
0703: *
0704: * @param srcNumBands The number of bands of the source image.
0705: * @return the number of bands in destination image.
0706: */
0707: public int getDestNumBands(int srcNumBands) {
0708: int tblNumBands = getNumBands();
0709: return srcNumBands == 1 ? tblNumBands : srcNumBands;
0710: }
0711:
0712: /**
0713: * Returns a <code>SampleModel</code> suitable for holding the output
0714: * of a lookup operation on the source data described by a given
0715: * SampleModel with this table. The width and height of the destination
0716: * SampleModel are the same as that of the source. This method will
0717: * return null if the source SampleModel has a non-integral data type.
0718: *
0719: * @param srcSampleModel The SampleModel of the source image.
0720: *
0721: * @throws IllegalArgumentException if srcSampleModel is null.
0722: * @return sampleModel suitable for the destination image.
0723: */
0724: public SampleModel getDestSampleModel(SampleModel srcSampleModel) {
0725: if (srcSampleModel == null) {
0726: throw new IllegalArgumentException(JaiI18N
0727: .getString("Generic0"));
0728: }
0729:
0730: return getDestSampleModel(srcSampleModel, srcSampleModel
0731: .getWidth(), srcSampleModel.getHeight());
0732: }
0733:
0734: /**
0735: * Returns a <code>SampleModel</code> suitable for holding the output
0736: * of a lookup operation on the source data described by a given
0737: * SampleModel with this table. This method will return null if the
0738: * source SampleModel has a non-integral data type.
0739: *
0740: * @param srcSampleModel The SampleModel of the source image.
0741: * @param width The width of the destination SampleModel.
0742: * @param height The height of the destination SampleModel.
0743: *
0744: * @throws IllegalArgumentException if srcSampleModel is null.
0745: * @return sampleModel suitable for the destination image.
0746: */
0747: public SampleModel getDestSampleModel(SampleModel srcSampleModel,
0748: int width, int height) {
0749: if (srcSampleModel == null) {
0750: throw new IllegalArgumentException(JaiI18N
0751: .getString("Generic0"));
0752: }
0753:
0754: if (!isIntegralDataType(srcSampleModel)) {
0755: return null; // source has non-integral data type
0756: }
0757:
0758: return RasterFactory.createComponentSampleModel(srcSampleModel,
0759: getDataType(), width, height,
0760: getDestNumBands(srcSampleModel.getNumBands()));
0761: }
0762:
0763: /**
0764: * Validates data type. Returns true if it's one of the integral
0765: * data types; false otherwise.
0766: *
0767: * @throws IllegalArgumentException if sampleModel is null.
0768: */
0769: public boolean isIntegralDataType(SampleModel sampleModel) {
0770: if (sampleModel == null) {
0771: throw new IllegalArgumentException(JaiI18N
0772: .getString("Generic0"));
0773: }
0774:
0775: return isIntegralDataType(sampleModel.getTransferType());
0776: }
0777:
0778: /**
0779: * Returns <code>true</code> if the specified data type is
0780: * an integral data type, such as byte, ushort, short, or int.
0781: */
0782: public boolean isIntegralDataType(int dataType) {
0783: if ((dataType == DataBuffer.TYPE_BYTE)
0784: || (dataType == DataBuffer.TYPE_USHORT)
0785: || (dataType == DataBuffer.TYPE_SHORT)
0786: || (dataType == DataBuffer.TYPE_INT)) {
0787: return true;
0788: } else {
0789: return false;
0790: }
0791: }
0792:
0793: /**
0794: * Performs lookup on a given value belonging to a given source
0795: * band, and returns the result as an int.
0796: *
0797: * @param band The source band the value is from.
0798: * @param value The source value to be placed through the lookup table.
0799: */
0800: public int lookup(int band, int value) {
0801: return data.getElem(band, value - tableOffsets[band]);
0802: }
0803:
0804: /**
0805: * Performs lookup on a given value belonging to a given source
0806: * band, and returns the result as a float.
0807: *
0808: * @param band The source band the value is from.
0809: * @param value The source value to be placed through the lookup table.
0810: */
0811: public float lookupFloat(int band, int value) {
0812: return data.getElemFloat(band, value - tableOffsets[band]);
0813: }
0814:
0815: /**
0816: * Performs lookup on a given value belonging to a given source
0817: * band, and returns the result as a double.
0818: *
0819: * @param band The source band the value is from.
0820: * @param value The source value to be placed through the lookup table.
0821: */
0822: public double lookupDouble(int band, int value) {
0823: return data.getElemDouble(band, value - tableOffsets[band]);
0824: }
0825:
0826: /**
0827: * Performs table lookup in place on a given WritableRaster. The
0828: * The lookup operation must preserve the data type and
0829: * SampleModel of the source. A reference to the supplied
0830: * WritableRaster will be returned.
0831: *
0832: * @throws IllegalArgumentException if the src is null.
0833: * @throws IllegalArgumentException if the source's SampleModel
0834: * is not of integral type.
0835: * @throws IllegalArgumentException if the lookup operation would
0836: * result in a change in the data type or number of bands
0837: * of the Raster.
0838: */
0839: public WritableRaster lookup(WritableRaster src) {
0840: if (src == null) {
0841: throw new IllegalArgumentException(JaiI18N
0842: .getString("Generic0"));
0843: }
0844:
0845: return lookup(src, src, src.getBounds());
0846: }
0847:
0848: /**
0849: * Performs table lookup on a source Raster, writing the result
0850: * into a supplied WritableRaster. The destination must have a
0851: * data type and SampleModel appropriate to the results of the
0852: * lookup operation. The table lookup operation is performed
0853: * within a specified rectangle.
0854: *
0855: * <p> The <code>dst</code> argument may be null, in which case a new
0856: * WritableRaster is created using the appropriate SampleModel.
0857: *
0858: * <p> The rectangle of interest may be null, in which case the
0859: * operation will be performed on the intersection of the source
0860: * and destination bounding rectangles.
0861: *
0862: * @param src A Raster containing the source pixel data.
0863: * @param dst The WritableRaster to be computed, or null.
0864: * If supplied, its data type and number of bands must
0865: * be suitable for the source and lookup table.
0866: * @param rect The rectangle within the tile to be computed.
0867: * If rect is null, the intersection of the source and
0868: * destination bounds will be used. Otherwise, it
0869: * will be clipped to the intersection of the source
0870: * and destination bounds.
0871: * @return A reference to the supplied WritableRaster, or to a
0872: * new WritableRaster if the supplied one was null.
0873: *
0874: * @throws IllegalArgumentException if the source is null.
0875: * @throws IllegalArgumentException if the source's SampleModel
0876: * is not of integral type.
0877: * @throws IllegalArgumentException if the destination's data type
0878: * or number of bands differ from those returned by
0879: * getDataType() and getDestNumBands().
0880: */
0881: public WritableRaster lookup(Raster src, WritableRaster dst,
0882: Rectangle rect) {
0883: // Validate source.
0884: if (src == null) {
0885: throw new IllegalArgumentException(JaiI18N
0886: .getString("LookupTableJAI1"));
0887: }
0888:
0889: SampleModel srcSampleModel = src.getSampleModel();
0890: if (!isIntegralDataType(srcSampleModel)) {
0891: throw new IllegalArgumentException(JaiI18N
0892: .getString("LookupTableJAI2"));
0893: }
0894:
0895: // Validate rectangle.
0896: if (rect == null) {
0897: rect = src.getBounds();
0898: } else {
0899: rect = rect.intersection(src.getBounds());
0900: }
0901:
0902: if (dst != null) {
0903: rect = rect.intersection(dst.getBounds());
0904: }
0905:
0906: // Validate destination.
0907: SampleModel dstSampleModel;
0908: if (dst == null) { // create dst according to table
0909: dstSampleModel = getDestSampleModel(srcSampleModel,
0910: rect.width, rect.height);
0911: dst = RasterFactory.createWritableRaster(dstSampleModel,
0912: new Point(rect.x, rect.y));
0913: } else {
0914: dstSampleModel = dst.getSampleModel();
0915:
0916: if (dstSampleModel.getTransferType() != getDataType()
0917: || dstSampleModel.getNumBands() != getDestNumBands(srcSampleModel
0918: .getNumBands())) {
0919: throw new IllegalArgumentException(JaiI18N
0920: .getString("LookupTableJAI3"));
0921: }
0922: }
0923:
0924: // Add bit support?
0925: int sTagID = RasterAccessor.findCompatibleTag(null,
0926: srcSampleModel);
0927: int dTagID = RasterAccessor.findCompatibleTag(null,
0928: dstSampleModel);
0929:
0930: RasterFormatTag sTag = new RasterFormatTag(srcSampleModel,
0931: sTagID);
0932: RasterFormatTag dTag = new RasterFormatTag(dstSampleModel,
0933: dTagID);
0934:
0935: RasterAccessor s = new RasterAccessor(src, rect, sTag, null);
0936: RasterAccessor d = new RasterAccessor(dst, rect, dTag, null);
0937:
0938: int srcNumBands = s.getNumBands();
0939: int srcDataType = s.getDataType();
0940:
0941: int tblNumBands = getNumBands();
0942: int tblDataType = getDataType();
0943:
0944: int dstWidth = d.getWidth();
0945: int dstHeight = d.getHeight();
0946: int dstNumBands = d.getNumBands();
0947: int dstDataType = d.getDataType();
0948:
0949: // Source information.
0950: int srcLineStride = s.getScanlineStride();
0951: int srcPixelStride = s.getPixelStride();
0952: int[] srcBandOffsets = s.getBandOffsets();
0953:
0954: byte[][] bSrcData = s.getByteDataArrays();
0955: short[][] sSrcData = s.getShortDataArrays();
0956: int[][] iSrcData = s.getIntDataArrays();
0957:
0958: if (srcNumBands < dstNumBands) {
0959: int offset0 = srcBandOffsets[0];
0960: srcBandOffsets = new int[dstNumBands];
0961: for (int i = 0; i < dstNumBands; i++) {
0962: srcBandOffsets[i] = offset0;
0963: }
0964:
0965: switch (srcDataType) {
0966: case DataBuffer.TYPE_BYTE:
0967: byte[] bData0 = bSrcData[0];
0968: bSrcData = new byte[dstNumBands][];
0969: for (int i = 0; i < dstNumBands; i++) {
0970: bSrcData[i] = bData0;
0971: }
0972: break;
0973: case DataBuffer.TYPE_USHORT:
0974: case DataBuffer.TYPE_SHORT:
0975: short[] sData0 = sSrcData[0];
0976: sSrcData = new short[dstNumBands][];
0977: for (int i = 0; i < dstNumBands; i++) {
0978: sSrcData[i] = sData0;
0979: }
0980: break;
0981: case DataBuffer.TYPE_INT:
0982: int[] iData0 = iSrcData[0];
0983: iSrcData = new int[dstNumBands][];
0984: for (int i = 0; i < dstNumBands; i++) {
0985: iSrcData[i] = iData0;
0986: }
0987: break;
0988: }
0989: }
0990:
0991: // Table information.
0992: int[] tblOffsets = getOffsets();
0993:
0994: byte[][] bTblData = getByteData();
0995: short[][] sTblData = getShortData();
0996: int[][] iTblData = getIntData();
0997: float[][] fTblData = getFloatData();
0998: double[][] dTblData = getDoubleData();
0999:
1000: if (tblNumBands < dstNumBands) {
1001: int offset0 = tblOffsets[0];
1002: tblOffsets = new int[dstNumBands];
1003: for (int i = 0; i < dstNumBands; i++) {
1004: tblOffsets[i] = offset0;
1005: }
1006:
1007: switch (tblDataType) {
1008: case DataBuffer.TYPE_BYTE:
1009: byte[] bData0 = bTblData[0];
1010: bTblData = new byte[dstNumBands][];
1011: for (int i = 0; i < dstNumBands; i++) {
1012: bTblData[i] = bData0;
1013: }
1014: break;
1015: case DataBuffer.TYPE_USHORT:
1016: case DataBuffer.TYPE_SHORT:
1017: short[] sData0 = sTblData[0];
1018: sTblData = new short[dstNumBands][];
1019: for (int i = 0; i < dstNumBands; i++) {
1020: sTblData[i] = sData0;
1021: }
1022: break;
1023: case DataBuffer.TYPE_INT:
1024: int[] iData0 = iTblData[0];
1025: iTblData = new int[dstNumBands][];
1026: for (int i = 0; i < dstNumBands; i++) {
1027: iTblData[i] = iData0;
1028: }
1029: break;
1030: case DataBuffer.TYPE_FLOAT:
1031: float[] fData0 = fTblData[0];
1032: fTblData = new float[dstNumBands][];
1033: for (int i = 0; i < dstNumBands; i++) {
1034: fTblData[i] = fData0;
1035: }
1036: break;
1037: case DataBuffer.TYPE_DOUBLE:
1038: double[] dData0 = dTblData[0];
1039: dTblData = new double[dstNumBands][];
1040: for (int i = 0; i < dstNumBands; i++) {
1041: dTblData[i] = dData0;
1042: }
1043: }
1044: }
1045:
1046: // Destination information.
1047: int dstLineStride = d.getScanlineStride();
1048: int dstPixelStride = d.getPixelStride();
1049: int[] dstBandOffsets = d.getBandOffsets();
1050:
1051: byte[][] bDstData = d.getByteDataArrays();
1052: short[][] sDstData = d.getShortDataArrays();
1053: int[][] iDstData = d.getIntDataArrays();
1054: float[][] fDstData = d.getFloatDataArrays();
1055: double[][] dDstData = d.getDoubleDataArrays();
1056:
1057: switch (dstDataType) {
1058: case DataBuffer.TYPE_BYTE:
1059: switch (srcDataType) {
1060: case DataBuffer.TYPE_BYTE:
1061: lookup(srcLineStride, srcPixelStride, srcBandOffsets,
1062: bSrcData, dstWidth, dstHeight, dstNumBands,
1063: dstLineStride, dstPixelStride, dstBandOffsets,
1064: bDstData, tblOffsets, bTblData);
1065: break;
1066:
1067: case DataBuffer.TYPE_USHORT:
1068: lookupU(srcLineStride, srcPixelStride, srcBandOffsets,
1069: sSrcData, dstWidth, dstHeight, dstNumBands,
1070: dstLineStride, dstPixelStride, dstBandOffsets,
1071: bDstData, tblOffsets, bTblData);
1072: break;
1073:
1074: case DataBuffer.TYPE_SHORT:
1075: lookup(srcLineStride, srcPixelStride, srcBandOffsets,
1076: sSrcData, dstWidth, dstHeight, dstNumBands,
1077: dstLineStride, dstPixelStride, dstBandOffsets,
1078: bDstData, tblOffsets, bTblData);
1079: break;
1080:
1081: case DataBuffer.TYPE_INT:
1082: lookup(srcLineStride, srcPixelStride, srcBandOffsets,
1083: iSrcData, dstWidth, dstHeight, dstNumBands,
1084: dstLineStride, dstPixelStride, dstBandOffsets,
1085: bDstData, tblOffsets, bTblData);
1086: break;
1087: }
1088: break;
1089:
1090: case DataBuffer.TYPE_USHORT:
1091: case DataBuffer.TYPE_SHORT:
1092: switch (srcDataType) {
1093: case DataBuffer.TYPE_BYTE:
1094: lookup(srcLineStride, srcPixelStride, srcBandOffsets,
1095: bSrcData, dstWidth, dstHeight, dstNumBands,
1096: dstLineStride, dstPixelStride, dstBandOffsets,
1097: sDstData, tblOffsets, sTblData);
1098: break;
1099:
1100: case DataBuffer.TYPE_USHORT:
1101: lookupU(srcLineStride, srcPixelStride, srcBandOffsets,
1102: sSrcData, dstWidth, dstHeight, dstNumBands,
1103: dstLineStride, dstPixelStride, dstBandOffsets,
1104: sDstData, tblOffsets, sTblData);
1105: break;
1106:
1107: case DataBuffer.TYPE_SHORT:
1108: lookup(srcLineStride, srcPixelStride, srcBandOffsets,
1109: sSrcData, dstWidth, dstHeight, dstNumBands,
1110: dstLineStride, dstPixelStride, dstBandOffsets,
1111: sDstData, tblOffsets, sTblData);
1112: break;
1113:
1114: case DataBuffer.TYPE_INT:
1115: lookup(srcLineStride, srcPixelStride, srcBandOffsets,
1116: iSrcData, dstWidth, dstHeight, dstNumBands,
1117: dstLineStride, dstPixelStride, dstBandOffsets,
1118: sDstData, tblOffsets, sTblData);
1119: break;
1120: }
1121: break;
1122:
1123: case DataBuffer.TYPE_INT:
1124: switch (srcDataType) {
1125: case DataBuffer.TYPE_BYTE:
1126: lookup(srcLineStride, srcPixelStride, srcBandOffsets,
1127: bSrcData, dstWidth, dstHeight, dstNumBands,
1128: dstLineStride, dstPixelStride, dstBandOffsets,
1129: iDstData, tblOffsets, iTblData);
1130: break;
1131:
1132: case DataBuffer.TYPE_USHORT:
1133: lookupU(srcLineStride, srcPixelStride, srcBandOffsets,
1134: sSrcData, dstWidth, dstHeight, dstNumBands,
1135: dstLineStride, dstPixelStride, dstBandOffsets,
1136: iDstData, tblOffsets, iTblData);
1137: break;
1138:
1139: case DataBuffer.TYPE_SHORT:
1140: lookup(srcLineStride, srcPixelStride, srcBandOffsets,
1141: sSrcData, dstWidth, dstHeight, dstNumBands,
1142: dstLineStride, dstPixelStride, dstBandOffsets,
1143: iDstData, tblOffsets, iTblData);
1144: break;
1145:
1146: case DataBuffer.TYPE_INT:
1147: lookup(srcLineStride, srcPixelStride, srcBandOffsets,
1148: iSrcData, dstWidth, dstHeight, dstNumBands,
1149: dstLineStride, dstPixelStride, dstBandOffsets,
1150: iDstData, tblOffsets, iTblData);
1151: break;
1152: }
1153: break;
1154:
1155: case DataBuffer.TYPE_FLOAT:
1156: switch (srcDataType) {
1157: case DataBuffer.TYPE_BYTE:
1158: lookup(srcLineStride, srcPixelStride, srcBandOffsets,
1159: bSrcData, dstWidth, dstHeight, dstNumBands,
1160: dstLineStride, dstPixelStride, dstBandOffsets,
1161: fDstData, tblOffsets, fTblData);
1162: break;
1163:
1164: case DataBuffer.TYPE_USHORT:
1165: lookupU(srcLineStride, srcPixelStride, srcBandOffsets,
1166: sSrcData, dstWidth, dstHeight, dstNumBands,
1167: dstLineStride, dstPixelStride, dstBandOffsets,
1168: fDstData, tblOffsets, fTblData);
1169: break;
1170:
1171: case DataBuffer.TYPE_SHORT:
1172: lookup(srcLineStride, srcPixelStride, srcBandOffsets,
1173: sSrcData, dstWidth, dstHeight, dstNumBands,
1174: dstLineStride, dstPixelStride, dstBandOffsets,
1175: fDstData, tblOffsets, fTblData);
1176: break;
1177:
1178: case DataBuffer.TYPE_INT:
1179: lookup(srcLineStride, srcPixelStride, srcBandOffsets,
1180: iSrcData, dstWidth, dstHeight, dstNumBands,
1181: dstLineStride, dstPixelStride, dstBandOffsets,
1182: fDstData, tblOffsets, fTblData);
1183: break;
1184: }
1185: break;
1186:
1187: case DataBuffer.TYPE_DOUBLE:
1188: switch (srcDataType) {
1189: case DataBuffer.TYPE_BYTE:
1190: lookup(srcLineStride, srcPixelStride, srcBandOffsets,
1191: bSrcData, dstWidth, dstHeight, dstNumBands,
1192: dstLineStride, dstPixelStride, dstBandOffsets,
1193: dDstData, tblOffsets, dTblData);
1194: break;
1195:
1196: case DataBuffer.TYPE_USHORT:
1197: lookupU(srcLineStride, srcPixelStride, srcBandOffsets,
1198: sSrcData, dstWidth, dstHeight, dstNumBands,
1199: dstLineStride, dstPixelStride, dstBandOffsets,
1200: dDstData, tblOffsets, dTblData);
1201: break;
1202:
1203: case DataBuffer.TYPE_SHORT:
1204: lookup(srcLineStride, srcPixelStride, srcBandOffsets,
1205: sSrcData, dstWidth, dstHeight, dstNumBands,
1206: dstLineStride, dstPixelStride, dstBandOffsets,
1207: dDstData, tblOffsets, dTblData);
1208: break;
1209:
1210: case DataBuffer.TYPE_INT:
1211: lookup(srcLineStride, srcPixelStride, srcBandOffsets,
1212: iSrcData, dstWidth, dstHeight, dstNumBands,
1213: dstLineStride, dstPixelStride, dstBandOffsets,
1214: dDstData, tblOffsets, dTblData);
1215: break;
1216: }
1217: break;
1218: }
1219:
1220: d.copyDataToRaster();
1221:
1222: return dst;
1223: }
1224:
1225: // byte to byte
1226: private void lookup(int srcLineStride, int srcPixelStride,
1227: int[] srcBandOffsets, byte[][] srcData, int width,
1228: int height, int bands, int dstLineStride,
1229: int dstPixelStride, int[] dstBandOffsets, byte[][] dstData,
1230: int[] tblOffsets, byte[][] tblData) {
1231: for (int b = 0; b < bands; b++) {
1232: byte[] s = srcData[b];
1233: byte[] d = dstData[b];
1234: byte[] t = tblData[b];
1235:
1236: int srcLineOffset = srcBandOffsets[b];
1237: int dstLineOffset = dstBandOffsets[b];
1238: int tblOffset = tblOffsets[b];
1239:
1240: for (int h = 0; h < height; h++) {
1241: int srcPixelOffset = srcLineOffset;
1242: int dstPixelOffset = dstLineOffset;
1243:
1244: srcLineOffset += srcLineStride;
1245: dstLineOffset += dstLineStride;
1246:
1247: for (int w = 0; w < width; w++) {
1248: d[dstPixelOffset] = t[(s[srcPixelOffset] & 0xFF)
1249: - tblOffset];
1250:
1251: srcPixelOffset += srcPixelStride;
1252: dstPixelOffset += dstPixelStride;
1253: }
1254: }
1255: }
1256: }
1257:
1258: // ushort to byte
1259: private void lookupU(int srcLineStride, int srcPixelStride,
1260: int[] srcBandOffsets, short[][] srcData, int width,
1261: int height, int bands, int dstLineStride,
1262: int dstPixelStride, int[] dstBandOffsets, byte[][] dstData,
1263: int[] tblOffsets, byte[][] tblData) {
1264: for (int b = 0; b < bands; b++) {
1265: short[] s = srcData[b];
1266: byte[] d = dstData[b];
1267: byte[] t = tblData[b];
1268:
1269: int srcLineOffset = srcBandOffsets[b];
1270: int dstLineOffset = dstBandOffsets[b];
1271: int tblOffset = tblOffsets[b];
1272:
1273: for (int h = 0; h < height; h++) {
1274: int srcPixelOffset = srcLineOffset;
1275: int dstPixelOffset = dstLineOffset;
1276:
1277: srcLineOffset += srcLineStride;
1278: dstLineOffset += dstLineStride;
1279:
1280: for (int w = 0; w < width; w++) {
1281: d[dstPixelOffset] = t[(s[srcPixelOffset] & 0xFFFF)
1282: - tblOffset];
1283:
1284: srcPixelOffset += srcPixelStride;
1285: dstPixelOffset += dstPixelStride;
1286: }
1287: }
1288: }
1289: }
1290:
1291: // short to byte
1292: private void lookup(int srcLineStride, int srcPixelStride,
1293: int[] srcBandOffsets, short[][] srcData, int width,
1294: int height, int bands, int dstLineStride,
1295: int dstPixelStride, int[] dstBandOffsets, byte[][] dstData,
1296: int[] tblOffsets, byte[][] tblData) {
1297: for (int b = 0; b < bands; b++) {
1298: short[] s = srcData[b];
1299: byte[] d = dstData[b];
1300: byte[] t = tblData[b];
1301:
1302: int srcLineOffset = srcBandOffsets[b];
1303: int dstLineOffset = dstBandOffsets[b];
1304: int tblOffset = tblOffsets[b];
1305:
1306: for (int h = 0; h < height; h++) {
1307: int srcPixelOffset = srcLineOffset;
1308: int dstPixelOffset = dstLineOffset;
1309:
1310: srcLineOffset += srcLineStride;
1311: dstLineOffset += dstLineStride;
1312:
1313: for (int w = 0; w < width; w++) {
1314: d[dstPixelOffset] = t[s[srcPixelOffset] - tblOffset];
1315:
1316: srcPixelOffset += srcPixelStride;
1317: dstPixelOffset += dstPixelStride;
1318: }
1319: }
1320: }
1321: }
1322:
1323: // int to byte
1324: private void lookup(int srcLineStride, int srcPixelStride,
1325: int[] srcBandOffsets, int[][] srcData, int width,
1326: int height, int bands, int dstLineStride,
1327: int dstPixelStride, int[] dstBandOffsets, byte[][] dstData,
1328: int[] tblOffsets, byte[][] tblData) {
1329: for (int b = 0; b < bands; b++) {
1330: int[] s = srcData[b];
1331: byte[] d = dstData[b];
1332: byte[] t = tblData[b];
1333:
1334: int srcLineOffset = srcBandOffsets[b];
1335: int dstLineOffset = dstBandOffsets[b];
1336: int tblOffset = tblOffsets[b];
1337:
1338: for (int h = 0; h < height; h++) {
1339: int srcPixelOffset = srcLineOffset;
1340: int dstPixelOffset = dstLineOffset;
1341:
1342: srcLineOffset += srcLineStride;
1343: dstLineOffset += dstLineStride;
1344:
1345: for (int w = 0; w < width; w++) {
1346: d[dstPixelOffset] = t[s[srcPixelOffset] - tblOffset];
1347:
1348: srcPixelOffset += srcPixelStride;
1349: dstPixelOffset += dstPixelStride;
1350: }
1351: }
1352: }
1353: }
1354:
1355: // byte to short or ushort
1356: private void lookup(int srcLineStride, int srcPixelStride,
1357: int[] srcBandOffsets, byte[][] srcData, int width,
1358: int height, int bands, int dstLineStride,
1359: int dstPixelStride, int[] dstBandOffsets,
1360: short[][] dstData, int[] tblOffsets, short[][] tblData) {
1361: for (int b = 0; b < bands; b++) {
1362: byte[] s = srcData[b];
1363: short[] d = dstData[b];
1364: short[] t = tblData[b];
1365:
1366: int srcLineOffset = srcBandOffsets[b];
1367: int dstLineOffset = dstBandOffsets[b];
1368: int tblOffset = tblOffsets[b];
1369:
1370: for (int h = 0; h < height; h++) {
1371: int srcPixelOffset = srcLineOffset;
1372: int dstPixelOffset = dstLineOffset;
1373:
1374: srcLineOffset += srcLineStride;
1375: dstLineOffset += dstLineStride;
1376:
1377: for (int w = 0; w < width; w++) {
1378: d[dstPixelOffset] = t[(s[srcPixelOffset] & 0xFF)
1379: - tblOffset];
1380:
1381: srcPixelOffset += srcPixelStride;
1382: dstPixelOffset += dstPixelStride;
1383: }
1384: }
1385: }
1386: }
1387:
1388: // ushort to short or ushort
1389: private void lookupU(int srcLineStride, int srcPixelStride,
1390: int[] srcBandOffsets, short[][] srcData, int width,
1391: int height, int bands, int dstLineStride,
1392: int dstPixelStride, int[] dstBandOffsets,
1393: short[][] dstData, int[] tblOffsets, short[][] tblData) {
1394: for (int b = 0; b < bands; b++) {
1395: short[] s = srcData[b];
1396: short[] d = dstData[b];
1397: short[] t = tblData[b];
1398:
1399: int srcLineOffset = srcBandOffsets[b];
1400: int dstLineOffset = dstBandOffsets[b];
1401: int tblOffset = tblOffsets[b];
1402:
1403: for (int h = 0; h < height; h++) {
1404: int srcPixelOffset = srcLineOffset;
1405: int dstPixelOffset = dstLineOffset;
1406:
1407: srcLineOffset += srcLineStride;
1408: dstLineOffset += dstLineStride;
1409:
1410: for (int w = 0; w < width; w++) {
1411: d[dstPixelOffset] = t[(s[srcPixelOffset] & 0xFFFF)
1412: - tblOffset];
1413:
1414: srcPixelOffset += srcPixelStride;
1415: dstPixelOffset += dstPixelStride;
1416: }
1417: }
1418: }
1419: }
1420:
1421: // short to short or ushort
1422: private void lookup(int srcLineStride, int srcPixelStride,
1423: int[] srcBandOffsets, short[][] srcData, int width,
1424: int height, int bands, int dstLineStride,
1425: int dstPixelStride, int[] dstBandOffsets,
1426: short[][] dstData, int[] tblOffsets, short[][] tblData) {
1427: for (int b = 0; b < bands; b++) {
1428: short[] s = srcData[b];
1429: short[] d = dstData[b];
1430: short[] t = tblData[b];
1431:
1432: int srcLineOffset = srcBandOffsets[b];
1433: int dstLineOffset = dstBandOffsets[b];
1434: int tblOffset = tblOffsets[b];
1435:
1436: for (int h = 0; h < height; h++) {
1437: int srcPixelOffset = srcLineOffset;
1438: int dstPixelOffset = dstLineOffset;
1439:
1440: srcLineOffset += srcLineStride;
1441: dstLineOffset += dstLineStride;
1442:
1443: for (int w = 0; w < width; w++) {
1444: d[dstPixelOffset] = t[s[srcPixelOffset] - tblOffset];
1445:
1446: srcPixelOffset += srcPixelStride;
1447: dstPixelOffset += dstPixelStride;
1448: }
1449: }
1450: }
1451: }
1452:
1453: // int to short or ushort
1454: private void lookup(int srcLineStride, int srcPixelStride,
1455: int[] srcBandOffsets, int[][] srcData, int width,
1456: int height, int bands, int dstLineStride,
1457: int dstPixelStride, int[] dstBandOffsets,
1458: short[][] dstData, int[] tblOffsets, short[][] tblData) {
1459: for (int b = 0; b < bands; b++) {
1460: int[] s = srcData[b];
1461: short[] d = dstData[b];
1462: short[] t = tblData[b];
1463:
1464: int srcLineOffset = srcBandOffsets[b];
1465: int dstLineOffset = dstBandOffsets[b];
1466: int tblOffset = tblOffsets[b];
1467:
1468: for (int h = 0; h < height; h++) {
1469: int srcPixelOffset = srcLineOffset;
1470: int dstPixelOffset = dstLineOffset;
1471:
1472: srcLineOffset += srcLineStride;
1473: dstLineOffset += dstLineStride;
1474:
1475: for (int w = 0; w < width; w++) {
1476: d[dstPixelOffset] = t[s[srcPixelOffset] - tblOffset];
1477:
1478: srcPixelOffset += srcPixelStride;
1479: dstPixelOffset += dstPixelStride;
1480: }
1481: }
1482: }
1483: }
1484:
1485: // byte to int
1486: private void lookup(int srcLineStride, int srcPixelStride,
1487: int[] srcBandOffsets, byte[][] srcData, int width,
1488: int height, int bands, int dstLineStride,
1489: int dstPixelStride, int[] dstBandOffsets, int[][] dstData,
1490: int[] tblOffsets, int[][] tblData) {
1491: if (tblData == null) {
1492: for (int b = 0; b < bands; b++) {
1493: byte[] s = srcData[b];
1494: int[] d = dstData[b];
1495:
1496: int srcLineOffset = srcBandOffsets[b];
1497: int dstLineOffset = dstBandOffsets[b];
1498:
1499: for (int h = 0; h < height; h++) {
1500: int srcPixelOffset = srcLineOffset;
1501: int dstPixelOffset = dstLineOffset;
1502:
1503: srcLineOffset += srcLineStride;
1504: dstLineOffset += dstLineStride;
1505:
1506: for (int w = 0; w < width; w++) {
1507: d[dstPixelOffset] = data.getElem(b,
1508: s[srcPixelOffset] & 0xFF);
1509:
1510: srcPixelOffset += srcPixelStride;
1511: dstPixelOffset += dstPixelStride;
1512: }
1513: }
1514: }
1515: } else {
1516: for (int b = 0; b < bands; b++) {
1517: byte[] s = srcData[b];
1518: int[] d = dstData[b];
1519: int[] t = tblData[b];
1520:
1521: int srcLineOffset = srcBandOffsets[b];
1522: int dstLineOffset = dstBandOffsets[b];
1523: int tblOffset = tblOffsets[b];
1524:
1525: for (int h = 0; h < height; h++) {
1526: int srcPixelOffset = srcLineOffset;
1527: int dstPixelOffset = dstLineOffset;
1528:
1529: srcLineOffset += srcLineStride;
1530: dstLineOffset += dstLineStride;
1531:
1532: for (int w = 0; w < width; w++) {
1533: d[dstPixelOffset] = t[(s[srcPixelOffset] & 0xFF)
1534: - tblOffset];
1535:
1536: srcPixelOffset += srcPixelStride;
1537: dstPixelOffset += dstPixelStride;
1538: }
1539: }
1540: }
1541: }
1542: }
1543:
1544: // ushort to int
1545: private void lookupU(int srcLineStride, int srcPixelStride,
1546: int[] srcBandOffsets, short[][] srcData, int width,
1547: int height, int bands, int dstLineStride,
1548: int dstPixelStride, int[] dstBandOffsets, int[][] dstData,
1549: int[] tblOffsets, int[][] tblData) {
1550: if (tblData == null) {
1551: for (int b = 0; b < bands; b++) {
1552: short[] s = srcData[b];
1553: int[] d = dstData[b];
1554:
1555: int srcLineOffset = srcBandOffsets[b];
1556: int dstLineOffset = dstBandOffsets[b];
1557:
1558: for (int h = 0; h < height; h++) {
1559: int srcPixelOffset = srcLineOffset;
1560: int dstPixelOffset = dstLineOffset;
1561:
1562: srcLineOffset += srcLineStride;
1563: dstLineOffset += dstLineStride;
1564:
1565: for (int w = 0; w < width; w++) {
1566: d[dstPixelOffset] = data.getElem(b,
1567: s[srcPixelOffset] & 0xFFFF);
1568:
1569: srcPixelOffset += srcPixelStride;
1570: dstPixelOffset += dstPixelStride;
1571: }
1572: }
1573: }
1574: } else {
1575: for (int b = 0; b < bands; b++) {
1576: short[] s = srcData[b];
1577: int[] d = dstData[b];
1578: int[] t = tblData[b];
1579:
1580: int srcLineOffset = srcBandOffsets[b];
1581: int dstLineOffset = dstBandOffsets[b];
1582: int tblOffset = tblOffsets[b];
1583:
1584: for (int h = 0; h < height; h++) {
1585: int srcPixelOffset = srcLineOffset;
1586: int dstPixelOffset = dstLineOffset;
1587:
1588: srcLineOffset += srcLineStride;
1589: dstLineOffset += dstLineStride;
1590:
1591: for (int w = 0; w < width; w++) {
1592: d[dstPixelOffset] = t[(s[srcPixelOffset] & 0xFFFF)
1593: - tblOffset];
1594:
1595: srcPixelOffset += srcPixelStride;
1596: dstPixelOffset += dstPixelStride;
1597: }
1598: }
1599: }
1600: }
1601: }
1602:
1603: // short to int
1604: private void lookup(int srcLineStride, int srcPixelStride,
1605: int[] srcBandOffsets, short[][] srcData, int width,
1606: int height, int bands, int dstLineStride,
1607: int dstPixelStride, int[] dstBandOffsets, int[][] dstData,
1608: int[] tblOffsets, int[][] tblData) {
1609: if (tblData == null) {
1610: for (int b = 0; b < bands; b++) {
1611: short[] s = srcData[b];
1612: int[] d = dstData[b];
1613:
1614: int srcLineOffset = srcBandOffsets[b];
1615: int dstLineOffset = dstBandOffsets[b];
1616:
1617: for (int h = 0; h < height; h++) {
1618: int srcPixelOffset = srcLineOffset;
1619: int dstPixelOffset = dstLineOffset;
1620:
1621: srcLineOffset += srcLineStride;
1622: dstLineOffset += dstLineStride;
1623:
1624: for (int w = 0; w < width; w++) {
1625: d[dstPixelOffset] = data.getElem(b,
1626: s[srcPixelOffset]);
1627:
1628: srcPixelOffset += srcPixelStride;
1629: dstPixelOffset += dstPixelStride;
1630: }
1631: }
1632: }
1633: } else {
1634: for (int b = 0; b < bands; b++) {
1635: short[] s = srcData[b];
1636: int[] d = dstData[b];
1637: int[] t = tblData[b];
1638:
1639: int srcLineOffset = srcBandOffsets[b];
1640: int dstLineOffset = dstBandOffsets[b];
1641: int tblOffset = tblOffsets[b];
1642:
1643: for (int h = 0; h < height; h++) {
1644: int srcPixelOffset = srcLineOffset;
1645: int dstPixelOffset = dstLineOffset;
1646:
1647: srcLineOffset += srcLineStride;
1648: dstLineOffset += dstLineStride;
1649:
1650: for (int w = 0; w < width; w++) {
1651: d[dstPixelOffset] = t[s[srcPixelOffset]
1652: - tblOffset];
1653:
1654: srcPixelOffset += srcPixelStride;
1655: dstPixelOffset += dstPixelStride;
1656: }
1657: }
1658: }
1659: }
1660: }
1661:
1662: // int to int
1663: private void lookup(int srcLineStride, int srcPixelStride,
1664: int[] srcBandOffsets, int[][] srcData, int width,
1665: int height, int bands, int dstLineStride,
1666: int dstPixelStride, int[] dstBandOffsets, int[][] dstData,
1667: int[] tblOffsets, int[][] tblData) {
1668: if (tblData == null) {
1669: for (int b = 0; b < bands; b++) {
1670: int[] s = srcData[b];
1671: int[] d = dstData[b];
1672:
1673: int srcLineOffset = srcBandOffsets[b];
1674: int dstLineOffset = dstBandOffsets[b];
1675:
1676: for (int h = 0; h < height; h++) {
1677: int srcPixelOffset = srcLineOffset;
1678: int dstPixelOffset = dstLineOffset;
1679:
1680: srcLineOffset += srcLineStride;
1681: dstLineOffset += dstLineStride;
1682:
1683: for (int w = 0; w < width; w++) {
1684: d[dstPixelOffset] = data.getElem(b,
1685: s[srcPixelOffset]);
1686:
1687: srcPixelOffset += srcPixelStride;
1688: dstPixelOffset += dstPixelStride;
1689: }
1690: }
1691: }
1692: } else {
1693: for (int b = 0; b < bands; b++) {
1694: int[] s = srcData[b];
1695: int[] d = dstData[b];
1696: int[] t = tblData[b];
1697:
1698: int srcLineOffset = srcBandOffsets[b];
1699: int dstLineOffset = dstBandOffsets[b];
1700: int tblOffset = tblOffsets[b];
1701:
1702: for (int h = 0; h < height; h++) {
1703: int srcPixelOffset = srcLineOffset;
1704: int dstPixelOffset = dstLineOffset;
1705:
1706: srcLineOffset += srcLineStride;
1707: dstLineOffset += dstLineStride;
1708:
1709: for (int w = 0; w < width; w++) {
1710: d[dstPixelOffset] = t[s[srcPixelOffset]
1711: - tblOffset];
1712:
1713: srcPixelOffset += srcPixelStride;
1714: dstPixelOffset += dstPixelStride;
1715: }
1716: }
1717: }
1718: }
1719: }
1720:
1721: // byte to float
1722: private void lookup(int srcLineStride, int srcPixelStride,
1723: int[] srcBandOffsets, byte[][] srcData, int width,
1724: int height, int bands, int dstLineStride,
1725: int dstPixelStride, int[] dstBandOffsets,
1726: float[][] dstData, int[] tblOffsets, float[][] tblData) {
1727: for (int b = 0; b < bands; b++) {
1728: byte[] s = srcData[b];
1729: float[] d = dstData[b];
1730: float[] t = tblData[b];
1731:
1732: int srcLineOffset = srcBandOffsets[b];
1733: int dstLineOffset = dstBandOffsets[b];
1734: int tblOffset = tblOffsets[b];
1735:
1736: for (int h = 0; h < height; h++) {
1737: int srcPixelOffset = srcLineOffset;
1738: int dstPixelOffset = dstLineOffset;
1739:
1740: srcLineOffset += srcLineStride;
1741: dstLineOffset += dstLineStride;
1742:
1743: for (int w = 0; w < width; w++) {
1744: d[dstPixelOffset] = t[(s[srcPixelOffset] & 0xFF)
1745: - tblOffset];
1746:
1747: srcPixelOffset += srcPixelStride;
1748: dstPixelOffset += dstPixelStride;
1749: }
1750: }
1751: }
1752: }
1753:
1754: // ushort to float
1755: private void lookupU(int srcLineStride, int srcPixelStride,
1756: int[] srcBandOffsets, short[][] srcData, int width,
1757: int height, int bands, int dstLineStride,
1758: int dstPixelStride, int[] dstBandOffsets,
1759: float[][] dstData, int[] tblOffsets, float[][] tblData) {
1760: for (int b = 0; b < bands; b++) {
1761: short[] s = srcData[b];
1762: float[] d = dstData[b];
1763: float[] t = tblData[b];
1764:
1765: int srcLineOffset = srcBandOffsets[b];
1766: int dstLineOffset = dstBandOffsets[b];
1767: int tblOffset = tblOffsets[b];
1768:
1769: for (int h = 0; h < height; h++) {
1770: int srcPixelOffset = srcLineOffset;
1771: int dstPixelOffset = dstLineOffset;
1772:
1773: srcLineOffset += srcLineStride;
1774: dstLineOffset += dstLineStride;
1775:
1776: for (int w = 0; w < width; w++) {
1777: d[dstPixelOffset] = t[(s[srcPixelOffset] & 0xFFFF)
1778: - tblOffset];
1779:
1780: srcPixelOffset += srcPixelStride;
1781: dstPixelOffset += dstPixelStride;
1782: }
1783: }
1784: }
1785: }
1786:
1787: // short to float
1788: private void lookup(int srcLineStride, int srcPixelStride,
1789: int[] srcBandOffsets, short[][] srcData, int width,
1790: int height, int bands, int dstLineStride,
1791: int dstPixelStride, int[] dstBandOffsets,
1792: float[][] dstData, int[] tblOffsets, float[][] tblData) {
1793: for (int b = 0; b < bands; b++) {
1794: short[] s = srcData[b];
1795: float[] d = dstData[b];
1796: float[] t = tblData[b];
1797:
1798: int srcLineOffset = srcBandOffsets[b];
1799: int dstLineOffset = dstBandOffsets[b];
1800: int tblOffset = tblOffsets[b];
1801:
1802: for (int h = 0; h < height; h++) {
1803: int srcPixelOffset = srcLineOffset;
1804: int dstPixelOffset = dstLineOffset;
1805:
1806: srcLineOffset += srcLineStride;
1807: dstLineOffset += dstLineStride;
1808:
1809: for (int w = 0; w < width; w++) {
1810: d[dstPixelOffset] = t[s[srcPixelOffset] - tblOffset];
1811:
1812: srcPixelOffset += srcPixelStride;
1813: dstPixelOffset += dstPixelStride;
1814: }
1815: }
1816: }
1817: }
1818:
1819: // int to float
1820: private void lookup(int srcLineStride, int srcPixelStride,
1821: int[] srcBandOffsets, int[][] srcData, int width,
1822: int height, int bands, int dstLineStride,
1823: int dstPixelStride, int[] dstBandOffsets,
1824: float[][] dstData, int[] tblOffsets, float[][] tblData) {
1825: for (int b = 0; b < bands; b++) {
1826: int[] s = srcData[b];
1827: float[] d = dstData[b];
1828: float[] t = tblData[b];
1829:
1830: int srcLineOffset = srcBandOffsets[b];
1831: int dstLineOffset = dstBandOffsets[b];
1832: int tblOffset = tblOffsets[b];
1833:
1834: for (int h = 0; h < height; h++) {
1835: int srcPixelOffset = srcLineOffset;
1836: int dstPixelOffset = dstLineOffset;
1837:
1838: srcLineOffset += srcLineStride;
1839: dstLineOffset += dstLineStride;
1840:
1841: for (int w = 0; w < width; w++) {
1842: d[dstPixelOffset] = t[s[srcPixelOffset] - tblOffset];
1843:
1844: srcPixelOffset += srcPixelStride;
1845: dstPixelOffset += dstPixelStride;
1846: }
1847: }
1848: }
1849: }
1850:
1851: // byte to double
1852: private void lookup(int srcLineStride, int srcPixelStride,
1853: int[] srcBandOffsets, byte[][] srcData, int width,
1854: int height, int bands, int dstLineStride,
1855: int dstPixelStride, int[] dstBandOffsets,
1856: double[][] dstData, int[] tblOffsets, double[][] tblData) {
1857: for (int b = 0; b < bands; b++) {
1858: byte[] s = srcData[b];
1859: double[] d = dstData[b];
1860: double[] t = tblData[b];
1861:
1862: int srcLineOffset = srcBandOffsets[b];
1863: int dstLineOffset = dstBandOffsets[b];
1864: int tblOffset = tblOffsets[b];
1865:
1866: for (int h = 0; h < height; h++) {
1867: int srcPixelOffset = srcLineOffset;
1868: int dstPixelOffset = dstLineOffset;
1869:
1870: srcLineOffset += srcLineStride;
1871: dstLineOffset += dstLineStride;
1872:
1873: for (int w = 0; w < width; w++) {
1874: d[dstPixelOffset] = t[(s[srcPixelOffset] & 0xFF)
1875: - tblOffset];
1876:
1877: srcPixelOffset += srcPixelStride;
1878: dstPixelOffset += dstPixelStride;
1879: }
1880: }
1881: }
1882: }
1883:
1884: // ushort to double
1885: private void lookupU(int srcLineStride, int srcPixelStride,
1886: int[] srcBandOffsets, short[][] srcData, int width,
1887: int height, int bands, int dstLineStride,
1888: int dstPixelStride, int[] dstBandOffsets,
1889: double[][] dstData, int[] tblOffsets, double[][] tblData) {
1890: for (int b = 0; b < bands; b++) {
1891: short[] s = srcData[b];
1892: double[] d = dstData[b];
1893: double[] t = tblData[b];
1894:
1895: int srcLineOffset = srcBandOffsets[b];
1896: int dstLineOffset = dstBandOffsets[b];
1897: int tblOffset = tblOffsets[b];
1898:
1899: for (int h = 0; h < height; h++) {
1900: int srcPixelOffset = srcLineOffset;
1901: int dstPixelOffset = dstLineOffset;
1902:
1903: srcLineOffset += srcLineStride;
1904: dstLineOffset += dstLineStride;
1905:
1906: for (int w = 0; w < width; w++) {
1907: d[dstPixelOffset] = t[(s[srcPixelOffset] & 0xFFFF)
1908: - tblOffset];
1909:
1910: srcPixelOffset += srcPixelStride;
1911: dstPixelOffset += dstPixelStride;
1912: }
1913: }
1914: }
1915: }
1916:
1917: // short to double
1918: private void lookup(int srcLineStride, int srcPixelStride,
1919: int[] srcBandOffsets, short[][] srcData, int width,
1920: int height, int bands, int dstLineStride,
1921: int dstPixelStride, int[] dstBandOffsets,
1922: double[][] dstData, int[] tblOffsets, double[][] tblData) {
1923: for (int b = 0; b < bands; b++) {
1924: short[] s = srcData[b];
1925: double[] d = dstData[b];
1926: double[] t = tblData[b];
1927:
1928: int srcLineOffset = srcBandOffsets[b];
1929: int dstLineOffset = dstBandOffsets[b];
1930: int tblOffset = tblOffsets[b];
1931:
1932: for (int h = 0; h < height; h++) {
1933: int srcPixelOffset = srcLineOffset;
1934: int dstPixelOffset = dstLineOffset;
1935:
1936: srcLineOffset += srcLineStride;
1937: dstLineOffset += dstLineStride;
1938:
1939: for (int w = 0; w < width; w++) {
1940: d[dstPixelOffset] = t[s[srcPixelOffset] - tblOffset];
1941:
1942: srcPixelOffset += srcPixelStride;
1943: dstPixelOffset += dstPixelStride;
1944: }
1945: }
1946: }
1947: }
1948:
1949: // int to double
1950: private void lookup(int srcLineStride, int srcPixelStride,
1951: int[] srcBandOffsets, int[][] srcData, int width,
1952: int height, int bands, int dstLineStride,
1953: int dstPixelStride, int[] dstBandOffsets,
1954: double[][] dstData, int[] tblOffsets, double[][] tblData) {
1955: for (int b = 0; b < bands; b++) {
1956: int[] s = srcData[b];
1957: double[] d = dstData[b];
1958: double[] t = tblData[b];
1959:
1960: int srcLineOffset = srcBandOffsets[b];
1961: int dstLineOffset = dstBandOffsets[b];
1962: int tblOffset = tblOffsets[b];
1963:
1964: for (int h = 0; h < height; h++) {
1965: int srcPixelOffset = srcLineOffset;
1966: int dstPixelOffset = dstLineOffset;
1967:
1968: srcLineOffset += srcLineStride;
1969: dstLineOffset += dstLineStride;
1970:
1971: for (int w = 0; w < width; w++) {
1972: d[dstPixelOffset] = t[s[srcPixelOffset] - tblOffset];
1973:
1974: srcPixelOffset += srcPixelStride;
1975: dstPixelOffset += dstPixelStride;
1976: }
1977: }
1978: }
1979: }
1980:
1981: /**
1982: * Determine which entry in the <code>LookupTableJAI</code> is closest
1983: * in Euclidean distance to the argument pixel.
1984: *
1985: * @param pixel The pixel the closest entry to which is to be found.
1986: *
1987: * @return the index of the closest entry. If the data array of the
1988: * lookup table is in the format data[numBands][numEntries], then the
1989: * value <i>v</i> for band <i>b</i> of the closest entry is
1990: * <pre>
1991: * v = data[b][index - lookup.getOffset()]
1992: * </pre>
1993: * where <i>index</i> is the returned value of this method.
1994: *
1995: * @throws IllegalArgumentException if pixel is null.
1996: */
1997: public int findNearestEntry(float[] pixel) {
1998:
1999: if (pixel == null) {
2000: throw new IllegalArgumentException(JaiI18N
2001: .getString("Generic0"));
2002: }
2003:
2004: int dataType = data.getDataType();
2005: int numBands = getNumBands();
2006: int numEntries = getNumEntries();
2007: int index = -1;
2008:
2009: if (dataType == DataBuffer.TYPE_BYTE) {
2010: byte buffer[][] = getByteData();
2011:
2012: // Find the distance to the first entry and set result to 0.
2013: float minDistance = 0.0F;
2014: index = 0;
2015: for (int b = 0; b < numBands; b++) {
2016: float delta = pixel[b] - (float) (buffer[b][0] & 0xff);
2017: minDistance += delta * delta;
2018: }
2019:
2020: // Find the distance to each entry and set the result to
2021: // the index which is closest to the argument.
2022: for (int i = 1; i < numEntries; i++) {
2023: float distance = 0.0F;
2024: for (int b = 0; b < numBands; b++) {
2025: float delta = pixel[b]
2026: - (float) (buffer[b][i] & 0xff);
2027: distance += delta * delta;
2028: }
2029:
2030: if (distance < minDistance) {
2031: minDistance = distance;
2032: index = i;
2033: }
2034: }
2035: } else if (dataType == DataBuffer.TYPE_SHORT) {
2036: short buffer[][] = getShortData();
2037:
2038: // Find the distance to the first entry and set result to 0.
2039: float minDistance = 0.0F;
2040: index = 0;
2041: for (int b = 0; b < numBands; b++) {
2042: float delta = pixel[b] - buffer[b][0];
2043: minDistance += delta * delta;
2044: }
2045:
2046: // Find the distance to each entry and set the result to
2047: // the index which is closest to the argument.
2048: for (int i = 1; i < numEntries; i++) {
2049: float distance = 0.0F;
2050: for (int b = 0; b < numBands; b++) {
2051: float delta = pixel[b] - buffer[b][i];
2052: distance += delta * delta;
2053: }
2054:
2055: if (distance < minDistance) {
2056: minDistance = distance;
2057: index = i;
2058: }
2059: }
2060: } else if (dataType == DataBuffer.TYPE_USHORT) {
2061: short buffer[][] = getShortData();
2062:
2063: // Find the distance to the first entry and set result to 0.
2064: float minDistance = 0.0F;
2065: index = 0;
2066: for (int b = 0; b < numBands; b++) {
2067: float delta = pixel[b]
2068: - (float) (buffer[b][0] & 0xffff);
2069: minDistance += delta * delta;
2070: }
2071:
2072: // Find the distance to each entry and set the result to
2073: // the index which is closest to the argument.
2074: for (int i = 1; i < numEntries; i++) {
2075: float distance = 0.0F;
2076: for (int b = 0; b < numBands; b++) {
2077: float delta = pixel[b]
2078: - (float) (buffer[b][i] & 0xffff);
2079: distance += delta * delta;
2080: }
2081:
2082: if (distance < minDistance) {
2083: minDistance = distance;
2084: index = i;
2085: }
2086: }
2087: } else if (dataType == DataBuffer.TYPE_INT) {
2088: int buffer[][] = getIntData();
2089:
2090: // Find the distance to the first entry and set result to 0.
2091: float minDistance = 0.0F;
2092: index = 0;
2093: for (int b = 0; b < numBands; b++) {
2094: float delta = pixel[b] - buffer[b][0];
2095: minDistance += delta * delta;
2096: }
2097:
2098: // Find the distance to each entry and set the result to
2099: // the index which is closest to the argument.
2100: for (int i = 1; i < numEntries; i++) {
2101: float distance = 0.0F;
2102: for (int b = 0; b < numBands; b++) {
2103: float delta = pixel[b] - buffer[b][i];
2104: distance += delta * delta;
2105: }
2106:
2107: if (distance < minDistance) {
2108: minDistance = distance;
2109: index = i;
2110: }
2111: }
2112: } else if (dataType == DataBuffer.TYPE_FLOAT) {
2113: float buffer[][] = getFloatData();
2114:
2115: // Find the distance to the first entry and set result to 0.
2116: float minDistance = 0.0F;
2117: index = 0;
2118: for (int b = 0; b < numBands; b++) {
2119: float delta = pixel[b] - buffer[b][0];
2120: minDistance += delta * delta;
2121: }
2122:
2123: // Find the distance to each entry and set the result to
2124: // the index which is closest to the argument.
2125: for (int i = 1; i < numEntries; i++) {
2126: float distance = 0.0F;
2127: for (int b = 0; b < numBands; b++) {
2128: float delta = pixel[b] - buffer[b][i];
2129: distance += delta * delta;
2130: }
2131:
2132: if (distance < minDistance) {
2133: minDistance = distance;
2134: index = i;
2135: }
2136: }
2137: } else if (dataType == DataBuffer.TYPE_DOUBLE) {
2138: double buffer[][] = getDoubleData();
2139:
2140: // Find the distance to the first entry and set result to 0.
2141: double minDistance = 0.0F;
2142: index = 0;
2143: for (int b = 0; b < numBands; b++) {
2144: double delta = pixel[b] - buffer[b][0];
2145: minDistance += delta * delta;
2146: }
2147:
2148: // Find the distance to each entry and set the result to
2149: // the index which is closest to the argument.
2150: for (int i = 1; i < numEntries; i++) {
2151: double distance = 0.0F;
2152: for (int b = 0; b < numBands; b++) {
2153: double delta = pixel[b] - buffer[b][i];
2154: distance += delta * delta;
2155: }
2156:
2157: if (distance < minDistance) {
2158: minDistance = distance;
2159: index = i;
2160: }
2161: }
2162: } else {
2163: // This can't happen since we control the type of data
2164: throw new RuntimeException(JaiI18N
2165: .getString("LookupTableJAI0"));
2166: }
2167:
2168: // Return the index of the closest color plus the offset of the
2169: // default band or -1 on error.
2170: return index == -1 ? index : index + getOffset();
2171: }
2172:
2173: /**
2174: * Serialize the <code>LookupTableJAI</code>.
2175: *
2176: * @param out The <code>ObjectOutputStream</code>.
2177: */
2178: private void writeObject(ObjectOutputStream out) throws IOException {
2179: out.defaultWriteObject();
2180: out.writeObject(SerializerFactory.getState(data));
2181: }
2182:
2183: /**
2184: * Deserialize the <code>LookupTableJAI</code>.
2185: *
2186: * @param in The <code>ObjectInputStream</code>.
2187: */
2188: private void readObject(ObjectInputStream in) throws IOException,
2189: ClassNotFoundException {
2190: in.defaultReadObject();
2191: Object object = in.readObject();
2192: SerializableState ss = (SerializableState) object;
2193: data = (DataBuffer) ss.getObject();
2194: }
2195:
2196: private void initOffsets(int nbands, int offset) {
2197: tableOffsets = new int[nbands];
2198: for (int i = 0; i < nbands; i++) {
2199: tableOffsets[i] = offset;
2200: }
2201: }
2202:
2203: private void initOffsets(int nbands, int[] offset) {
2204: tableOffsets = new int[nbands];
2205: for (int i = 0; i < nbands; i++) {
2206: tableOffsets[i] = offset[i];
2207: }
2208: }
2209:
2210: }
|