1 /*****************************************************************************
2  *                                                                            *
3  *                                 O S S I M                                  *
4  *            Open Source, Geospatial Image Processing Project                *
5  *          License: MIT, see LICENSE at the top-level directory              *
6  *                                                                            *
7  *****************************************************************************/
8 
9 #ifndef ossimHdf5ImageHandler_HEADER
10 #define ossimHdf5ImageHandler_HEADER 1
11 
12 #include <ossim/base/ossimConstants.h>
13 #include <ossim/base/ossimIrect.h>
14 #include <ossim/base/ossimRefPtr.h>
15 #include <ossim/imaging/ossimImageHandler.h>
16 #include <ossim/hdf5/ossimHdf5.h>
17 #include <ossim/hdf5/ossimHdf5ImageDataset.h>
18 #include <vector>
19 #include <string>
20 #include <mutex>
21 /**
22  * This is the base class for all imagery using HDF5 as the file format. HDF5 is unique in that it
23  * represents a variety of subformats for raster and projection information. The derived classes
24  * will need to specify the group and dataset names where the needed data lives.
25  */
26 class OSSIM_DLL ossimHdf5ImageHandler : public ossimImageHandler
27 {
28    friend class ossimHdf5ImageDataset;
29 
30 public:
31 
32    /** default constructor */
33    ossimHdf5ImageHandler();
34 
35    /** virtual destructor */
36    virtual ~ossimHdf5ImageHandler();
37 
38    /** @return "hdf5" */
39    virtual ossimString getShortName() const;
40 
41    /** @return "ossim hdf5" */
42    virtual ossimString getLongName()  const;
43 
44    /** @return "ossimH5Reader" */
45    virtual ossimString getClassName()    const;
46 
47    /**
48     *  Returns a pointer to a tile given an origin representing the upper
49     *  left corner of the tile to grab from the image.
50     *  Satisfies pure virtual from TileSource class.
51     */
52    virtual ossimRefPtr<ossimImageData> getTile(const  ossimIrect& rect,
53                                                ossim_uint32 resLevel=0);
54    /**
55     * Method to get a tile.
56     *
57     * @param result The tile to stuff.  Note The requested rectangle in full
58     * image space and bands should be set in the result tile prior to
59     * passing.  It will be an error if:
60     * result.getNumberOfBands() != this->getNumberOfOutputBands()
61     *
62     * @return true on success false on error.  If return is false, result
63     *  is undefined so caller should handle appropriately with makeBlank or
64     * whatever.
65     */
66    virtual bool getTile(ossimImageData* result, ossim_uint32 resLevel=0);
67 
68    /**
69     *  Returns the number of bands in the image.
70     *  Satisfies pure virtual from ImageHandler class.
71     */
72    virtual ossim_uint32 getNumberOfInputBands() const;
73 
74    /**
75     * Returns the number of bands in a tile returned from this TileSource.
76     * Note: we are supporting sources that can have multiple data objects.
77     * If you want to know the scalar type of an object you can pass in the
78     */
79    virtual ossim_uint32 getNumberOfOutputBands()const;
80 
81    /**
82     *  Returns the number of lines in the image.
83     *  Satisfies pure virtual from ImageHandler class.
84     */
85    virtual ossim_uint32 getNumberOfLines(ossim_uint32 reduced_res_level = 0) const;
86 
87    /**
88     *  Returns the number of samples in the image.
89     *  Satisfies pure virtual from ImageHandler class.
90     */
91    virtual ossim_uint32 getNumberOfSamples(ossim_uint32 reduced_res_level = 0) const;
92 
93    /**
94     * Returns the zero based image rectangle for the reduced resolution data
95     * set (rrds) passed in.  Note that rrds 0 is the highest resolution rrds.
96     */
97    virtual ossimIrect getImageRectangle(ossim_uint32 reduced_res_level = 0) const;
98 
99    /**
100     * Method to save the state of an object to a keyword list.
101     * Return true if ok or false on error.
102     */
103    virtual bool saveState(ossimKeywordlist& kwl,
104                           const char* prefix=0)const;
105 
106    /**
107     * Method to the load (recreate) the state of an object from a keyword
108     * list.  Return true if ok or false on error.
109     */
110    virtual bool loadState(const ossimKeywordlist& kwl,
111                           const char* prefix=0);
112 
113    /**
114     * Returns the output pixel type of the tile source.
115     */
116    virtual ossimScalarType getOutputScalarType() const;
117 
118    /**
119     * Returns the tile width of the image or 0 if the image is not tiled.
120     * Note: this is not the same as the ossimImageSource::getTileWidth which
121     * returns the output tile width which can be different than the internal
122     * image tile width on disk.
123     */
124    virtual ossim_uint32 getImageTileWidth() const;
125 
126    /**
127     * Returns the tile width of the image or 0 if the image is not tiled.
128     * Note: this is not the same as the ossimImageSource::getTileWidth which
129     * returns the output tile width which can be different than the internal
130     * image tile width on disk.
131     */
132    virtual ossim_uint32 getImageTileHeight() const;
133 
134    virtual bool isOpen() const;
135 
136    /** Close method. */
137    virtual void close();
138    virtual void loadMetaData();
139    /**
140     * @return The number of entries (images) in the image file.
141     */
142    virtual ossim_uint32 getNumberOfEntries()const;
143 
144    /**
145     * @brief Get the name of entry as a string.
146     *
147     * Example given from HDF5 file:
148     *
149     * entry_name: /All_Data/VIIRS-IMG-GTM-EDR-GEO_All/QF1_VIIRSGTMGEO
150     *
151     * @param entryIdx Zero based entry index. If out of range name will
152     * be cleared.
153     *
154     * @param name Initialized by this.
155     */
156    virtual void getEntryNames(std::vector<ossimString>& entryNames) const;
157 
158    /**
159     * @param entryList This is the list to initialize with entry indexes.
160     *
161     * @note This implementation returns puts one entry "0" in the list.
162     */
163    virtual void getEntryList(std::vector<ossim_uint32>& entryList) const;
164 
165    virtual bool setCurrentEntry(ossim_uint32 entryIdx);
166 
167    /**
168     * @return The current entry number.
169     */
170    virtual ossim_uint32 getCurrentEntry() const;
171 
172    ossimRefPtr<ossimHdf5ImageDataset> getCurrentDataset();
173 
174    /** @return Null pixel value. */
175    virtual double getNullPixelValue(ossim_uint32 band=0) const;
176    virtual double getMaxPixelValue(ossim_uint32 band=0) const;
177    virtual double getMinPixelValue(ossim_uint32 band=0) const;
178 
179    /**
180     * @brief Set propterty method. Overrides ossimImageHandler::setProperty.
181     *
182     * Current property name handled:
183     * "scale" One double value representing the scale in meters per pixel. It is
184     * assumed the scale is same for x and y direction.
185     *
186     * @param property to set.
187     */
188    virtual void setProperty(ossimRefPtr<ossimProperty> property);
189 
190    /**
191     * @brief Get propterty method. Overrides ossimImageHandler::getProperty.
192     * @param name Property name to get.
193     */
194    virtual ossimRefPtr<ossimProperty> getProperty(const ossimString& name) const;
195 
196    /**
197     * @brief Get propterty names. Overrides ossimImageHandler::getPropertyNames.
198     * @param propertyNames Array to initialize.
199     */
200    virtual void getPropertyNames(std::vector<ossimString>& propertyNames) const;
201 
202    /**  The derived class needs to initialize the raster dataset names m_renderableNames in their
203     * constructor, for this method to work. This should be implemented by the derived HDF5-format
204     * readers defined in plugins.
205     * @return true on success, false on error. */
206    virtual bool open();
207 
208    const std::vector<ossimString>& getRenderableSetNames() { return m_renderableNames; }
209 
210    /** Adds the dataset name, either the full HDF5 path or the simple object name, to the list of
211     * renderable datasets */
212    void addRenderable(const ossimString& datasetName) { m_renderableNames.push_back(datasetName); }
213 
214 protected:
215    /** @brief Allocates the tile. */
216    void allocate();
217 
218    std::vector<ossimString>         m_renderableNames;
219    ossimRefPtr<ossimHdf5>           m_hdf5;
220    std::vector<ossimRefPtr<ossimHdf5ImageDataset> > m_entries;
221    ossim_uint32                     m_currentEntry;
222    ossimRefPtr<ossimImageData>      m_tile;
223    std::mutex                       m_mutex;
224 
225    TYPE_DATA
226 };
227 
228 #endif /* #ifndef ossimH5Reader_HEADER */
229