1 //---
2 //
3 // License: MIT
4 //
5 // Author:  David Burken
6 //
7 // Description: Generic image writer class.
8 //
9 //---
10 // $Id$
11 #ifndef ossimWriter_HEADER
12 #define ossimWriter_HEADER 1
13 
14 #include <ossim/base/ossimConstants.h>
15 #include <ossim/base/ossimIpt.h>
16 #include <ossim/imaging/ossimImageFileWriter.h>
17 #include <iosfwd>
18 #include <vector>
19 
20 class ossimKeywordlist;
21 class ossimProperty;
22 
23 /**
24  * @brief ossimWriter - Generic image writer.
25  *
26  * Please do NOT add any external library dependencies. drb - 26 May 2016
27  */
28 class OSSIM_DLL ossimWriter : public ossimImageFileWriter
29 {
30 public:
31 
32    /** default constructor */
33    ossimWriter();
34 
35    /** virtual destructor */
36    virtual ~ossimWriter();
37 
38    /** @return "ossim_writer" */
39    virtual ossimString getShortName() const;
40 
41    /** @return "ossim writer" */
42    virtual ossimString getLongName() const;
43 
44    /** @return "ossimWriter" */
45    virtual ossimString getClassName() const;
46 
47    /**
48     * Returns a 3-letter extension from the image type descriptor
49     * (theOutputImageType) that can be used for image file extensions.
50     *
51     * @param imageType string representing image type.
52     *
53     * @return the 3-letter string extension.
54     */
55    virtual ossimString getExtension() const;
56 
57    /**
58     * @brief getImageTypeList method.
59     *
60     * Satisfies ossimImageFileWriter::getImageTypeList pure virtual.
61     *
62     * Appends the writers image types to the "imageTypeList".
63     *
64     * Current write type:
65     * ossim_ttbs - tiled tiff band separate, big tiff format.
66     *
67     * @param imageTypeList list to append to.
68     */
69    virtual void getImageTypeList(std::vector<ossimString>& imageTypeList) const;
70 
71    /**
72     * @brief isOpen
73     * @return true if open; else, false.
74     */
75    virtual bool isOpen()const;
76 
77    /**
78     * @brief open
79     * @return true on success, false on error.
80     */
81    virtual bool open();
82 
83    /** @brief close Flushes and deletes stream if we own it. */
84    virtual void close();
85 
86    bool hasImageType(const ossimString& imageType) const;
87 
88    /**
89     * @brief Method to write the image to a stream.
90     *
91     * @return true on success, false on error.
92     */
93    virtual bool writeStream();
94 
95    /**
96     * @brief Sets the output stream to write to.
97     *
98     * This sets the stream and sets m_ownsStreamFlag to false. So destructor
99     * will not delete the stream if this method is used.
100     *
101     * @param stream The stream to write to.
102     * @return true if object can write to stream, false if not.
103     */
104    virtual bool setOutputStream(std::ostream& str);
105 
106    /**
107     * @brief Sets the output tile size for tiled formats.
108     * @param tileSize Must be a multiple of 16.
109     */
110    virtual void setTileSize(const ossimIpt& tileSize);
111 
112    /**
113     * @brief Gets the tile size.
114     * @return Reference to tile size.
115     */
116    virtual const ossimIpt& getOutputTileSize() const;
117 
118    /**
119     * @brief Saves the state of the object.
120     */
121    virtual bool saveState(ossimKeywordlist& kwl,
122                           const char* prefix=0)const;
123 
124    /**
125     * Method to the load (recreate) the state of an object from a keyword
126     * list.  Return true if ok or false on error.
127     */
128    virtual bool loadState(const ossimKeywordlist& kwl,
129                           const char* prefix=0);
130 
131    /**
132     * Will set the property whose name matches the argument
133     * "property->getName()".
134     *
135     * @param property Object containing property to set.
136     */
137    virtual void setProperty(ossimRefPtr<ossimProperty> property);
138 
139    /**
140     * @param name Name of property to return.
141     *
142     * @returns A pointer to a property object which matches "name".  Returns
143     * NULL if no match is found.
144     */
145    virtual ossimRefPtr<ossimProperty> getProperty(const ossimString& name) const;
146 
147    /**
148     * Pushes this's names onto the list of property names.
149     *
150     * @param propertyNames array to add this's property names to.
151     */
152    virtual void getPropertyNames(std::vector<ossimString>& propertyNames) const;
153 
154 
155 
156 protected:
157 
158    /**
159     * @brief Write out the file.
160     * @return true on success, false on error.
161     */
162    virtual bool writeFile();
163 
164 private:
165 
166    /**
167     * @brief Writes a tiled tiff band separate to stream.
168     * @return true on success, false on error.
169     */
170    bool writeStreamTtbs();
171 
172    /**
173     * @brief Writes tiff header to stream.
174     * @return true on success, false on error.
175     */
176    bool writeTiffHdr();
177 
178    /**
179     * @brief Writes tags to image file directory(IFD).
180     * @param tile_offsets
181     * @param tile_byte_counts
182     * @param minBands
183     * @param maxBands
184     * @return true on success, false on error.
185     */
186    bool writeTiffTags( const std::vector<ossim_uint64>& tile_offsets,
187                        const std::vector<ossim_uint64>& tile_byte_counts,
188                        const std::vector<ossim_float64>& minBands,
189                        const std::vector<ossim_float64>& maxBands );
190 
191    /**
192     * @brief Writes tags TIFFTAG_MINSAMPLEVALUE(280) and
193     * TIFFTAG_MAXSAMPLEVALUE(281).  Only written if scalar type is an unsigned
194     * byte or short.
195     * @return true on success, false on error.
196     */
197    bool writeMinMaxTiffTags( std::streamoff& arrayWritePos  );
198 
199 
200    /**
201     * @brief Writes tags TIFFTAG_SMINSAMPLEVALUE(340) and
202     * TIFFTAG_SMAXSAMPLEVALUE(341).  Only written if scalar type is not an
203     * unsigned byte or short.
204     * @param minBands Array of min values from image write.
205     * @param maxBands Array of max values from image write.
206     * @return true if tags are written, false if not.
207     * A false return is not necessarily an error, just means the
208     * tags were not written due to the scalar type.
209     */
210    bool writeSMinSMaxTiffTags( const std::vector<ossim_float64>& minBands,
211                              const std::vector<ossim_float64>& maxBands,
212                              std::streamoff& arrayWritePos  );
213 
214    /**
215     * @brief Writes tiff tag to image file directory(IFD).
216     * @param tag
217     * @param type
218     * @param count
219     * @param value(s) or offset to array.
220     * @param arrayWritePos Position to write array to.  This will be updated
221     * if array is written with new offset.
222     */
223    template <class T> void writeTiffTag(ossim_uint16 tag, ossim_uint16 type,
224                                         ossim_uint64 count,
225                                         const T* value,
226                                         std::streamoff& arrayWritePos );
227 
228    /**
229     * @brief Writes image data to stream.
230     *
231     * Data is in a band separate tile layout(PLANARCONFIG_SEPARATE), i.e. all
232     * the red tiles, all the green tiles, all the blue tiles.
233     *
234     * @param tile_offsets Initialized by this with offset for each tile.
235     * @param tile_byte_counts Initialized by this with the byte count of each
236     * tile.
237     * @param minBands Initialized by this with the min values for each band.
238     * @param maxBands Initialized by this with the max values for each band.
239     * @return true on success, false on error.
240     */
241    bool writeTiffTilesBandSeparate( std::vector<ossim_uint64>& tile_offsets,
242                                     std::vector<ossim_uint64>& tile_byte_counts,
243                                     std::vector<ossim_float64>& minBands,
244                                     std::vector<ossim_float64>& maxBands );
245 
246    /**
247     * @brief Gets the tiff sample format based on scalar type.
248     * E.g SAMPLEFORMAT_UINT, SAMPLEFORMAT_INT or SAMPLEFORMAT_IEEEFP.
249     * @return TIFF sample format or 0 if not mapped to a scalar type.
250     */
251    ossim_uint16 getTiffSampleFormat() const;
252 
253    /**
254     *  @return true if the output type is tiled, false if not.
255     */
256    bool isTiled() const;
257 
258    /**
259     * @return Value of options key: "align_tiles".
260     * If true, aligns tile addresses to 4096 boundary.
261     * default=true
262     */
263    bool getAlignTilesFlag() const;
264 
265    /**
266     * @return Value of options key: "flush_tiles".
267     * If true, aligns tile addresses to block boundary.
268     * default=true
269     */
270    ossim_int64 getBlockSize() const;
271 
272    /**
273     * @return Value of options key: "flush_tiles".
274     * If true, std::ostream::flush() is called after each tile write.
275     * default=true
276     */
277    bool getFlushTilesFlag() const;
278 
279    /**
280     * @return Value of options key: "include_blank_tiles".
281     * If true, empty/blank tiles will be written; if false, the tile will not
282     * be written, the tile offset and byte count will be set to zero.
283     * default=true (write blanks).
284     */
285    bool getWriteBlanksFlag() const;
286 
287    bool needsMinMax() const;
288 
289    std::ostream* m_str;
290    bool          m_ownsStreamFlag;
291 
292    /** Hold all options. */
293    ossimRefPtr<ossimKeywordlist> m_kwl;
294 
295    ossimIpt      m_outputTileSize;
296 
297 }; // End: class ossimWriter
298 
299 #endif /* End of "#ifndef ossimWriter_HEADER" */
300