1 /* 2 * $RCSfile: LookupTableJAI.java,v $ 3 * 4 * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved. 5 * 6 * Use is subject to license terms. 7 * 8 * $Revision: 1.1 $ 9 * $Date: 2005/02/11 04:57:12 $ 10 * $State: Exp $ 11 */ 12 package com.lightcrafts.mediax.jai; 13 import java.awt.Rectangle; 14 import java.awt.Point; 15 import java.awt.image.DataBuffer; 16 import java.awt.image.DataBufferByte; 17 import java.awt.image.DataBufferInt; 18 import java.awt.image.DataBufferShort; 19 import java.awt.image.DataBufferUShort; 20 import java.awt.image.Raster; 21 import java.awt.image.SampleModel; 22 import java.awt.image.WritableRaster; 23 import java.io.IOException; 24 import java.io.ObjectInputStream; 25 import java.io.ObjectOutputStream; 26 import java.io.Serializable; 27 import com.lightcrafts.mediax.jai.remote.SerializableState; 28 import com.lightcrafts.mediax.jai.remote.SerializerFactory; 29 import com.lightcrafts.media.jai.util.DataBufferUtils; 30 31 /** 32 * A lookup table object associated with the "Lookup" operation. The 33 * "Lookup" operation is described in 34 * <code>com.lightcrafts.mediax.jai.operator.LookupDescriptor</code>. 35 * 36 * <p>This object represents a single- or multi-banded table of any 37 * JAI supported data type. A single- or multi-banded source image 38 * of integral data types is passed through the table and transformed 39 * into a single- or multi-banded destination image of either integral 40 * and floating point data types. 41 * 42 * <p>The table data may cover only a subrange of the legal range of the 43 * input data type. The subrange is selected by means of an offset parameter 44 * which is to be subtracted from the input value before indexing into the 45 * table array. When only a subranged table is used with a source image, it 46 * is up to the user to make certain that the source image does not have 47 * pixel values outside of the table range. Otherwise, 48 * an ArrayIndexOutOfBoundsException can occur. 49 * 50 * <p>The table data is saved by reference only. 51 * 52 * @see com.lightcrafts.mediax.jai.operator.LookupDescriptor 53 * 54 */ 55 public class LookupTableJAI extends Object implements Serializable { 56 57 /** The table data. */ 58 transient DataBuffer data; 59 60 /** The band offset values */ 61 private int[] tableOffsets; 62 63 /** 64 * Constructs a single-banded byte lookup table. The index offset is 0. 65 * 66 * @param data The single-banded byte data. 67 * @throws IllegalArgumentException if data is null. 68 */ LookupTableJAI(byte[] data)69 public LookupTableJAI(byte[] data) { 70 if ( data == null ) { 71 throw new IllegalArgumentException(JaiI18N.getString("Generic0")); 72 } 73 74 this.data = new DataBufferByte(data, data.length); 75 this.initOffsets(1, 0); 76 } 77 78 /** 79 * Constructs a single-banded byte lookup table with an index offset. 80 * 81 * @param data The single-banded byte data. 82 * @param offset The offset. 83 * @throws IllegalArgumentException if data is null. 84 */ LookupTableJAI(byte[] data, int offset)85 public LookupTableJAI(byte[] data, int offset) { 86 if ( data == null ) { 87 throw new IllegalArgumentException(JaiI18N.getString("Generic0")); 88 } 89 90 this.initOffsets(1, offset); 91 this.data = new DataBufferByte(data, data.length); 92 } 93 94 /** 95 * Constructs a multi-banded byte lookup table. The index offset for 96 * each band is 0. 97 * 98 * @param data The multi-banded byte data in [band][index] format. 99 * @throws IllegalArgumentException if data is null. 100 */ LookupTableJAI(byte[][] data)101 public LookupTableJAI(byte[][] data) { 102 if ( data == null ) { 103 throw new IllegalArgumentException(JaiI18N.getString("Generic0")); 104 } 105 106 this.initOffsets(data.length, 0); 107 this.data = new DataBufferByte(data, data[0].length); 108 } 109 110 /** 111 * Constructs a multi-banded byte lookup table where all bands have 112 * the same index offset. 113 * 114 * @param data The multi-banded byte data in [band][index] format. 115 * @param offset The common offset for all bands. 116 * @throws IllegalArgumentException if data is null. 117 */ LookupTableJAI(byte[][] data, int offset)118 public LookupTableJAI(byte[][] data, int offset) { 119 if ( data == null ) { 120 throw new IllegalArgumentException(JaiI18N.getString("Generic0")); 121 } 122 123 this.initOffsets(data.length, offset); 124 this.data = new DataBufferByte(data, data[0].length); 125 } 126 127 /** 128 * Constructs a multi-banded byte lookup table where each band has 129 * a different index offset. 130 * 131 * @param data The multi-banded byte data in [band][index] format. 132 * @param offsets The offsets for the bands. 133 * @throws IllegalArgumentException if data is null. 134 */ LookupTableJAI(byte[][] data, int[] offsets)135 public LookupTableJAI(byte[][] data, int[] offsets) { 136 if ( data == null ) { 137 throw new IllegalArgumentException(JaiI18N.getString("Generic0")); 138 } 139 140 this.initOffsets(data.length, offsets); 141 this.data = new DataBufferByte(data, data[0].length); 142 } 143 144 /** 145 * Constructs a single-banded short or unsigned short lookup table. 146 * The index offset is 0. 147 * 148 * @param data The single-banded short data. 149 * @param isUShort True if data type is DataBuffer.TYPE_USHORT; 150 * false if data type is DataBuffer.TYPE_SHORT. 151 * @throws IllegalArgumentException if data is null. 152 */ LookupTableJAI(short[] data, boolean isUShort)153 public LookupTableJAI(short[] data, boolean isUShort) { 154 if ( data == null ) { 155 throw new IllegalArgumentException(JaiI18N.getString("Generic0")); 156 } 157 158 this.initOffsets(1, 0); 159 if (isUShort) { 160 this.data = new DataBufferUShort(data, data.length); 161 } else { 162 this.data = new DataBufferShort(data, data.length); 163 } 164 } 165 166 /** 167 * Constructs a single-banded short or unsigned short lookup table with 168 * an index offset. 169 * 170 * @param data The single-banded short data. 171 * @param offset The offset. 172 * @param isUShort True if data type is DataBuffer.TYPE_USHORT; 173 * false if data type is DataBuffer.TYPE_SHORT. 174 * @throws IllegalArgumentException if data is null. 175 */ LookupTableJAI(short[] data, int offset, boolean isUShort)176 public LookupTableJAI(short[] data, int offset, boolean isUShort) { 177 if ( data == null ) { 178 throw new IllegalArgumentException(JaiI18N.getString("Generic0")); 179 } 180 181 this.initOffsets(1, offset); 182 if (isUShort) { 183 this.data = new DataBufferUShort(data, data.length); 184 } else { 185 this.data = new DataBufferShort(data, data.length); 186 } 187 } 188 189 /** 190 * Constructs a multi-banded short or unsigned short lookup table. 191 * The index offset for each band is 0. 192 * 193 * @param data The multi-banded short data in [band][index] format. 194 * @param isUShort True if data type is DataBuffer.TYPE_USHORT; 195 * false if data type is DataBuffer.TYPE_SHORT. 196 * @throws IllegalArgumentException if data is null. 197 */ LookupTableJAI(short[][] data, boolean isUShort)198 public LookupTableJAI(short[][] data, boolean isUShort) { 199 if ( data == null ) { 200 throw new IllegalArgumentException(JaiI18N.getString("Generic0")); 201 } 202 203 this.initOffsets(data.length, 0); 204 if (isUShort) { 205 this.data = new DataBufferUShort(data, data[0].length); 206 } else { 207 this.data = new DataBufferShort(data, data[0].length); 208 } 209 } 210 211 /** 212 * Constructs a multi-banded short or unsigned short lookup table where all 213 * bands have the same index offset. 214 * 215 * @param data The multi-banded short data in [band][index] format. 216 * @param offset The common offset for all bands. 217 * @param isUShort True if data type is DataBuffer.TYPE_USHORT; 218 * false if data type is DataBuffer.TYPE_SHORT. 219 * @throws IllegalArgumentException if data is null. 220 */ LookupTableJAI(short[][] data, int offset, boolean isUShort)221 public LookupTableJAI(short[][] data, int offset, boolean isUShort) { 222 if ( data == null ) { 223 throw new IllegalArgumentException(JaiI18N.getString("Generic0")); 224 } 225 226 this.initOffsets(data.length, offset); 227 if (isUShort) { 228 this.data = new DataBufferUShort(data, data[0].length); 229 } else { 230 this.data = new DataBufferShort(data, data[0].length); 231 } 232 } 233 234 /** 235 * Constructs a multi-banded short or unsigned short lookup table where 236 * each band has a different index offset. 237 * 238 * @param data The multi-banded short data in [band][index] format. 239 * @param offsets The offsets for the bands. 240 * @param isUShort True if data type is DataBuffer.TYPE_USHORT; 241 * false if data type is DataBuffer.TYPE_SHORT. 242 * @throws IllegalArgumentException if data is null. 243 */ LookupTableJAI(short[][] data, int[] offsets, boolean isUShort)244 public LookupTableJAI(short[][] data, int[] offsets, boolean isUShort) { 245 if ( data == null ) { 246 throw new IllegalArgumentException(JaiI18N.getString("Generic0")); 247 } 248 249 this.initOffsets(data.length, offsets); 250 251 if (isUShort) { 252 this.data = new DataBufferUShort(data, data[0].length); 253 } else { 254 this.data = new DataBufferShort(data, data[0].length); 255 } 256 } 257 258 /** 259 * Constructs a single-banded int lookup table. The index offset is 0. 260 * 261 * @param data The single-banded int data. 262 * @throws IllegalArgumentException if data is null. 263 */ LookupTableJAI(int[] data)264 public LookupTableJAI(int[] data) { 265 if ( data == null ) { 266 throw new IllegalArgumentException(JaiI18N.getString("Generic0")); 267 } 268 269 this.initOffsets(1, 0); 270 this.data = new DataBufferInt(data, data.length); 271 } 272 273 /** 274 * Constructs a single-banded int lookup table with an index offset. 275 * 276 * @param data The single-banded int data. 277 * @param offset The offset. 278 * @throws IllegalArgumentException if data is null. 279 */ LookupTableJAI(int[] data, int offset)280 public LookupTableJAI(int[] data, int offset) { 281 if ( data == null ) { 282 throw new IllegalArgumentException(JaiI18N.getString("Generic0")); 283 } 284 285 this.initOffsets(1, offset); 286 this.data = new DataBufferInt(data, data.length); 287 } 288 289 /** 290 * Constructs a multi-banded int lookup table. The index offset for 291 * each band is 0. 292 * 293 * @param data The multi-banded int data in [band][index] format. 294 * @throws IllegalArgumentException if data is null. 295 */ LookupTableJAI(int[][] data)296 public LookupTableJAI(int[][] data) { 297 if ( data == null ) { 298 throw new IllegalArgumentException(JaiI18N.getString("Generic0")); 299 } 300 301 this.initOffsets(data.length, 0); 302 this.data = new DataBufferInt(data, data[0].length); 303 } 304 305 /** 306 * Constructs a multi-banded int lookup table where all bands have 307 * the same index offset. 308 * 309 * @param data The multi-banded int data in [band][index] format. 310 * @param offset The common offset for all bands. 311 * @throws IllegalArgumentException if data is null. 312 */ LookupTableJAI(int[][] data, int offset)313 public LookupTableJAI(int[][] data, int offset) { 314 if ( data == null ) { 315 throw new IllegalArgumentException(JaiI18N.getString("Generic0")); 316 } 317 318 this.initOffsets(data.length, offset); 319 this.data = new DataBufferInt(data, data[0].length); 320 } 321 322 /** 323 * Constructs a multi-banded int lookup table where each band has 324 * a different index offset. 325 * 326 * @param data The multi-banded int data in [band][index] format. 327 * @param offsets The offsets for the bands. 328 * @throws IllegalArgumentException if data is null. 329 */ LookupTableJAI(int[][] data, int[] offsets)330 public LookupTableJAI(int[][] data, int[] offsets) { 331 if ( data == null ) { 332 throw new IllegalArgumentException(JaiI18N.getString("Generic0")); 333 } 334 335 this.initOffsets(data.length, offsets); 336 this.data = new DataBufferInt(data, data[0].length); 337 } 338 339 /** 340 * Constructs a single-banded float lookup table. The index offset is 0. 341 * 342 * @param data The single-banded float data. 343 * @throws IllegalArgumentException if data is null. 344 */ LookupTableJAI(float[] data)345 public LookupTableJAI(float[] data) { 346 if ( data == null ) { 347 throw new IllegalArgumentException(JaiI18N.getString("Generic0")); 348 } 349 350 this.initOffsets(1, 0); 351 this.data = DataBufferUtils.createDataBufferFloat(data, data.length); 352 } 353 354 /** 355 * Constructs a single-banded float lookup table with an index offset. 356 * 357 * @param data The single-banded float data. 358 * @param offset The offset. 359 * @throws IllegalArgumentException if data is null. 360 */ LookupTableJAI(float[] data, int offset)361 public LookupTableJAI(float[] data, int offset) { 362 if ( data == null ) { 363 throw new IllegalArgumentException(JaiI18N.getString("Generic0")); 364 } 365 366 this.initOffsets(1, offset); 367 this.data = DataBufferUtils.createDataBufferFloat(data, data.length); 368 } 369 370 /** 371 * Constructs a multi-banded float lookup table. The index offset for 372 * each band is 0. 373 * 374 * @param data The multi-banded float data in [band][index] format. 375 * @throws IllegalArgumentException if data is null. 376 */ LookupTableJAI(float[][] data)377 public LookupTableJAI(float[][] data) { 378 if ( data == null ) { 379 throw new IllegalArgumentException(JaiI18N.getString("Generic0")); 380 } 381 382 this.initOffsets(data.length, 0); 383 this.data = DataBufferUtils.createDataBufferFloat(data, data[0].length); 384 } 385 386 /** 387 * Constructs a multi-banded float lookup table where all bands have 388 * the same index offset. 389 * 390 * @param data The multi-banded float data in [band][index] format. 391 * @param offset The common offset for all bands. 392 * @throws IllegalArgumentException if data is null. 393 */ LookupTableJAI(float[][] data, int offset)394 public LookupTableJAI(float[][] data, int offset) { 395 if ( data == null ) { 396 throw new IllegalArgumentException(JaiI18N.getString("Generic0")); 397 } 398 399 this.initOffsets(data.length, offset); 400 this.data = DataBufferUtils.createDataBufferFloat(data, data[0].length); 401 } 402 403 /** 404 * Constructs a multi-banded float lookup table where each band has 405 * a different index offset. 406 * 407 * @param data The multi-banded float data in [band][index] format. 408 * @param offsets The offsets for the bands. 409 * @throws IllegalArgumentException if data is null. 410 */ LookupTableJAI(float[][] data, int[] offsets)411 public LookupTableJAI(float[][] data, int[] offsets) { 412 if ( data == null ) { 413 throw new IllegalArgumentException(JaiI18N.getString("Generic0")); 414 } 415 416 this.initOffsets(data.length, offsets); 417 this.data = DataBufferUtils.createDataBufferFloat(data, data[0].length); 418 } 419 420 /** 421 * Constructs a single-banded double lookup table. The index offset is 0. 422 * 423 * @param data The single-banded double data. 424 * @throws IllegalArgumentException if data is null. 425 */ LookupTableJAI(double[] data)426 public LookupTableJAI(double[] data) { 427 if ( data == null ) { 428 throw new IllegalArgumentException(JaiI18N.getString("Generic0")); 429 } 430 431 this.initOffsets(1, 0); 432 this.data = DataBufferUtils.createDataBufferDouble(data, data.length); 433 } 434 435 /** 436 * Constructs a single-banded double lookup table with an index offset. 437 * 438 * @param data The single-banded double data. 439 * @param offset The offset. 440 * @throws IllegalArgumentException if data is null. 441 */ LookupTableJAI(double[] data, int offset)442 public LookupTableJAI(double[] data, int offset) { 443 if ( data == null ) { 444 throw new IllegalArgumentException(JaiI18N.getString("Generic0")); 445 } 446 447 this.initOffsets(1, offset); 448 this.data = DataBufferUtils.createDataBufferDouble(data, data.length); 449 } 450 451 /** 452 * Constructs a multi-banded double lookup table. The index offset for 453 * each band is 0. 454 * 455 * @param data The multi-banded double data in [band][index] format. 456 * @throws IllegalArgumentException if data is null. 457 */ LookupTableJAI(double[][] data)458 public LookupTableJAI(double[][] data) { 459 if ( data == null ) { 460 throw new IllegalArgumentException(JaiI18N.getString("Generic0")); 461 } 462 463 this.initOffsets(data.length, 0); 464 this.data = DataBufferUtils.createDataBufferDouble(data, data[0].length); 465 } 466 467 /** 468 * Constructs a multi-banded double lookup table where all bands have 469 * the same index offset. 470 * 471 * @param data The multi-banded double data in [band][index] format. 472 * @param offset The common offset for all bands. 473 * @throws IllegalArgumentException if data is null. 474 */ LookupTableJAI(double[][] data, int offset)475 public LookupTableJAI(double[][] data, int offset) { 476 if ( data == null ) { 477 throw new IllegalArgumentException(JaiI18N.getString("Generic0")); 478 } 479 480 this.initOffsets(data.length, offset); 481 this.data = DataBufferUtils.createDataBufferDouble(data, data[0].length); 482 } 483 484 /** 485 * Constructs a multi-banded double lookup table where each band has 486 * a different index offset. 487 * 488 * @param data The multi-banded double data in [band][index] format. 489 * @param offsets The offsets for the bands. 490 * @throws IllegalArgumentException if data is null. 491 */ LookupTableJAI(double[][] data, int[] offsets)492 public LookupTableJAI(double[][] data, int[] offsets) { 493 if ( data == null ) { 494 throw new IllegalArgumentException(JaiI18N.getString("Generic0")); 495 } 496 497 this.initOffsets(data.length, offsets); 498 this.data = DataBufferUtils.createDataBufferDouble(data, data[0].length); 499 } 500 501 /** 502 * Returns the table data as a DataBuffer. 503 */ getData()504 public DataBuffer getData() { 505 return data; 506 } 507 508 /** 509 * Returns the byte table data in array format, or null if the 510 * table's data type is not byte. 511 */ getByteData()512 public byte[][] getByteData() { 513 return data instanceof DataBufferByte ? 514 ((DataBufferByte)data).getBankData() : null; 515 } 516 517 /** 518 * Returns the byte table data of a specific band in array format, 519 * or null if the table's data type is not byte. 520 */ getByteData(int band)521 public byte[] getByteData(int band) { 522 return data instanceof DataBufferByte ? 523 ((DataBufferByte)data).getData(band) : null; 524 } 525 526 /** 527 * Returns the short table data in array format, or null if the 528 * table's data type is not short. This includes both signed and 529 * unsigned short table data. 530 * 531 */ getShortData()532 public short[][] getShortData() { 533 if (data instanceof DataBufferUShort) { 534 return ((DataBufferUShort)data).getBankData(); 535 } else if (data instanceof DataBufferShort) { 536 return ((DataBufferShort)data).getBankData(); 537 } else { 538 return null; 539 } 540 } 541 542 /** 543 * Returns the short table data of a specific band in array format, 544 * or null if the table's data type is not short. 545 * 546 */ getShortData(int band)547 public short[] getShortData(int band) { 548 if (data instanceof DataBufferUShort) { 549 return ((DataBufferUShort)data).getData(band); 550 } else if (data instanceof DataBufferShort) { 551 return ((DataBufferShort)data).getData(band); 552 } else { 553 return null; 554 } 555 } 556 557 /** 558 * Returns the integer table data in array format, or null if the 559 * table's data type is not int. 560 * 561 */ getIntData()562 public int[][] getIntData() { 563 return data instanceof DataBufferInt ? 564 ((DataBufferInt)data).getBankData() : null; 565 } 566 567 /** 568 * Returns the integer table data of a specific band in array format, 569 * or null if table's data type is not int. 570 * 571 */ getIntData(int band)572 public int[] getIntData(int band) { 573 return data instanceof DataBufferInt ? 574 ((DataBufferInt)data).getData(band) : null; 575 } 576 577 /** 578 * Returns the float table data in array format, or null if the 579 * table's data type is not float. 580 * 581 */ getFloatData()582 public float[][] getFloatData() { 583 return data.getDataType() == DataBuffer.TYPE_FLOAT ? 584 DataBufferUtils.getBankDataFloat(data) : null; 585 } 586 587 /** 588 * Returns the float table data of a specific band in array format, 589 * or null if table's data type is not float. 590 * 591 */ getFloatData(int band)592 public float[] getFloatData(int band) { 593 return data.getDataType() == DataBuffer.TYPE_FLOAT ? 594 DataBufferUtils.getDataFloat(data, band) : null; 595 } 596 597 /** 598 * Returns the double table data in array format, or null if the 599 * table's data type is not double. 600 * 601 */ getDoubleData()602 public double[][] getDoubleData() { 603 return data.getDataType() == DataBuffer.TYPE_DOUBLE ? 604 DataBufferUtils.getBankDataDouble(data) : null; 605 } 606 607 /** 608 * Returns the double table data of a specific band in array format, 609 * or null if table's data type is not double. 610 * 611 */ getDoubleData(int band)612 public double[] getDoubleData(int band) { 613 return data.getDataType() == DataBuffer.TYPE_DOUBLE ? 614 DataBufferUtils.getDataDouble(data, band) : null; 615 } 616 617 /** Returns the index offsets of entry 0 for all bands. */ getOffsets()618 public int[] getOffsets() { 619 return tableOffsets; 620 } 621 622 /** 623 * Returns the index offset of entry 0 for the default band. 624 * 625 */ getOffset()626 public int getOffset() { 627 return tableOffsets[0]; 628 } 629 630 /** 631 * Returns the index offset of entry 0 for a specific band. 632 * 633 */ getOffset(int band)634 public int getOffset(int band) { 635 return tableOffsets[band]; 636 } 637 638 /** Returns the number of bands of the table. */ getNumBands()639 public int getNumBands() { 640 return data.getNumBanks(); 641 } 642 643 /** 644 * Returns the number of entries per band of the table. 645 * 646 */ getNumEntries()647 public int getNumEntries() { 648 return data.getSize(); 649 } 650 651 /** Returns the data type of the table data. 652 * 653 */ getDataType()654 public int getDataType() { 655 return data.getDataType(); 656 } 657 658 /** 659 * Returns the number of bands of the destination image, based on 660 * the number of bands of the source image and lookup table. 661 * 662 * @param srcNumBands The number of bands of the source image. 663 * @return the number of bands in destination image. 664 */ getDestNumBands(int srcNumBands)665 public int getDestNumBands(int srcNumBands) { 666 int tblNumBands = getNumBands(); 667 return srcNumBands == 1 ? tblNumBands : srcNumBands; 668 } 669 670 /** 671 * Returns a <code>SampleModel</code> suitable for holding the output 672 * of a lookup operation on the source data described by a given 673 * SampleModel with this table. The width and height of the destination 674 * SampleModel are the same as that of the source. This method will 675 * return null if the source SampleModel has a non-integral data type. 676 * 677 * @param srcSampleModel The SampleModel of the source image. 678 * 679 * @throws IllegalArgumentException if srcSampleModel is null. 680 * @return sampleModel suitable for the destination image. 681 */ getDestSampleModel(SampleModel srcSampleModel)682 public SampleModel getDestSampleModel(SampleModel srcSampleModel) { 683 if ( srcSampleModel == null ) { 684 throw new IllegalArgumentException(JaiI18N.getString("Generic0")); 685 } 686 687 return getDestSampleModel(srcSampleModel, 688 srcSampleModel.getWidth(), 689 srcSampleModel.getHeight()); 690 } 691 692 /** 693 * Returns a <code>SampleModel</code> suitable for holding the output 694 * of a lookup operation on the source data described by a given 695 * SampleModel with this table. This method will return null if the 696 * source SampleModel has a non-integral data type. 697 * 698 * @param srcSampleModel The SampleModel of the source image. 699 * @param width The width of the destination SampleModel. 700 * @param height The height of the destination SampleModel. 701 * 702 * @throws IllegalArgumentException if srcSampleModel is null. 703 * @return sampleModel suitable for the destination image. 704 */ getDestSampleModel(SampleModel srcSampleModel, int width, int height)705 public SampleModel getDestSampleModel(SampleModel srcSampleModel, 706 int width, 707 int height) { 708 if ( srcSampleModel == null ) { 709 throw new IllegalArgumentException(JaiI18N.getString("Generic0")); 710 } 711 712 if (!isIntegralDataType(srcSampleModel)) { 713 return null; // source has non-integral data type 714 } 715 716 return RasterFactory.createComponentSampleModel(srcSampleModel, 717 getDataType(), width, height, 718 getDestNumBands(srcSampleModel.getNumBands())); 719 } 720 721 /** 722 * Validates data type. Returns true if it's one of the integral 723 * data types; false otherwise. 724 * 725 * @throws IllegalArgumentException if sampleModel is null. 726 */ isIntegralDataType(SampleModel sampleModel)727 public boolean isIntegralDataType(SampleModel sampleModel) { 728 if ( sampleModel == null ) { 729 throw new IllegalArgumentException(JaiI18N.getString("Generic0")); 730 } 731 732 return isIntegralDataType(sampleModel.getTransferType()); 733 } 734 735 /** 736 * Returns <code>true</code> if the specified data type is 737 * an integral data type, such as byte, ushort, short, or int. 738 */ isIntegralDataType(int dataType)739 public boolean isIntegralDataType(int dataType) { 740 if ((dataType == DataBuffer.TYPE_BYTE) || 741 (dataType == DataBuffer.TYPE_USHORT) || 742 (dataType == DataBuffer.TYPE_SHORT) || 743 (dataType == DataBuffer.TYPE_INT)){ 744 return true; 745 } else { 746 return false; 747 } 748 } 749 750 /** 751 * Performs lookup on a given value belonging to a given source 752 * band, and returns the result as an int. 753 * 754 * @param band The source band the value is from. 755 * @param value The source value to be placed through the lookup table. 756 */ lookup(int band, int value)757 public int lookup(int band, int value) { 758 return data.getElem(band, value-tableOffsets[band]); 759 } 760 761 /** 762 * Performs lookup on a given value belonging to a given source 763 * band, and returns the result as a float. 764 * 765 * @param band The source band the value is from. 766 * @param value The source value to be placed through the lookup table. 767 */ lookupFloat(int band, int value)768 public float lookupFloat(int band, int value) { 769 return data.getElemFloat(band, value-tableOffsets[band]); 770 } 771 772 /** 773 * Performs lookup on a given value belonging to a given source 774 * band, and returns the result as a double. 775 * 776 * @param band The source band the value is from. 777 * @param value The source value to be placed through the lookup table. 778 */ lookupDouble(int band, int value)779 public double lookupDouble(int band, int value) { 780 return data.getElemDouble(band, value-tableOffsets[band]); 781 } 782 783 /** 784 * Performs table lookup in place on a given WritableRaster. The 785 * The lookup operation must preserve the data type and 786 * SampleModel of the source. A reference to the supplied 787 * WritableRaster will be returned. 788 * 789 * @throws IllegalArgumentException if the src is null. 790 * @throws IllegalArgumentException if the source's SampleModel 791 * is not of integral type. 792 * @throws IllegalArgumentException if the lookup operation would 793 * result in a change in the data type or number of bands 794 * of the Raster. 795 */ lookup(WritableRaster src)796 public WritableRaster lookup(WritableRaster src) { 797 if ( src == null ) { 798 throw new IllegalArgumentException(JaiI18N.getString("Generic0")); 799 } 800 801 return lookup(src, src, src.getBounds()); 802 } 803 804 /** 805 * Performs table lookup on a source Raster, writing the result 806 * into a supplied WritableRaster. The destination must have a 807 * data type and SampleModel appropriate to the results of the 808 * lookup operation. The table lookup operation is performed 809 * within a specified rectangle. 810 * 811 * <p> The <code>dst</code> argument may be null, in which case a new 812 * WritableRaster is created using the appropriate SampleModel. 813 * 814 * <p> The rectangle of interest may be null, in which case the 815 * operation will be performed on the intersection of the source 816 * and destination bounding rectangles. 817 * 818 * @param src A Raster containing the source pixel data. 819 * @param dst The WritableRaster to be computed, or null. 820 * If supplied, its data type and number of bands must 821 * be suitable for the source and lookup table. 822 * @param rect The rectangle within the tile to be computed. 823 * If rect is null, the intersection of the source and 824 * destination bounds will be used. Otherwise, it 825 * will be clipped to the intersection of the source 826 * and destination bounds. 827 * @return A reference to the supplied WritableRaster, or to a 828 * new WritableRaster if the supplied one was null. 829 * 830 * @throws IllegalArgumentException if the source is null. 831 * @throws IllegalArgumentException if the source's SampleModel 832 * is not of integral type. 833 * @throws IllegalArgumentException if the destination's data type 834 * or number of bands differ from those returned by 835 * getDataType() and getDestNumBands(). 836 */ lookup(Raster src, WritableRaster dst, Rectangle rect)837 public WritableRaster lookup(Raster src, 838 WritableRaster dst, 839 Rectangle rect) { 840 // Validate source. 841 if (src == null) { 842 throw 843 new IllegalArgumentException(JaiI18N.getString("LookupTableJAI1")); 844 } 845 846 SampleModel srcSampleModel = src.getSampleModel(); 847 if (!isIntegralDataType(srcSampleModel)) { 848 throw 849 new IllegalArgumentException(JaiI18N.getString("LookupTableJAI2")); 850 } 851 852 // Validate rectangle. 853 if (rect == null) { 854 rect = src.getBounds(); 855 } else { 856 rect = rect.intersection(src.getBounds()); 857 } 858 859 if (dst != null) { 860 rect = rect.intersection(dst.getBounds()); 861 } 862 863 // Validate destination. 864 SampleModel dstSampleModel; 865 if (dst == null) { // create dst according to table 866 dstSampleModel = getDestSampleModel(srcSampleModel, 867 rect.width, rect.height); 868 dst = 869 RasterFactory.createWritableRaster(dstSampleModel, 870 new Point(rect.x, rect.y)); 871 } else { 872 dstSampleModel = dst.getSampleModel(); 873 874 if (dstSampleModel.getTransferType() != getDataType() || 875 dstSampleModel.getNumBands() != 876 getDestNumBands(srcSampleModel.getNumBands())) { 877 throw new 878 IllegalArgumentException(JaiI18N.getString("LookupTableJAI3")); 879 } 880 } 881 882 // Add bit support? 883 int sTagID = RasterAccessor.findCompatibleTag(null, srcSampleModel); 884 int dTagID = RasterAccessor.findCompatibleTag(null, dstSampleModel); 885 886 RasterFormatTag sTag = new RasterFormatTag(srcSampleModel,sTagID); 887 RasterFormatTag dTag = new RasterFormatTag(dstSampleModel,dTagID); 888 889 RasterAccessor s = new RasterAccessor(src, rect, sTag, null); 890 RasterAccessor d = new RasterAccessor(dst, rect, dTag, null); 891 892 int srcNumBands = s.getNumBands(); 893 int srcDataType = s.getDataType(); 894 895 int tblNumBands = getNumBands(); 896 int tblDataType = getDataType(); 897 898 int dstWidth = d.getWidth(); 899 int dstHeight = d.getHeight(); 900 int dstNumBands = d.getNumBands(); 901 int dstDataType = d.getDataType(); 902 903 // Source information. 904 int srcLineStride = s.getScanlineStride(); 905 int srcPixelStride = s.getPixelStride(); 906 int[] srcBandOffsets = s.getBandOffsets(); 907 908 byte[][] bSrcData = s.getByteDataArrays(); 909 short[][] sSrcData = s.getShortDataArrays(); 910 int[][] iSrcData = s.getIntDataArrays(); 911 912 if (srcNumBands < dstNumBands) { 913 int offset0 = srcBandOffsets[0]; 914 srcBandOffsets = new int[dstNumBands]; 915 for (int i = 0; i < dstNumBands; i++) { 916 srcBandOffsets[i] = offset0; 917 } 918 919 switch (srcDataType) { 920 case DataBuffer.TYPE_BYTE: 921 byte[] bData0 = bSrcData[0]; 922 bSrcData = new byte[dstNumBands][]; 923 for (int i = 0; i < dstNumBands; i++) { 924 bSrcData[i] = bData0; 925 } 926 break; 927 case DataBuffer.TYPE_USHORT: 928 case DataBuffer.TYPE_SHORT: 929 short[] sData0 = sSrcData[0]; 930 sSrcData = new short[dstNumBands][]; 931 for (int i = 0; i < dstNumBands; i++) { 932 sSrcData[i] = sData0; 933 } 934 break; 935 case DataBuffer.TYPE_INT: 936 int[] iData0 = iSrcData[0]; 937 iSrcData = new int[dstNumBands][]; 938 for (int i = 0; i < dstNumBands; i++) { 939 iSrcData[i] = iData0; 940 } 941 break; 942 } 943 } 944 945 // Table information. 946 int[] tblOffsets = getOffsets(); 947 948 byte[][] bTblData = getByteData(); 949 short[][] sTblData = getShortData(); 950 int[][] iTblData = getIntData(); 951 float[][] fTblData = getFloatData(); 952 double[][] dTblData = getDoubleData(); 953 954 if (tblNumBands < dstNumBands) { 955 int offset0 = tblOffsets[0]; 956 tblOffsets = new int[dstNumBands]; 957 for (int i = 0; i < dstNumBands; i++) { 958 tblOffsets[i] = offset0; 959 } 960 961 switch (tblDataType) { 962 case DataBuffer.TYPE_BYTE: 963 byte[] bData0 = bTblData[0]; 964 bTblData = new byte[dstNumBands][]; 965 for (int i = 0; i < dstNumBands; i++) { 966 bTblData[i] = bData0; 967 } 968 break; 969 case DataBuffer.TYPE_USHORT: 970 case DataBuffer.TYPE_SHORT: 971 short[] sData0 = sTblData[0]; 972 sTblData = new short[dstNumBands][]; 973 for (int i = 0; i < dstNumBands; i++) { 974 sTblData[i] = sData0; 975 } 976 break; 977 case DataBuffer.TYPE_INT: 978 int[] iData0 = iTblData[0]; 979 iTblData = new int[dstNumBands][]; 980 for (int i = 0; i < dstNumBands; i++) { 981 iTblData[i] = iData0; 982 } 983 break; 984 case DataBuffer.TYPE_FLOAT: 985 float[] fData0 = fTblData[0]; 986 fTblData = new float[dstNumBands][]; 987 for (int i = 0; i < dstNumBands; i++) { 988 fTblData[i] = fData0; 989 } 990 break; 991 case DataBuffer.TYPE_DOUBLE: 992 double[] dData0 = dTblData[0]; 993 dTblData = new double[dstNumBands][]; 994 for (int i = 0; i < dstNumBands; i++) { 995 dTblData[i] = dData0; 996 } 997 } 998 } 999 1000 // Destination information. 1001 int dstLineStride = d.getScanlineStride(); 1002 int dstPixelStride = d.getPixelStride(); 1003 int[] dstBandOffsets = d.getBandOffsets(); 1004 1005 byte[][] bDstData = d.getByteDataArrays(); 1006 short[][] sDstData = d.getShortDataArrays(); 1007 int[][] iDstData = d.getIntDataArrays(); 1008 float[][] fDstData = d.getFloatDataArrays(); 1009 double[][] dDstData = d.getDoubleDataArrays(); 1010 1011 switch (dstDataType) { 1012 case DataBuffer.TYPE_BYTE: 1013 switch (srcDataType) { 1014 case DataBuffer.TYPE_BYTE: 1015 lookup(srcLineStride, srcPixelStride, 1016 srcBandOffsets, bSrcData, 1017 dstWidth, dstHeight, dstNumBands, 1018 dstLineStride, dstPixelStride, 1019 dstBandOffsets, bDstData, 1020 tblOffsets, bTblData); 1021 break; 1022 1023 case DataBuffer.TYPE_USHORT: 1024 lookupU(srcLineStride, srcPixelStride, 1025 srcBandOffsets, sSrcData, 1026 dstWidth, dstHeight, dstNumBands, 1027 dstLineStride, dstPixelStride, 1028 dstBandOffsets, bDstData, 1029 tblOffsets, bTblData); 1030 break; 1031 1032 case DataBuffer.TYPE_SHORT: 1033 lookup(srcLineStride, srcPixelStride, 1034 srcBandOffsets, sSrcData, 1035 dstWidth, dstHeight, dstNumBands, 1036 dstLineStride, dstPixelStride, 1037 dstBandOffsets, bDstData, 1038 tblOffsets, bTblData); 1039 break; 1040 1041 case DataBuffer.TYPE_INT: 1042 lookup(srcLineStride, srcPixelStride, 1043 srcBandOffsets, iSrcData, 1044 dstWidth, dstHeight, dstNumBands, 1045 dstLineStride, dstPixelStride, 1046 dstBandOffsets, bDstData, 1047 tblOffsets, bTblData); 1048 break; 1049 } 1050 break; 1051 1052 case DataBuffer.TYPE_USHORT: 1053 case DataBuffer.TYPE_SHORT: 1054 switch (srcDataType) { 1055 case DataBuffer.TYPE_BYTE: 1056 lookup(srcLineStride, srcPixelStride, 1057 srcBandOffsets, bSrcData, 1058 dstWidth, dstHeight, dstNumBands, 1059 dstLineStride, dstPixelStride, 1060 dstBandOffsets, sDstData, 1061 tblOffsets, sTblData); 1062 break; 1063 1064 case DataBuffer.TYPE_USHORT: 1065 lookupU(srcLineStride, srcPixelStride, 1066 srcBandOffsets, sSrcData, 1067 dstWidth, dstHeight, dstNumBands, 1068 dstLineStride, dstPixelStride, 1069 dstBandOffsets, sDstData, 1070 tblOffsets, sTblData); 1071 break; 1072 1073 case DataBuffer.TYPE_SHORT: 1074 lookup(srcLineStride, srcPixelStride, 1075 srcBandOffsets, sSrcData, 1076 dstWidth, dstHeight, dstNumBands, 1077 dstLineStride, dstPixelStride, 1078 dstBandOffsets, sDstData, 1079 tblOffsets, sTblData); 1080 break; 1081 1082 case DataBuffer.TYPE_INT: 1083 lookup(srcLineStride, srcPixelStride, 1084 srcBandOffsets, iSrcData, 1085 dstWidth, dstHeight, dstNumBands, 1086 dstLineStride, dstPixelStride, 1087 dstBandOffsets, sDstData, 1088 tblOffsets, sTblData); 1089 break; 1090 } 1091 break; 1092 1093 case DataBuffer.TYPE_INT: 1094 switch (srcDataType) { 1095 case DataBuffer.TYPE_BYTE: 1096 lookup(srcLineStride, srcPixelStride, 1097 srcBandOffsets, bSrcData, 1098 dstWidth, dstHeight, dstNumBands, 1099 dstLineStride, dstPixelStride, 1100 dstBandOffsets, iDstData, 1101 tblOffsets, iTblData); 1102 break; 1103 1104 case DataBuffer.TYPE_USHORT: 1105 lookupU(srcLineStride, srcPixelStride, 1106 srcBandOffsets, sSrcData, 1107 dstWidth, dstHeight, dstNumBands, 1108 dstLineStride, dstPixelStride, 1109 dstBandOffsets, iDstData, 1110 tblOffsets, iTblData); 1111 break; 1112 1113 case DataBuffer.TYPE_SHORT: 1114 lookup(srcLineStride, srcPixelStride, 1115 srcBandOffsets, sSrcData, 1116 dstWidth, dstHeight, dstNumBands, 1117 dstLineStride, dstPixelStride, 1118 dstBandOffsets, iDstData, 1119 tblOffsets, iTblData); 1120 break; 1121 1122 case DataBuffer.TYPE_INT: 1123 lookup(srcLineStride, srcPixelStride, 1124 srcBandOffsets, iSrcData, 1125 dstWidth, dstHeight, dstNumBands, 1126 dstLineStride, dstPixelStride, 1127 dstBandOffsets, iDstData, 1128 tblOffsets, iTblData); 1129 break; 1130 } 1131 break; 1132 1133 case DataBuffer.TYPE_FLOAT: 1134 switch (srcDataType) { 1135 case DataBuffer.TYPE_BYTE: 1136 lookup(srcLineStride, srcPixelStride, 1137 srcBandOffsets, bSrcData, 1138 dstWidth, dstHeight, dstNumBands, 1139 dstLineStride, dstPixelStride, 1140 dstBandOffsets, fDstData, 1141 tblOffsets, fTblData); 1142 break; 1143 1144 case DataBuffer.TYPE_USHORT: 1145 lookupU(srcLineStride, srcPixelStride, 1146 srcBandOffsets, sSrcData, 1147 dstWidth, dstHeight, dstNumBands, 1148 dstLineStride, dstPixelStride, 1149 dstBandOffsets, fDstData, 1150 tblOffsets, fTblData); 1151 break; 1152 1153 case DataBuffer.TYPE_SHORT: 1154 lookup(srcLineStride, srcPixelStride, 1155 srcBandOffsets, sSrcData, 1156 dstWidth, dstHeight, dstNumBands, 1157 dstLineStride, dstPixelStride, 1158 dstBandOffsets, fDstData, 1159 tblOffsets, fTblData); 1160 break; 1161 1162 case DataBuffer.TYPE_INT: 1163 lookup(srcLineStride, srcPixelStride, 1164 srcBandOffsets, iSrcData, 1165 dstWidth, dstHeight, dstNumBands, 1166 dstLineStride, dstPixelStride, 1167 dstBandOffsets, fDstData, 1168 tblOffsets, fTblData); 1169 break; 1170 } 1171 break; 1172 1173 case DataBuffer.TYPE_DOUBLE: 1174 switch (srcDataType) { 1175 case DataBuffer.TYPE_BYTE: 1176 lookup(srcLineStride, srcPixelStride, 1177 srcBandOffsets, bSrcData, 1178 dstWidth, dstHeight, dstNumBands, 1179 dstLineStride, dstPixelStride, 1180 dstBandOffsets, dDstData, 1181 tblOffsets, dTblData); 1182 break; 1183 1184 case DataBuffer.TYPE_USHORT: 1185 lookupU(srcLineStride, srcPixelStride, 1186 srcBandOffsets, sSrcData, 1187 dstWidth, dstHeight, dstNumBands, 1188 dstLineStride, dstPixelStride, 1189 dstBandOffsets, dDstData, 1190 tblOffsets, dTblData); 1191 break; 1192 1193 case DataBuffer.TYPE_SHORT: 1194 lookup(srcLineStride, srcPixelStride, 1195 srcBandOffsets, sSrcData, 1196 dstWidth, dstHeight, dstNumBands, 1197 dstLineStride, dstPixelStride, 1198 dstBandOffsets, dDstData, 1199 tblOffsets, dTblData); 1200 break; 1201 1202 case DataBuffer.TYPE_INT: 1203 lookup(srcLineStride, srcPixelStride, 1204 srcBandOffsets, iSrcData, 1205 dstWidth, dstHeight, dstNumBands, 1206 dstLineStride, dstPixelStride, 1207 dstBandOffsets, dDstData, 1208 tblOffsets, dTblData); 1209 break; 1210 } 1211 break; 1212 } 1213 1214 d.copyDataToRaster(); 1215 1216 return dst; 1217 } 1218 1219 // byte to byte lookup(int srcLineStride, int srcPixelStride, int[] srcBandOffsets, byte[][] srcData, int width, int height, int bands, int dstLineStride, int dstPixelStride, int[] dstBandOffsets, byte[][] dstData, int[] tblOffsets, byte[][] tblData)1220 private void lookup(int srcLineStride, int srcPixelStride, 1221 int[] srcBandOffsets, byte[][] srcData, 1222 int width, int height, int bands, 1223 int dstLineStride, int dstPixelStride, 1224 int[] dstBandOffsets, byte[][] dstData, 1225 int[] tblOffsets, byte[][] tblData) { 1226 for (int b = 0; b < bands; b++) { 1227 byte[] s = srcData[b]; 1228 byte[] d = dstData[b]; 1229 byte[] t = tblData[b]; 1230 1231 int srcLineOffset = srcBandOffsets[b]; 1232 int dstLineOffset = dstBandOffsets[b]; 1233 int tblOffset = tblOffsets[b]; 1234 1235 for (int h = 0; h < height; h++) { 1236 int srcPixelOffset = srcLineOffset; 1237 int dstPixelOffset = dstLineOffset; 1238 1239 srcLineOffset += srcLineStride; 1240 dstLineOffset += dstLineStride; 1241 1242 for (int w = 0; w < width; w++) { 1243 d[dstPixelOffset] = t[(s[srcPixelOffset]&0xFF) - tblOffset]; 1244 1245 srcPixelOffset += srcPixelStride; 1246 dstPixelOffset += dstPixelStride; 1247 } 1248 } 1249 } 1250 } 1251 1252 // ushort to byte lookupU(int srcLineStride, int srcPixelStride, int[] srcBandOffsets, short[][] srcData, int width, int height, int bands, int dstLineStride, int dstPixelStride, int[] dstBandOffsets, byte[][] dstData, int[] tblOffsets, byte[][] tblData)1253 private void lookupU(int srcLineStride, int srcPixelStride, 1254 int[] srcBandOffsets, short[][] srcData, 1255 int width, int height, int bands, 1256 int dstLineStride, int dstPixelStride, 1257 int[] dstBandOffsets, byte[][] dstData, 1258 int[] tblOffsets, byte[][] tblData) { 1259 for (int b = 0; b < bands; b++) { 1260 short[] s = srcData[b]; 1261 byte[] d = dstData[b]; 1262 byte[] t = tblData[b]; 1263 1264 int srcLineOffset = srcBandOffsets[b]; 1265 int dstLineOffset = dstBandOffsets[b]; 1266 int tblOffset = tblOffsets[b]; 1267 1268 for (int h = 0; h < height; h++) { 1269 int srcPixelOffset = srcLineOffset; 1270 int dstPixelOffset = dstLineOffset; 1271 1272 srcLineOffset += srcLineStride; 1273 dstLineOffset += dstLineStride; 1274 1275 for (int w = 0; w < width; w++) { 1276 d[dstPixelOffset] = 1277 t[(s[srcPixelOffset]&0xFFFF) - tblOffset]; 1278 1279 srcPixelOffset += srcPixelStride; 1280 dstPixelOffset += dstPixelStride; 1281 } 1282 } 1283 } 1284 } 1285 1286 // short to byte lookup(int srcLineStride, int srcPixelStride, int[] srcBandOffsets, short[][] srcData, int width, int height, int bands, int dstLineStride, int dstPixelStride, int[] dstBandOffsets, byte[][] dstData, int[] tblOffsets, byte[][] tblData)1287 private void lookup(int srcLineStride, int srcPixelStride, 1288 int[] srcBandOffsets, short[][] srcData, 1289 int width, int height, int bands, 1290 int dstLineStride, int dstPixelStride, 1291 int[] dstBandOffsets, byte[][] dstData, 1292 int[] tblOffsets, byte[][] tblData) { 1293 for (int b = 0; b < bands; b++) { 1294 short[] s = srcData[b]; 1295 byte[] d = dstData[b]; 1296 byte[] t = tblData[b]; 1297 1298 int srcLineOffset = srcBandOffsets[b]; 1299 int dstLineOffset = dstBandOffsets[b]; 1300 int tblOffset = tblOffsets[b]; 1301 1302 for (int h = 0; h < height; h++) { 1303 int srcPixelOffset = srcLineOffset; 1304 int dstPixelOffset = dstLineOffset; 1305 1306 srcLineOffset += srcLineStride; 1307 dstLineOffset += dstLineStride; 1308 1309 for (int w = 0; w < width; w++) { 1310 d[dstPixelOffset] = t[s[srcPixelOffset] - tblOffset]; 1311 1312 srcPixelOffset += srcPixelStride; 1313 dstPixelOffset += dstPixelStride; 1314 } 1315 } 1316 } 1317 } 1318 1319 // int to byte lookup(int srcLineStride, int srcPixelStride, int[] srcBandOffsets, int[][] srcData, int width, int height, int bands, int dstLineStride, int dstPixelStride, int[] dstBandOffsets, byte[][] dstData, int[] tblOffsets, byte[][] tblData)1320 private void lookup(int srcLineStride, int srcPixelStride, 1321 int[] srcBandOffsets, int[][] srcData, 1322 int width, int height, int bands, 1323 int dstLineStride, int dstPixelStride, 1324 int[] dstBandOffsets, byte[][] dstData, 1325 int[] tblOffsets, byte[][] tblData) { 1326 for (int b = 0; b < bands; b++) { 1327 int[] s = srcData[b]; 1328 byte[] d = dstData[b]; 1329 byte[] t = tblData[b]; 1330 1331 int srcLineOffset = srcBandOffsets[b]; 1332 int dstLineOffset = dstBandOffsets[b]; 1333 int tblOffset = tblOffsets[b]; 1334 1335 for (int h = 0; h < height; h++) { 1336 int srcPixelOffset = srcLineOffset; 1337 int dstPixelOffset = dstLineOffset; 1338 1339 srcLineOffset += srcLineStride; 1340 dstLineOffset += dstLineStride; 1341 1342 for (int w = 0; w < width; w++) { 1343 d[dstPixelOffset] = t[s[srcPixelOffset] - tblOffset]; 1344 1345 srcPixelOffset += srcPixelStride; 1346 dstPixelOffset += dstPixelStride; 1347 } 1348 } 1349 } 1350 } 1351 1352 // byte to short or ushort lookup(int srcLineStride, int srcPixelStride, int[] srcBandOffsets, byte[][] srcData, int width, int height, int bands, int dstLineStride, int dstPixelStride, int[] dstBandOffsets, short[][] dstData, int[] tblOffsets, short[][] tblData)1353 private void lookup(int srcLineStride, int srcPixelStride, 1354 int[] srcBandOffsets, byte[][] srcData, 1355 int width, int height, int bands, 1356 int dstLineStride, int dstPixelStride, 1357 int[] dstBandOffsets, short[][] dstData, 1358 int[] tblOffsets, short[][] tblData) { 1359 for (int b = 0; b < bands; b++) { 1360 byte[] s = srcData[b]; 1361 short[] d = dstData[b]; 1362 short[] t = tblData[b]; 1363 1364 int srcLineOffset = srcBandOffsets[b]; 1365 int dstLineOffset = dstBandOffsets[b]; 1366 int tblOffset = tblOffsets[b]; 1367 1368 for (int h = 0; h < height; h++) { 1369 int srcPixelOffset = srcLineOffset; 1370 int dstPixelOffset = dstLineOffset; 1371 1372 srcLineOffset += srcLineStride; 1373 dstLineOffset += dstLineStride; 1374 1375 for (int w = 0; w < width; w++) { 1376 d[dstPixelOffset] = t[(s[srcPixelOffset]&0xFF) - tblOffset]; 1377 1378 srcPixelOffset += srcPixelStride; 1379 dstPixelOffset += dstPixelStride; 1380 } 1381 } 1382 } 1383 } 1384 1385 // ushort to short or ushort lookupU(int srcLineStride, int srcPixelStride, int[] srcBandOffsets, short[][] srcData, int width, int height, int bands, int dstLineStride, int dstPixelStride, int[] dstBandOffsets, short[][] dstData, int[] tblOffsets, short[][] tblData)1386 private void lookupU(int srcLineStride, int srcPixelStride, 1387 int[] srcBandOffsets, short[][] srcData, 1388 int width, int height, int bands, 1389 int dstLineStride, int dstPixelStride, 1390 int[] dstBandOffsets, short[][] dstData, 1391 int[] tblOffsets, short[][] tblData) { 1392 for (int b = 0; b < bands; b++) { 1393 short[] s = srcData[b]; 1394 short[] d = dstData[b]; 1395 short[] t = tblData[b]; 1396 1397 int srcLineOffset = srcBandOffsets[b]; 1398 int dstLineOffset = dstBandOffsets[b]; 1399 int tblOffset = tblOffsets[b]; 1400 1401 for (int h = 0; h < height; h++) { 1402 int srcPixelOffset = srcLineOffset; 1403 int dstPixelOffset = dstLineOffset; 1404 1405 srcLineOffset += srcLineStride; 1406 dstLineOffset += dstLineStride; 1407 1408 for (int w = 0; w < width; w++) { 1409 d[dstPixelOffset] = 1410 t[(s[srcPixelOffset]&0xFFFF) - tblOffset]; 1411 1412 srcPixelOffset += srcPixelStride; 1413 dstPixelOffset += dstPixelStride; 1414 } 1415 } 1416 } 1417 } 1418 1419 // short to short or ushort lookup(int srcLineStride, int srcPixelStride, int[] srcBandOffsets, short[][] srcData, int width, int height, int bands, int dstLineStride, int dstPixelStride, int[] dstBandOffsets, short[][] dstData, int[] tblOffsets, short[][] tblData)1420 private void lookup(int srcLineStride, int srcPixelStride, 1421 int[] srcBandOffsets, short[][] srcData, 1422 int width, int height, int bands, 1423 int dstLineStride, int dstPixelStride, 1424 int[] dstBandOffsets, short[][] dstData, 1425 int[] tblOffsets, short[][] tblData) { 1426 for (int b = 0; b < bands; b++) { 1427 short[] s = srcData[b]; 1428 short[] d = dstData[b]; 1429 short[] t = tblData[b]; 1430 1431 int srcLineOffset = srcBandOffsets[b]; 1432 int dstLineOffset = dstBandOffsets[b]; 1433 int tblOffset = tblOffsets[b]; 1434 1435 for (int h = 0; h < height; h++) { 1436 int srcPixelOffset = srcLineOffset; 1437 int dstPixelOffset = dstLineOffset; 1438 1439 srcLineOffset += srcLineStride; 1440 dstLineOffset += dstLineStride; 1441 1442 for (int w = 0; w < width; w++) { 1443 d[dstPixelOffset] = t[s[srcPixelOffset] - tblOffset]; 1444 1445 srcPixelOffset += srcPixelStride; 1446 dstPixelOffset += dstPixelStride; 1447 } 1448 } 1449 } 1450 } 1451 1452 // int to short or ushort lookup(int srcLineStride, int srcPixelStride, int[] srcBandOffsets, int[][] srcData, int width, int height, int bands, int dstLineStride, int dstPixelStride, int[] dstBandOffsets, short[][] dstData, int[] tblOffsets, short[][] tblData)1453 private void lookup(int srcLineStride, int srcPixelStride, 1454 int[] srcBandOffsets, int[][] srcData, 1455 int width, int height, int bands, 1456 int dstLineStride, int dstPixelStride, 1457 int[] dstBandOffsets, short[][] dstData, 1458 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 lookup(int srcLineStride, int srcPixelStride, int[] srcBandOffsets, byte[][] srcData, int width, int height, int bands, int dstLineStride, int dstPixelStride, int[] dstBandOffsets, int[][] dstData, int[] tblOffsets, int[][] tblData)1486 private void lookup(int srcLineStride, int srcPixelStride, 1487 int[] srcBandOffsets, byte[][] srcData, 1488 int width, int height, int bands, 1489 int dstLineStride, int dstPixelStride, 1490 int[] dstBandOffsets, int[][] dstData, 1491 int[] tblOffsets, int[][] tblData) { 1492 if (tblData == null) { 1493 for (int b = 0; b < bands; b++) { 1494 byte[] s = srcData[b]; 1495 int[] d = dstData[b]; 1496 1497 int srcLineOffset = srcBandOffsets[b]; 1498 int dstLineOffset = dstBandOffsets[b]; 1499 1500 for (int h = 0; h < height; h++) { 1501 int srcPixelOffset = srcLineOffset; 1502 int dstPixelOffset = dstLineOffset; 1503 1504 srcLineOffset += srcLineStride; 1505 dstLineOffset += dstLineStride; 1506 1507 for (int w = 0; w < width; w++) { 1508 d[dstPixelOffset] = 1509 data.getElem(b, s[srcPixelOffset]&0xFF); 1510 1511 srcPixelOffset += srcPixelStride; 1512 dstPixelOffset += dstPixelStride; 1513 } 1514 } 1515 } 1516 } else { 1517 for (int b = 0; b < bands; b++) { 1518 byte[] s = srcData[b]; 1519 int[] d = dstData[b]; 1520 int[] t = tblData[b]; 1521 1522 int srcLineOffset = srcBandOffsets[b]; 1523 int dstLineOffset = dstBandOffsets[b]; 1524 int tblOffset = tblOffsets[b]; 1525 1526 for (int h = 0; h < height; h++) { 1527 int srcPixelOffset = srcLineOffset; 1528 int dstPixelOffset = dstLineOffset; 1529 1530 srcLineOffset += srcLineStride; 1531 dstLineOffset += dstLineStride; 1532 1533 for (int w = 0; w < width; w++) { 1534 d[dstPixelOffset] = 1535 t[(s[srcPixelOffset]&0xFF) - tblOffset]; 1536 1537 srcPixelOffset += srcPixelStride; 1538 dstPixelOffset += dstPixelStride; 1539 } 1540 } 1541 } 1542 } 1543 } 1544 1545 // ushort to int lookupU(int srcLineStride, int srcPixelStride, int[] srcBandOffsets, short[][] srcData, int width, int height, int bands, int dstLineStride, int dstPixelStride, int[] dstBandOffsets, int[][] dstData, int[] tblOffsets, int[][] tblData)1546 private void lookupU(int srcLineStride, int srcPixelStride, 1547 int[] srcBandOffsets, short[][] srcData, 1548 int width, int height, int bands, 1549 int dstLineStride, int dstPixelStride, 1550 int[] dstBandOffsets, int[][] dstData, 1551 int[] tblOffsets, int[][] tblData) { 1552 if (tblData == null) { 1553 for (int b = 0; b < bands; b++) { 1554 short[] s = srcData[b]; 1555 int[] d = dstData[b]; 1556 1557 int srcLineOffset = srcBandOffsets[b]; 1558 int dstLineOffset = dstBandOffsets[b]; 1559 1560 for (int h = 0; h < height; h++) { 1561 int srcPixelOffset = srcLineOffset; 1562 int dstPixelOffset = dstLineOffset; 1563 1564 srcLineOffset += srcLineStride; 1565 dstLineOffset += dstLineStride; 1566 1567 for (int w = 0; w < width; w++) { 1568 d[dstPixelOffset] = 1569 data.getElem(b, s[srcPixelOffset]&0xFFFF); 1570 1571 srcPixelOffset += srcPixelStride; 1572 dstPixelOffset += dstPixelStride; 1573 } 1574 } 1575 } 1576 } else { 1577 for (int b = 0; b < bands; b++) { 1578 short[] s = srcData[b]; 1579 int[] d = dstData[b]; 1580 int[] t = tblData[b]; 1581 1582 int srcLineOffset = srcBandOffsets[b]; 1583 int dstLineOffset = dstBandOffsets[b]; 1584 int tblOffset = tblOffsets[b]; 1585 1586 for (int h = 0; h < height; h++) { 1587 int srcPixelOffset = srcLineOffset; 1588 int dstPixelOffset = dstLineOffset; 1589 1590 srcLineOffset += srcLineStride; 1591 dstLineOffset += dstLineStride; 1592 1593 for (int w = 0; w < width; w++) { 1594 d[dstPixelOffset] = 1595 t[(s[srcPixelOffset]&0xFFFF) - tblOffset]; 1596 1597 srcPixelOffset += srcPixelStride; 1598 dstPixelOffset += dstPixelStride; 1599 } 1600 } 1601 } 1602 } 1603 } 1604 1605 // short to int lookup(int srcLineStride, int srcPixelStride, int[] srcBandOffsets, short[][] srcData, int width, int height, int bands, int dstLineStride, int dstPixelStride, int[] dstBandOffsets, int[][] dstData, int[] tblOffsets, int[][] tblData)1606 private void lookup(int srcLineStride, int srcPixelStride, 1607 int[] srcBandOffsets, short[][] srcData, 1608 int width, int height, int bands, 1609 int dstLineStride, int dstPixelStride, 1610 int[] dstBandOffsets, int[][] dstData, 1611 int[] tblOffsets, int[][] tblData) { 1612 if (tblData == null) { 1613 for (int b = 0; b < bands; b++) { 1614 short[] s = srcData[b]; 1615 int[] d = dstData[b]; 1616 1617 int srcLineOffset = srcBandOffsets[b]; 1618 int dstLineOffset = dstBandOffsets[b]; 1619 1620 for (int h = 0; h < height; h++) { 1621 int srcPixelOffset = srcLineOffset; 1622 int dstPixelOffset = dstLineOffset; 1623 1624 srcLineOffset += srcLineStride; 1625 dstLineOffset += dstLineStride; 1626 1627 for (int w = 0; w < width; w++) { 1628 d[dstPixelOffset] = 1629 data.getElem(b, s[srcPixelOffset]); 1630 1631 srcPixelOffset += srcPixelStride; 1632 dstPixelOffset += dstPixelStride; 1633 } 1634 } 1635 } 1636 } else { 1637 for (int b = 0; b < bands; b++) { 1638 short[] s = srcData[b]; 1639 int[] d = dstData[b]; 1640 int[] t = tblData[b]; 1641 1642 int srcLineOffset = srcBandOffsets[b]; 1643 int dstLineOffset = dstBandOffsets[b]; 1644 int tblOffset = tblOffsets[b]; 1645 1646 for (int h = 0; h < height; h++) { 1647 int srcPixelOffset = srcLineOffset; 1648 int dstPixelOffset = dstLineOffset; 1649 1650 srcLineOffset += srcLineStride; 1651 dstLineOffset += dstLineStride; 1652 1653 for (int w = 0; w < width; w++) { 1654 d[dstPixelOffset] = t[s[srcPixelOffset] - tblOffset]; 1655 1656 srcPixelOffset += srcPixelStride; 1657 dstPixelOffset += dstPixelStride; 1658 } 1659 } 1660 } 1661 } 1662 } 1663 1664 // int to int lookup(int srcLineStride, int srcPixelStride, int[] srcBandOffsets, int[][] srcData, int width, int height, int bands, int dstLineStride, int dstPixelStride, int[] dstBandOffsets, int[][] dstData, int[] tblOffsets, int[][] tblData)1665 private void lookup(int srcLineStride, int srcPixelStride, 1666 int[] srcBandOffsets, int[][] srcData, 1667 int width, int height, int bands, 1668 int dstLineStride, int dstPixelStride, 1669 int[] dstBandOffsets, int[][] dstData, 1670 int[] tblOffsets, int[][] tblData) { 1671 if (tblData == null) { 1672 for (int b = 0; b < bands; b++) { 1673 int[] s = srcData[b]; 1674 int[] d = dstData[b]; 1675 1676 int srcLineOffset = srcBandOffsets[b]; 1677 int dstLineOffset = dstBandOffsets[b]; 1678 1679 for (int h = 0; h < height; h++) { 1680 int srcPixelOffset = srcLineOffset; 1681 int dstPixelOffset = dstLineOffset; 1682 1683 srcLineOffset += srcLineStride; 1684 dstLineOffset += dstLineStride; 1685 1686 for (int w = 0; w < width; w++) { 1687 d[dstPixelOffset] = data.getElem(b, s[srcPixelOffset]); 1688 1689 srcPixelOffset += srcPixelStride; 1690 dstPixelOffset += dstPixelStride; 1691 } 1692 } 1693 } 1694 } else { 1695 for (int b = 0; b < bands; b++) { 1696 int[] s = srcData[b]; 1697 int[] d = dstData[b]; 1698 int[] t = tblData[b]; 1699 1700 int srcLineOffset = srcBandOffsets[b]; 1701 int dstLineOffset = dstBandOffsets[b]; 1702 int tblOffset = tblOffsets[b]; 1703 1704 for (int h = 0; h < height; h++) { 1705 int srcPixelOffset = srcLineOffset; 1706 int dstPixelOffset = dstLineOffset; 1707 1708 srcLineOffset += srcLineStride; 1709 dstLineOffset += dstLineStride; 1710 1711 for (int w = 0; w < width; w++) { 1712 d[dstPixelOffset] = t[s[srcPixelOffset] - tblOffset]; 1713 1714 srcPixelOffset += srcPixelStride; 1715 dstPixelOffset += dstPixelStride; 1716 } 1717 } 1718 } 1719 } 1720 } 1721 1722 // byte to float lookup(int srcLineStride, int srcPixelStride, int[] srcBandOffsets, byte[][] srcData, int width, int height, int bands, int dstLineStride, int dstPixelStride, int[] dstBandOffsets, float[][] dstData, int[] tblOffsets, float[][] tblData)1723 private void lookup(int srcLineStride, int srcPixelStride, 1724 int[] srcBandOffsets, byte[][] srcData, 1725 int width, int height, int bands, 1726 int dstLineStride, int dstPixelStride, 1727 int[] dstBandOffsets, float[][] dstData, 1728 int[] tblOffsets, float[][] tblData) { 1729 for (int b = 0; b < bands; b++) { 1730 byte[] s = srcData[b]; 1731 float[] d = dstData[b]; 1732 float[] t = tblData[b]; 1733 1734 int srcLineOffset = srcBandOffsets[b]; 1735 int dstLineOffset = dstBandOffsets[b]; 1736 int tblOffset = tblOffsets[b]; 1737 1738 for (int h = 0; h < height; h++) { 1739 int srcPixelOffset = srcLineOffset; 1740 int dstPixelOffset = dstLineOffset; 1741 1742 srcLineOffset += srcLineStride; 1743 dstLineOffset += dstLineStride; 1744 1745 for (int w = 0; w < width; w++) { 1746 d[dstPixelOffset] = t[(s[srcPixelOffset]&0xFF) - tblOffset]; 1747 1748 srcPixelOffset += srcPixelStride; 1749 dstPixelOffset += dstPixelStride; 1750 } 1751 } 1752 } 1753 } 1754 1755 // ushort to float lookupU(int srcLineStride, int srcPixelStride, int[] srcBandOffsets, short[][] srcData, int width, int height, int bands, int dstLineStride, int dstPixelStride, int[] dstBandOffsets, float[][] dstData, int[] tblOffsets, float[][] tblData)1756 private void lookupU(int srcLineStride, int srcPixelStride, 1757 int[] srcBandOffsets, short[][] srcData, 1758 int width, int height, int bands, 1759 int dstLineStride, int dstPixelStride, 1760 int[] dstBandOffsets, float[][] dstData, 1761 int[] tblOffsets, float[][] tblData) { 1762 for (int b = 0; b < bands; b++) { 1763 short[] s = srcData[b]; 1764 float[] d = dstData[b]; 1765 float[] t = tblData[b]; 1766 1767 int srcLineOffset = srcBandOffsets[b]; 1768 int dstLineOffset = dstBandOffsets[b]; 1769 int tblOffset = tblOffsets[b]; 1770 1771 for (int h = 0; h < height; h++) { 1772 int srcPixelOffset = srcLineOffset; 1773 int dstPixelOffset = dstLineOffset; 1774 1775 srcLineOffset += srcLineStride; 1776 dstLineOffset += dstLineStride; 1777 1778 for (int w = 0; w < width; w++) { 1779 d[dstPixelOffset] = 1780 t[(s[srcPixelOffset]&0xFFFF) - tblOffset]; 1781 1782 srcPixelOffset += srcPixelStride; 1783 dstPixelOffset += dstPixelStride; 1784 } 1785 } 1786 } 1787 } 1788 1789 // short to float lookup(int srcLineStride, int srcPixelStride, int[] srcBandOffsets, short[][] srcData, int width, int height, int bands, int dstLineStride, int dstPixelStride, int[] dstBandOffsets, float[][] dstData, int[] tblOffsets, float[][] tblData)1790 private void lookup(int srcLineStride, int srcPixelStride, 1791 int[] srcBandOffsets, short[][] srcData, 1792 int width, int height, int bands, 1793 int dstLineStride, int dstPixelStride, 1794 int[] dstBandOffsets, float[][] dstData, 1795 int[] tblOffsets, float[][] tblData) { 1796 for (int b = 0; b < bands; b++) { 1797 short[] s = srcData[b]; 1798 float[] d = dstData[b]; 1799 float[] t = tblData[b]; 1800 1801 int srcLineOffset = srcBandOffsets[b]; 1802 int dstLineOffset = dstBandOffsets[b]; 1803 int tblOffset = tblOffsets[b]; 1804 1805 for (int h = 0; h < height; h++) { 1806 int srcPixelOffset = srcLineOffset; 1807 int dstPixelOffset = dstLineOffset; 1808 1809 srcLineOffset += srcLineStride; 1810 dstLineOffset += dstLineStride; 1811 1812 for (int w = 0; w < width; w++) { 1813 d[dstPixelOffset] = t[s[srcPixelOffset] - tblOffset]; 1814 1815 srcPixelOffset += srcPixelStride; 1816 dstPixelOffset += dstPixelStride; 1817 } 1818 } 1819 } 1820 } 1821 1822 // int to float lookup(int srcLineStride, int srcPixelStride, int[] srcBandOffsets, int[][] srcData, int width, int height, int bands, int dstLineStride, int dstPixelStride, int[] dstBandOffsets, float[][] dstData, int[] tblOffsets, float[][] tblData)1823 private void lookup(int srcLineStride, int srcPixelStride, 1824 int[] srcBandOffsets, int[][] srcData, 1825 int width, int height, int bands, 1826 int dstLineStride, int dstPixelStride, 1827 int[] dstBandOffsets, float[][] dstData, 1828 int[] tblOffsets, float[][] tblData) { 1829 for (int b = 0; b < bands; b++) { 1830 int[] s = srcData[b]; 1831 float[] d = dstData[b]; 1832 float[] t = tblData[b]; 1833 1834 int srcLineOffset = srcBandOffsets[b]; 1835 int dstLineOffset = dstBandOffsets[b]; 1836 int tblOffset = tblOffsets[b]; 1837 1838 for (int h = 0; h < height; h++) { 1839 int srcPixelOffset = srcLineOffset; 1840 int dstPixelOffset = dstLineOffset; 1841 1842 srcLineOffset += srcLineStride; 1843 dstLineOffset += dstLineStride; 1844 1845 for (int w = 0; w < width; w++) { 1846 d[dstPixelOffset] = t[s[srcPixelOffset] - tblOffset]; 1847 1848 srcPixelOffset += srcPixelStride; 1849 dstPixelOffset += dstPixelStride; 1850 } 1851 } 1852 } 1853 } 1854 1855 // byte to double lookup(int srcLineStride, int srcPixelStride, int[] srcBandOffsets, byte[][] srcData, int width, int height, int bands, int dstLineStride, int dstPixelStride, int[] dstBandOffsets, double[][] dstData, int[] tblOffsets, double[][] tblData)1856 private void lookup(int srcLineStride, int srcPixelStride, 1857 int[] srcBandOffsets, byte[][] srcData, 1858 int width, int height, int bands, 1859 int dstLineStride, int dstPixelStride, 1860 int[] dstBandOffsets, double[][] dstData, 1861 int[] tblOffsets, double[][] tblData) { 1862 for (int b = 0; b < bands; b++) { 1863 byte[] s = srcData[b]; 1864 double[] d = dstData[b]; 1865 double[] t = tblData[b]; 1866 1867 int srcLineOffset = srcBandOffsets[b]; 1868 int dstLineOffset = dstBandOffsets[b]; 1869 int tblOffset = tblOffsets[b]; 1870 1871 for (int h = 0; h < height; h++) { 1872 int srcPixelOffset = srcLineOffset; 1873 int dstPixelOffset = dstLineOffset; 1874 1875 srcLineOffset += srcLineStride; 1876 dstLineOffset += dstLineStride; 1877 1878 for (int w = 0; w < width; w++) { 1879 d[dstPixelOffset] = t[(s[srcPixelOffset]&0xFF) - tblOffset]; 1880 1881 srcPixelOffset += srcPixelStride; 1882 dstPixelOffset += dstPixelStride; 1883 } 1884 } 1885 } 1886 } 1887 1888 // ushort to double lookupU(int srcLineStride, int srcPixelStride, int[] srcBandOffsets, short[][] srcData, int width, int height, int bands, int dstLineStride, int dstPixelStride, int[] dstBandOffsets, double[][] dstData, int[] tblOffsets, double[][] tblData)1889 private void lookupU(int srcLineStride, int srcPixelStride, 1890 int[] srcBandOffsets, short[][] srcData, 1891 int width, int height, int bands, 1892 int dstLineStride, int dstPixelStride, 1893 int[] dstBandOffsets, double[][] dstData, 1894 int[] tblOffsets, double[][] tblData) { 1895 for (int b = 0; b < bands; b++) { 1896 short[] s = srcData[b]; 1897 double[] d = dstData[b]; 1898 double[] t = tblData[b]; 1899 1900 int srcLineOffset = srcBandOffsets[b]; 1901 int dstLineOffset = dstBandOffsets[b]; 1902 int tblOffset = tblOffsets[b]; 1903 1904 for (int h = 0; h < height; h++) { 1905 int srcPixelOffset = srcLineOffset; 1906 int dstPixelOffset = dstLineOffset; 1907 1908 srcLineOffset += srcLineStride; 1909 dstLineOffset += dstLineStride; 1910 1911 for (int w = 0; w < width; w++) { 1912 d[dstPixelOffset] = 1913 t[(s[srcPixelOffset]&0xFFFF) - tblOffset]; 1914 1915 srcPixelOffset += srcPixelStride; 1916 dstPixelOffset += dstPixelStride; 1917 } 1918 } 1919 } 1920 } 1921 1922 // short to double lookup(int srcLineStride, int srcPixelStride, int[] srcBandOffsets, short[][] srcData, int width, int height, int bands, int dstLineStride, int dstPixelStride, int[] dstBandOffsets, double[][] dstData, int[] tblOffsets, double[][] tblData)1923 private void lookup(int srcLineStride, int srcPixelStride, 1924 int[] srcBandOffsets, short[][] srcData, 1925 int width, int height, int bands, 1926 int dstLineStride, int dstPixelStride, 1927 int[] dstBandOffsets, double[][] dstData, 1928 int[] tblOffsets, double[][] tblData) { 1929 for (int b = 0; b < bands; b++) { 1930 short[] s = srcData[b]; 1931 double[] d = dstData[b]; 1932 double[] t = tblData[b]; 1933 1934 int srcLineOffset = srcBandOffsets[b]; 1935 int dstLineOffset = dstBandOffsets[b]; 1936 int tblOffset = tblOffsets[b]; 1937 1938 for (int h = 0; h < height; h++) { 1939 int srcPixelOffset = srcLineOffset; 1940 int dstPixelOffset = dstLineOffset; 1941 1942 srcLineOffset += srcLineStride; 1943 dstLineOffset += dstLineStride; 1944 1945 for (int w = 0; w < width; w++) { 1946 d[dstPixelOffset] = t[s[srcPixelOffset] - tblOffset]; 1947 1948 srcPixelOffset += srcPixelStride; 1949 dstPixelOffset += dstPixelStride; 1950 } 1951 } 1952 } 1953 } 1954 1955 // int to double lookup(int srcLineStride, int srcPixelStride, int[] srcBandOffsets, int[][] srcData, int width, int height, int bands, int dstLineStride, int dstPixelStride, int[] dstBandOffsets, double[][] dstData, int[] tblOffsets, double[][] tblData)1956 private void lookup(int srcLineStride, int srcPixelStride, 1957 int[] srcBandOffsets, int[][] srcData, 1958 int width, int height, int bands, 1959 int dstLineStride, int dstPixelStride, 1960 int[] dstBandOffsets, double[][] dstData, 1961 int[] tblOffsets, double[][] tblData) { 1962 for (int b = 0; b < bands; b++) { 1963 int[] s = srcData[b]; 1964 double[] d = dstData[b]; 1965 double[] t = tblData[b]; 1966 1967 int srcLineOffset = srcBandOffsets[b]; 1968 int dstLineOffset = dstBandOffsets[b]; 1969 int tblOffset = tblOffsets[b]; 1970 1971 for (int h = 0; h < height; h++) { 1972 int srcPixelOffset = srcLineOffset; 1973 int dstPixelOffset = dstLineOffset; 1974 1975 srcLineOffset += srcLineStride; 1976 dstLineOffset += dstLineStride; 1977 1978 for (int w = 0; w < width; w++) { 1979 d[dstPixelOffset] = t[s[srcPixelOffset] - tblOffset]; 1980 1981 srcPixelOffset += srcPixelStride; 1982 dstPixelOffset += dstPixelStride; 1983 } 1984 } 1985 } 1986 } 1987 1988 /** 1989 * Determine which entry in the <code>LookupTableJAI</code> is closest 1990 * in Euclidean distance to the argument pixel. 1991 * 1992 * @param pixel The pixel the closest entry to which is to be found. 1993 * 1994 * @return the index of the closest entry. If the data array of the 1995 * lookup table is in the format data[numBands][numEntries], then the 1996 * value <i>v</i> for band <i>b</i> of the closest entry is 1997 * <pre> 1998 * v = data[b][index - lookup.getOffset()] 1999 * </pre> 2000 * where <i>index</i> is the returned value of this method. 2001 * 2002 * @throws IllegalArgumentException if pixel is null. 2003 */ findNearestEntry(float[] pixel)2004 public int findNearestEntry(float[] pixel) { 2005 2006 if ( pixel == null ) { 2007 throw new IllegalArgumentException(JaiI18N.getString("Generic0")); 2008 } 2009 2010 int dataType = data.getDataType(); 2011 int numBands = getNumBands(); 2012 int numEntries = getNumEntries(); 2013 int index = -1; 2014 2015 if(dataType == DataBuffer.TYPE_BYTE) { 2016 byte buffer[][] = getByteData(); 2017 2018 // Find the distance to the first entry and set result to 0. 2019 float minDistance = 0.0F; 2020 index = 0; 2021 for(int b = 0; b < numBands; b++) { 2022 float delta = pixel[b] - (float)(buffer[b][0] & 0xff); 2023 minDistance += delta*delta; 2024 } 2025 2026 // Find the distance to each entry and set the result to 2027 // the index which is closest to the argument. 2028 for(int i = 1; i < numEntries; i++) { 2029 float distance = 0.0F; 2030 for(int b = 0; b < numBands; b++) { 2031 float delta = 2032 pixel[b] - (float)(buffer[b][i] & 0xff); 2033 distance += delta*delta; 2034 } 2035 2036 if(distance < minDistance) { 2037 minDistance = distance; 2038 index = i; 2039 } 2040 } 2041 } else if(dataType == DataBuffer.TYPE_SHORT) { 2042 short buffer[][] = getShortData(); 2043 2044 // Find the distance to the first entry and set result to 0. 2045 float minDistance = 0.0F; 2046 index = 0; 2047 for(int b = 0; b < numBands; b++) { 2048 float delta = pixel[b] - buffer[b][0]; 2049 minDistance += delta*delta; 2050 } 2051 2052 // Find the distance to each entry and set the result to 2053 // the index which is closest to the argument. 2054 for(int i = 1; i < numEntries; i++) { 2055 float distance = 0.0F; 2056 for(int b = 0; b < numBands; b++) { 2057 float delta = pixel[b] - buffer[b][i]; 2058 distance += delta*delta; 2059 } 2060 2061 if(distance < minDistance) { 2062 minDistance = distance; 2063 index = i; 2064 } 2065 } 2066 } else if(dataType == DataBuffer.TYPE_USHORT) { 2067 short buffer[][] = getShortData(); 2068 2069 // Find the distance to the first entry and set result to 0. 2070 float minDistance = 0.0F; 2071 index = 0; 2072 for(int b = 0; b < numBands; b++) { 2073 float delta = pixel[b] - (float)(buffer[b][0] & 0xffff); 2074 minDistance += delta*delta; 2075 } 2076 2077 // Find the distance to each entry and set the result to 2078 // the index which is closest to the argument. 2079 for(int i = 1; i < numEntries; i++) { 2080 float distance = 0.0F; 2081 for(int b = 0; b < numBands; b++) { 2082 float delta = 2083 pixel[b] - (float)(buffer[b][i] & 0xffff); 2084 distance += delta*delta; 2085 } 2086 2087 if(distance < minDistance) { 2088 minDistance = distance; 2089 index = i; 2090 } 2091 } 2092 } else if(dataType == DataBuffer.TYPE_INT) { 2093 int buffer[][] = getIntData(); 2094 2095 // Find the distance to the first entry and set result to 0. 2096 float minDistance = 0.0F; 2097 index = 0; 2098 for(int b = 0; b < numBands; b++) { 2099 float delta = pixel[b] - buffer[b][0]; 2100 minDistance += delta*delta; 2101 } 2102 2103 // Find the distance to each entry and set the result to 2104 // the index which is closest to the argument. 2105 for(int i = 1; i < numEntries; i++) { 2106 float distance = 0.0F; 2107 for(int b = 0; b < numBands; b++) { 2108 float delta = pixel[b] - buffer[b][i]; 2109 distance += delta*delta; 2110 } 2111 2112 if(distance < minDistance) { 2113 minDistance = distance; 2114 index = i; 2115 } 2116 } 2117 } else if(dataType == DataBuffer.TYPE_FLOAT) { 2118 float buffer[][] = getFloatData(); 2119 2120 // Find the distance to the first entry and set result to 0. 2121 float minDistance = 0.0F; 2122 index = 0; 2123 for(int b = 0; b < numBands; b++) { 2124 float delta = pixel[b] - buffer[b][0]; 2125 minDistance += delta*delta; 2126 } 2127 2128 // Find the distance to each entry and set the result to 2129 // the index which is closest to the argument. 2130 for(int i = 1; i < numEntries; i++) { 2131 float distance = 0.0F; 2132 for(int b = 0; b < numBands; b++) { 2133 float delta = pixel[b] - buffer[b][i]; 2134 distance += delta*delta; 2135 } 2136 2137 if(distance < minDistance) { 2138 minDistance = distance; 2139 index = i; 2140 } 2141 } 2142 } else if(dataType == DataBuffer.TYPE_DOUBLE) { 2143 double buffer[][] = getDoubleData(); 2144 2145 // Find the distance to the first entry and set result to 0. 2146 double minDistance = 0.0F; 2147 index = 0; 2148 for(int b = 0; b < numBands; b++) { 2149 double delta = pixel[b] - buffer[b][0]; 2150 minDistance += delta*delta; 2151 } 2152 2153 // Find the distance to each entry and set the result to 2154 // the index which is closest to the argument. 2155 for(int i = 1; i < numEntries; i++) { 2156 double distance = 0.0F; 2157 for(int b = 0; b < numBands; b++) { 2158 double delta = pixel[b] - buffer[b][i]; 2159 distance += delta*delta; 2160 } 2161 2162 if(distance < minDistance) { 2163 minDistance = distance; 2164 index = i; 2165 } 2166 } 2167 } else { 2168 // This can't happen since we control the type of data 2169 throw new RuntimeException(JaiI18N.getString("LookupTableJAI0")); 2170 } 2171 2172 // Return the index of the closest color plus the offset of the 2173 // default band or -1 on error. 2174 return index == -1 ? index : index + getOffset(); 2175 } 2176 2177 /** 2178 * Serialize the <code>LookupTableJAI</code>. 2179 * 2180 * @param out The <code>ObjectOutputStream</code>. 2181 */ writeObject(ObjectOutputStream out)2182 private void writeObject(ObjectOutputStream out) throws IOException { 2183 out.defaultWriteObject(); 2184 out.writeObject(SerializerFactory.getState(data)); 2185 } 2186 2187 /** 2188 * Deserialize the <code>LookupTableJAI</code>. 2189 * 2190 * @param in The <code>ObjectInputStream</code>. 2191 */ readObject(ObjectInputStream in)2192 private void readObject(ObjectInputStream in) 2193 throws IOException, ClassNotFoundException { 2194 in.defaultReadObject(); 2195 Object object = in.readObject(); 2196 SerializableState ss = (SerializableState)object; 2197 data = (DataBuffer)ss.getObject(); 2198 } 2199 initOffsets(int nbands, int offset)2200 private void initOffsets(int nbands, int offset) { 2201 tableOffsets = new int[nbands]; 2202 for (int i=0; i<nbands; i++) { 2203 tableOffsets[i] = offset; 2204 } 2205 } 2206 initOffsets(int nbands, int[] offset)2207 private void initOffsets(int nbands, int[] offset) { 2208 tableOffsets = new int[nbands]; 2209 for (int i=0; i<nbands; i++) { 2210 tableOffsets[i] = offset[i]; 2211 } 2212 } 2213 2214 2215 } 2216 2217 2218