/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2005-2008, Open Source Geospatial Foundation (OSGeo) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ package org.geotools.coverage.grid.io.imageio.geotiff; import org.geotools.resources.i18n.ErrorKeys; import org.geotools.resources.i18n.Errors; import org.geotools.util.Utilities; /** * This class is a holder for a GeoKey record containing four short values as * specified in the GeoTiff spec. The values are a GeoKey ID, the TIFFTag number * of the location of this data, the count of values for this GeoKey, and the * offset (or value if the location is 0). * * <p> * If the Tiff Tag location is 0, then the value is a Short and is contained in * the offset. Otherwise, there is one or more value in the specified external * Tiff tag. The number is specified by the count field, and the offset into the * record is the offset field. * </p> * * @author Simone Giannecchini, GeoSolutions * @author Mike Nidel * * * @source $URL$ */ public final class GeoKeyEntry implements Comparable<GeoKeyEntry>{ @Override public boolean equals(Object obj) { if(this==obj) return true; if(!(obj instanceof GeoKeyEntry)) return false; final GeoKeyEntry that= (GeoKeyEntry) obj; if( this.keyID==that.keyID&& this.count==that.count&& this.valueOffset==that.valueOffset&& this.tiffTagLocation==that.tiffTagLocation ) return true; return false; } @Override public int hashCode() { int hash=Utilities.hash(this.keyID, 1); hash=Utilities.hash(this.count, hash); hash=Utilities.hash(this.valueOffset, hash); hash=Utilities.hash(this.tiffTagLocation, hash); return hash; } @Override public String toString() { final StringBuilder builder= new StringBuilder(); builder.append("GeoKeyEntry (").append(count==0?"VALUE":"OFFSET").append("\n"); builder.append("ID: ").append(keyID).append("\n"); builder.append("COUNT: ").append(count).append("\n"); builder.append("LOCATION: ").append(tiffTagLocation).append("\n"); builder.append("VALUE_OFFSET: ").append(valueOffset).append("\n"); return builder.toString(); } /** * "KeyID" gives the key-ID value of the Key (identical in function to TIFF * tag ID, but completely independent of TIFF tag-space) */ private int keyID; /** * "TIFFTagLocation" indicates which TIFF tag contains the value(s) of the * Key: if TIFFTagLocation is 0, then the value is SHORT, and is contained * in the "Value_Offset" entry. Otherwise, the type (format) of the value is * implied by the TIFF-Type of the tag containing the value. */ private int tiffTagLocation; /** * "Count" indicates the number of values in this key. */ private int count; /** * "Value_Offset" Value_Offset indicates the index- offset *into* the * TagArray indicated by TIFFTagLocation, if it is nonzero. If * TIFFTagLocation=0, then Value_Offset contains the actual (SHORT) value of * the Key, and Count=1 is implied. Note that the offset is not a * byte-offset, but rather an index based on the natural data type of the * specified tag array. */ private int valueOffset; /** * Constructor of a {@link GeoKeyEntry}. * * @param keyID * the id of this {@link GeoKeyEntry}. * @param tagLoc * the location of this tag. * @param count * @param offset */ public GeoKeyEntry(int keyID, int tagLoc, int count, int offset) { setKeyID(keyID); setCount(count); setTiffTagLocation(tagLoc); setValueOffset(offset); } private static void ensureNotNegative(final String argument, final int value) { if (value < 0) throw new IllegalArgumentException(Errors.format( ErrorKeys.ILLEGAL_ARGUMENT_$2, argument, value)); } public int getKeyID() { return keyID; } public int getTiffTagLocation() { return tiffTagLocation; } public int getCount() { return count; } public int getValueOffset() { return valueOffset; } public void setCount(int count) { ensureNotNegative("COUNT", count); this.count = count; } public void setKeyID(int keyID) { ensureNotNegative("ID", keyID); this.keyID = keyID; } public void setTiffTagLocation(int tagLoc) { ensureNotNegative("LOCATION", tagLoc); this.tiffTagLocation = tagLoc; } public void setValueOffset(int valueOffset) { ensureNotNegative("VALUE_OFFSET", valueOffset); this.valueOffset = valueOffset; } public int[] getValues() { return new int[] { keyID, tiffTagLocation, count, valueOffset}; } /** * According to GeoTIff spec: * * <p> * In the TIFF spec it is required that TIFF tags be written out to the file * in tag-ID sorted order. This is done to avoid forcing software to perform * N-squared sort operations when reading and writing tags. */ public int compareTo(GeoKeyEntry o) { return this.keyID>o.keyID?1:(this.keyID==o.keyID?0:1); } }