001: package it.geosolutions.imageio.plugins.jhdf.aps;
002:
003: import it.geosolutions.imageio.plugins.jhdf.BaseHDFImageReader;
004: import it.geosolutions.imageio.plugins.jhdf.SubDatasetInfo;
005:
006: import java.io.IOException;
007: import java.util.Iterator;
008: import java.util.LinkedHashMap;
009: import java.util.List;
010: import java.util.Set;
011:
012: import javax.imageio.metadata.IIOMetadata;
013: import javax.imageio.spi.ImageReaderSpi;
014:
015: import ncsa.hdf.object.Attribute;
016: import ncsa.hdf.object.Dataset;
017: import ncsa.hdf.object.Datatype;
018: import ncsa.hdf.object.Group;
019: import ncsa.hdf.object.HObject;
020: import ncsa.hdf.object.ScalarDS;
021:
022: /**
023: * Specific Implementation of the <code>BaseHDFImageReader</code> needed to
024: * work on HDF produced by the Navy's APS (Automated Processing System)
025: *
026: * @author Romagnoli Daniele
027: */
028: public class APSImageReader extends BaseHDFImageReader {
029:
030: public APSImageReader(ImageReaderSpi originatingProvider) {
031: super (originatingProvider);
032: }
033:
034: /** The Products Dataset List contained within the APS File */
035: private String[] productList;
036:
037: private APSImageMetadata imageMetadata;
038:
039: private APSStreamMetadata streamMetadata;
040:
041: private void checkImageIndex(int imageIndex) {
042: // TODO: Implements the imageIndex coherency check
043:
044: // if (imageIndex < 0
045: // || (!hasSubDatasets && imageIndex > 0)
046: // || (hasSubDatasets && ((nSubdatasets == 0 && imageIndex > 0) ||
047: // (nSubdatasets != 0 && (imageIndex > nSubdatasets))))) {
048: //
049: // // The specified imageIndex is not valid.
050: // // Retrieving the valid image index range.
051: // final int validImageIndex = hasSubDatasets ? nSubdatasets
052: // : 0;
053: // StringBuffer sb = new StringBuffer(
054: // "Illegal imageIndex specified = ").append(imageIndex)
055: // .append(", while the valid imageIndex");
056: // if (validImageIndex > 0)
057: // // There are N Subdatasets.
058: // sb.append(" range should be (0,").append(validImageIndex - 1)
059: // .append(")!!");
060: // else
061: // // Only the imageIndex 0 is valid.
062: // sb.append(" should be only 0!");
063: // throw new IndexOutOfBoundsException(sb.toString());
064: // }
065: }
066:
067: /**
068: * Retrieve APS main information.
069: *
070: * @param root
071: *
072: * @throws Exception
073: */
074: protected void initializeProfile() throws Exception {
075: // Getting the Member List from the provided root
076: final List membersList = ((Group) root).getMemberList();
077: final Iterator metadataIt = root.getMetadata().iterator();
078:
079: int subdatasetsNum = 0;
080: while (metadataIt.hasNext()) {
081: // get the attribute
082: final Attribute attrib = (Attribute) metadataIt.next();
083: final String attribName = attrib.getName();
084: // Checking if the attribute is related to the products list
085: if (attribName.equalsIgnoreCase("prodList")) {
086: Object valuesList = attrib.getValue();
087: final String[] values = (String[]) valuesList;
088: String products[] = values[0].split(",");
089: productList = refineProductList(products);
090: subdatasetsNum = productList.length;
091: break;
092: }
093: }
094: final int listSize = membersList.size();
095:
096: subDatasetsMap = new LinkedHashMap(subdatasetsNum);
097: sourceStructure = new SourceStructure(subdatasetsNum);
098:
099: // Scanning all the datasets
100: for (int i = 0; i < listSize; i++) {
101: final HObject member = (HObject) membersList.get(i);
102: if (member instanceof ScalarDS) {
103: final String name = member.getName();
104: for (int j = 0; j < subdatasetsNum; j++) {
105:
106: // Checking if the actual dataset is a product.
107: if (name.equals(productList[j])) {
108: // Updating the subDatasetsMap map
109: subDatasetsMap.put(name, member);
110:
111: // retrieving subDataset main properties
112: // (Rank, dims, chunkSize)
113: final int rank = ((Dataset) member).getRank();
114: final long[] dims = ((Dataset) member)
115: .getDims();
116:
117: final long[] chunkSize = ((Dataset) member)
118: .getChunkSize();
119:
120: final long[] subDatasetDims = new long[rank];
121: final long[] subDatasetChunkSize;
122: long datasetSize = 1;
123:
124: // copying values to avoid altering dataset
125: // fields.
126: for (int k = 0; k < rank; k++) {
127: subDatasetDims[k] = dims[k];
128:
129: // when rank > 2, X and Y are the last
130: // 2 coordinates. As an instance, for a
131: // 3D subdatasets, 3rd dimension has
132: // index 0.
133: if (k < rank - 2)
134: datasetSize *= dims[k];
135: }
136: if (chunkSize != null) {
137: subDatasetChunkSize = new long[rank];
138: for (int k = 0; k < rank; k++)
139: subDatasetChunkSize[k] = chunkSize[k];
140: } else
141: subDatasetChunkSize = null;
142:
143: final Datatype dt = ((Dataset) member)
144: .getDatatype();
145: // instantiating a SubDatasetInfo
146: SubDatasetInfo dsInfo = new SubDatasetInfo(
147: name, rank, subDatasetDims,
148: subDatasetChunkSize, dt);
149: sourceStructure.setSubDatasetSize(j,
150: datasetSize);
151: sourceStructure.setSubDatasetInfo(j, dsInfo);
152: }
153: }
154: }
155: }
156: }
157:
158: /**
159: * Reduces the product's list by removing not interesting ones. As an
160: * instance the dataset containing l2_flags will be not presented.
161: *
162: * @param products
163: * The originating <code>String</code> array containing the
164: * list of products to be checked.
165: * @return A <code>String</code> array containing a refined list of
166: * products
167: */
168: private String[] refineProductList(String[] products) {
169: final int inputProducts = products.length;
170: int j = 0;
171: final boolean[] accepted = new boolean[inputProducts];
172:
173: for (int i = 0; i < inputProducts; i++)
174: if (isAcceptedItem(products[i])) {
175: accepted[i] = true;
176: j++;
177: } else
178: accepted[i] = false;
179: if (j == inputProducts)
180: return products;
181: final String[] returnedProductsList = new String[j];
182: j = 0;
183: for (int i = 0; i < inputProducts; i++) {
184: if (accepted[i])
185: returnedProductsList[j++] = products[i];
186: }
187: return returnedProductsList;
188: }
189:
190: protected boolean isAcceptedItem(String productName) {
191: // if (attribName.endsWith("_flags"))
192: // return false;
193: if (APSProperties.apsProducts.getHDFProduct(productName) != null)
194: return true;
195: return false;
196: }
197:
198: public IIOMetadata getImageMetadata(int imageIndex)
199: throws IOException {
200: checkImageIndex(imageIndex);
201: SubDatasetInfo sdInfo = sourceStructure
202: .getSubDatasetInfo(retrieveSubDatasetIndex(imageIndex));
203: if (imageMetadata == null)
204: imageMetadata = new APSImageMetadata(sdInfo);
205: return imageMetadata;
206: }
207:
208: public int getNumImages(boolean allowSearch) throws IOException {
209: return sourceStructure.getNSubdatasets();
210: }
211:
212: public IIOMetadata getStreamMetadata() throws IOException {
213: if (streamMetadata == null)
214: streamMetadata = new APSStreamMetadata(root);
215: return streamMetadata;
216: }
217:
218: public void dispose() {
219: super .dispose();
220: synchronized (mutex) {
221: final Set set = subDatasetsMap.keySet();
222: final Iterator setIt = set.iterator();
223:
224: // Cleaning HashMap
225: while (setIt.hasNext()) {
226: Dataset ds = (Dataset) subDatasetsMap.get(setIt.next());
227: // TODO:Restore original properties?
228: // TODO: Close datasets
229: }
230: subDatasetsMap.clear();
231: }
232: }
233:
234: public void reset() {
235: super .reset();
236: streamMetadata = null;
237: imageMetadata = null;
238: productList = null;
239: }
240:
241: protected int getBandNumberFromProduct(String productName) {
242: return APSProperties.apsProducts.getHDFProduct(productName)
243: .getNBands();
244: }
245:
246: }
|