1 //----------------------------------------------------------------------------
2 // File: ossimImageUtil.h
3 //
4 // License:  MIT
5 //
6 // See LICENSE.txt file in the top level directory for more details.
7 //
8 // Author:  David Burken
9 //
10 // Description: ossimImageUtil
11 //
12 // See class descriptions below for more.
13 //
14 //----------------------------------------------------------------------------
15 // $Id$
16 
17 #ifndef ossimImageUtil_HEADER
18 #define ossimImageUtil_HEADER 1
19 
20 #include <ossim/base/ossimConstants.h>
21 #include <ossim/base/ossimFileProcessorInterface.h>
22 #include <ossim/base/ossimKeywordlist.h>
23 #include <ossim/base/ossimReferenced.h>
24 #include <ossim/base/ossimRefPtr.h>
25 #include <ossim/imaging/ossimImageHandler.h>
26 #include <ossim/imaging/ossimOverviewBuilderBase.h>
27 #include <ostream>
28 #include <vector>
29 #include <mutex>
30 
31 class ossimArgumentParser;
32 class ossimFileWalker;
33 class ossimGpt;
34 class ossimPropertyInterface;
35 class ossimApplicationUsage;
36 class ossimImageHandler;
37 /**
38  * @brief ossimImageUtil class.
39  *
40  * Utility class for processing image recursively.  This is for doing things like:
41  *
42  * building overview, histograms, compute min/max, extract vertices.
43  */
44 class OSSIM_DLL ossimImageUtil :
45    public ossimReferenced, public ossimFileProcessorInterface
46 {
getClassName()47 public:
48 
49    /** default constructor */
50    ossimImageUtil();
51 
52    /** virtual destructor */
53    virtual ~ossimImageUtil();
54 
55    void addOptions(ossimApplicationUsage* au);
56    /**
57     * @brief Adds application arguments to the argument parser.
58     * @param ap Parser to add to.
59     */
60    void addArguments(ossimArgumentParser& ap);
61 
62    /**
63     * @brief Initial method.
64     *
65     * Typically called from application prior to execute.  This parses
66     * all options and put in keyword list m_kwl.
67     *
68     * @param ap Arg parser to initialize from.
69     *
70     * @return true, indicating process should continue with execute.
71     */
72    bool initialize(ossimArgumentParser& ap);
73 
74    /**
75     * @brief Execute method.
76     *
77     * This launches file walking mechanism.
78     *
79     * @return int, 0 = good, non-zero something happened.  Because this can
80     * process multiple files a non-zero return may indicate just one file
81     * did not complete, e.g. building overviews.
82     *
83     * @note Throws ossimException on error.
84     */
85    ossim_int32 execute();
86 
87    /**
88     * @brief ProcessFile method.
89     *
90     * Satisfies pure virtual ossimFileProcessorInterface::processFile.
91     *
92     * This method is linked to the ossimFileWalker::walk method via a callback
93     * mechanism.  It is called by the ossimFileWalk (caller).  In turn this
94     * class (callee) calls ossimFileWalker::setRecurseFlag and
95     * ossimFileWalker::setAbortFlag to control the waking process.
96     *
97     * @param file to process.
98     */
99    virtual void processFile(const ossimFilename& file);
100 
101    /**
102     * @brief Sets create overviews flag keyword CREATE_OVERVIEWS_KW used by
103     * processFile method.
104     *
105     * @param flag If true overview will be created if image does not already
106     * have the required or if the REBUILD_OVERVIEWS_KW is set.
107     *
108     * @note Number of required overviews is controlled by the ossim preferences
109     * keyword overview_stop_dimension.
110     */
111    void setCreateOverviewsFlag(bool flag);
112 
113    /** @return true if CREATE_OVERVIEWS_KW is found and set to true. */
114    bool createOverviews() const;
115 
116    /**
117     * @brief Sets create thumbnails flag keyword CREATE_THUMBNAILS_KW used by
118     * processFile method.
119     *
120     * @param flag If true thumbnail will be created if image does not already.
121     *
122     * @note Overviews must be created before this works
123     */
124    void setCreateThumbnailsFlag(bool flag);
PatchProcessorJob(hlzUtil,origin,chip_id)125 
126    /**
127     *  @param value can be of values png or jpeg
128     */
129    void setThumbnailType(const std::string& value);
130 
131    /**
132     * @param value can be of values none,auto-minmax,auto-percentile,std-stretch-1,std-stretch-2,std-stretch-3
133     */
134    void setThumbnailStretchType(const std::string& value);
135 
136    /** @return true if CREATE_THUMBNAILS_KW is found and set to true. */
PatchProcessorJob(hlzUtil,origin,chip_id)137    bool createThumbnails() const;
138 
139    /**
140     * @brief Sets the rebuild overview flag keyword REBUILD_OVERVIEWS_KW used by
141     * processFile method.
142     *
143     * @param flag If true forces a rebuild of overviews even if image has
144     * required number of reduced resolution data sets.
145     *
146     * @note Number of required overviews is controlled by the ossim preferences
147     * keyword overview_stop_dimension.
148     */
149    void setRebuildOverviewsFlag( bool flag );
150 
151    /** @return true if REBUILD_OVERVIEWS_KW is found and set to true. */
152    bool rebuildOverviews() const;
153 
154    /**
155     * @brief Sets the rebuild histogram flag keyword REBUILD_HISTOGRAM_KW used by
156     * processFile method.
157     *
158     * @param flag If true forces a rebuild of histogram even if image has one already.
159     */
160    void setRebuildHistogramFlag( bool flag );
161 
162    /** @return true if REBUILD_HISTOGRAM_KW is found and set to true. */
163    bool rebuildHistogram() const;
164 
165    /**
166     * @brief Sets key OVERVIEW_TYPE_KW.
167     *
168     * Available types depends on plugins.  Known types:
169     * ossim_tiff_box ( defualt )
170     * ossim_tiff_nearest
171     * ossim_kakadu_nitf_j2k ( kakadu plugin )
172     * gdal_tiff_nearest	    ( gdal plugin )
173     * gdal_tiff_average	    ( gdal plugin )
174     * gdal_hfa_nearest      ( gdal plugin )
175     * gdal_hfa_average      ( gdal plugin )
176     *
177     * @param type One of the above.
178     */
179    void setOverviewType( const std::string& type );
180 
181    /**
182     * @brief sets the overview stop dimension.
183     *
184     * The overview builder will decimate the image until both dimensions are
185     * at or below this dimension.
186     *
187     * @param dimension
188     *
189     * @note Recommend a power of 2 value, i.e. 8, 16, 32 and so on.
190     */
191    void setOverviewStopDimension( ossim_uint32 dimension );
192    void setOverviewStopDimension( const std::string& dimension );
193 
194    /**
195     * @brief Sets the tile size.
196     *
197     * @param tileSize
198     *
199     * @note Must be a multiple of 16, i.e. 64, 128, 256 and so on.
200     */
201    void setTileSize( ossim_uint32 tileSize );
202 
203    /**
204     * @brief Gets the tile size.
205     * @param tileSize Initialized by this.
206     * @return true on success, false if not in options list.
207     */
208    bool getTileSize( ossimIpt& tileSize ) const;
209 
210    /**
211     * @return Overview stop dimension or 0 if OVERVIEW_STOP_DIM_KW is not
212     * found.
213     */
214    ossim_uint32 getOverviewStopDimension() const;
215 
216    /**
217     * @brief Sets create histogram flag keyword CREATE_HISTOGRAM_KW used by
218     * processFile method.
219     *
220     * @param flag If true a full histogram will be created.
221     */
222    void setCreateHistogramFlag( bool flag );
223 
224    /** @return true if CREATE_HISTOGRAM_KW is found and set to true. */
225    bool createHistogram() const;
226 
227    /**
228     * @brief Sets create histogram flag keyword CREATE_HISTOGRAM_FAST_KW used by
229     * processFile method.
230     *
231     * @param flag If true a histogram will be created in fast mode.
232     */
233    void setCreateHistogramFastFlag( bool flag );
234 
235    /** @return true if CREATE_HISTOGRAM_FAST_KW is found and set to true. */
236    bool createHistogramFast() const;
237 
238    /**
239     * @brief Sets create histogram "R0" flag keyword CREATE_HISTOGRAM_R0_KW used by
240     * processFile method.
241     *
242     * @param flag If true a histogram will be created from R0.
243     */
244    void setCreateHistogramR0Flag( bool flag );
245 
246    /** @return true if CREATE_HISTOGRAM_R0_KW is found and set to true. */
247    bool createHistogramR0() const;
248 
249    /** @return true if any of the histogram options are set. */
250    bool hasHistogramOption() const;
251 
252    /** @return Histogram mode or OSSIM_HISTO_MODE_UNKNOWN if not set. */
253    ossimHistogramMode getHistogramMode() const;
254 
255    /**
256     * @brief Sets scan for min/max flag keyword SCAN_MIN_MAX_KW used by
257     * processFile method.
258     *
259     * @param flag If true a file will be scanned for min/max and a file.omd
260     * will be written out.
261     */
262    void setScanForMinMax( bool flag );
263 
264    /** @return true if SCAN_MIN_MAX_KW is found and set to true. */
265    bool scanForMinMax() const;
266 
267    /**
268     * @brief Sets scan for min/max/null flag keyword SCAN_MIN_MAX_KW used by
269     * processFile method.
270     *
271     * @param flag If true a file will be scanned for min/max/null and a file.omd
272     * will be written out.
273     */
274    void setScanForMinMaxNull( bool flag );
275 
276    /** @return true if SCAN_MIN_MAX_NULL_KW is found and set to true. */
277    bool scanForMinMaxNull() const;
278 
279    /**
280     * @brief Sets the writer property for compression quality.
281     *
282     * @param quality For TIFF JPEG takes values from 1
283     * to 100, where 100 is best.  For J2K plugin (if available),
284     * numerically_lossless, visually_lossless, lossy.
285     */
286    void setCompressionQuality( const std::string& quality );
287 
288    /**
289     * @brief Sets the compression type to use when building overviews.
290     *
291     * @param compression_type Current supported types:
292     * - deflate
293     * - jpeg
294     * - lzw
295     * - none
296     * - packbits
297     */
298    void setCompressionType( const std::string& type );
299 
300    /**
301     * @brief Sets the overview builder copy all flag.
302     * @param flag
303     */
304    void setCopyAllFlag( bool flag );
305 
306    /**
307     * @return true if COPY_ALL_FLAG_KW key is found and value is true; else,
308     * false.
309     */
310    bool getCopyAllFlag() const;
311 
312    /**
313     * @brief Sets the dump filteredImageList flag.
314     * @param flag
315     */
316    void setDumpFilteredImageListFlag( bool flag );
317 
318    /**
319     * @return true if DUMP_FILTERED_IMAGES_KW key is found and value is true; else,
320     * false.
321     *
322     * DUMP_FILTERED_IMAGES_KW = "dump_filtered_images"
323     */
324    bool getDumpFilterImagesFlag() const;
325 
326    /**
327     * @brief Sets the overview builder internal overviews flag.
328     * @param flag
329     */
330    void setInternalOverviewsFlag( bool flag );
331 
332    /**
333     * @return true if INTERNAL_OVERVIEWS_FLAG_KW key is found and value is true; else,
334     * false.
335     */
336    bool getInternalOverviewsFlag() const;
337 
338    /**
339     * @brief Sets the output directory.  Typically overviews and histograms
340     * are placed parallel to image file.  This overrides.
341     *
342     * @param directory
343     */
344    void setOutputDirectory( const std::string& directory );
345 
346    /**
347     * @brief Sets the output file name flag OUTPUT_FILENAMES_KW.
348     *
349     * If set to true all files that we can successfully open will be output.
350     *
351     * @param flag
352     */
353    void setOutputFileNamesFlag( bool flag );
354 
355    /**
356     * @return true if OUTPUT_FILENAMES_KW key is found and value is true; else,
357     * false.
358     */
359    bool getOutputFileNamesFlag() const;
360 
361    /**
362     * @brief Sets the override filtered images flag.
363     * @param flag
364     */
365    void setOverrideFilteredImagesFlag( bool flag );
366 
367    /**
368     * @return true if DUMP_FILTERED_IMAGES_KW key is found and value is true; else,
369     * false.
370     *
371     * DUMP_FILTERED_IMAGES_KW = "dump_filtered_images"
372     */
373    bool getOverrideFilteredImagesFlag() const;
374 
375    /**
376     * @brief Set number of threads to use.
377     *
378     * This is only used in execute method if a directory is given to
379     * application to walk.
380     *
381     * @param threads Defaults to 1 if THREADS_KW is not found.
382     */
383    void setNumberOfThreads( ossim_uint32 threads );
384    void setNumberOfThreads( const std::string& threads );
385 
386    /** @return The list of filtered out files. */
387    const std::vector<std::string>& getFilteredImages() const;
388 
389    /**
390     * @brief Non const method to allow access for
391     * adding or deleting extensions from the list.
392     *
393     * The list is used by the private isFiltered method to avoid trying to
394     * process unwanted files.
395     */
396    std::vector<std::string>& getFilteredImages();
397 
398 private:
399 
400    /** @return true if key is set to true; false, if not. */
401    bool keyIsTrue( const std::string& key ) const;
402 
403    /**
404     * @brief Convenience method to check file to see is if file should be
405     * processed.
406     *
407     * @param f File to check.
408     *
409     * @return true if f is in filter list, false if not.
410     */
411    bool isFiltered(const ossimFilename& f) const;
412 
413    /**
414     * @brief Initializes the filter list with a default set of filtered out
415     * file names.
416     */
417    void initializeDefaultFilterList();
418 
419    /** @brief Dumps filtered image list to std out. */
420    void dumpFilteredImageList() const;
421 
422    void createOverview(ossimRefPtr<ossimImageHandler>& ih,
423                        bool& consumedHistogramOptions,
424                        bool& consumedCmmOptions);
425 
426    void createOverview(ossimRefPtr<ossimImageHandler>& ih,
427                        ossimRefPtr<ossimOverviewBuilderBase>& ob,
428                        ossim_uint32 entry,
429                        bool useEntryIndex,
430                        bool& consumedHistogramOptions);
431 
432    void createThumbnail(ossimRefPtr<ossimImageHandler> &ih);
433 
434    /** @return true if entry has required overviews. */
435    bool hasRequiredOverview( ossimRefPtr<ossimImageHandler>& ih,
436                              ossimRefPtr<ossimOverviewBuilderBase>& ob );
437 
438    /** @return true if any compute min, max or null options are set. */
439    bool hasCmmOption() const;
440 
441    void createHistogram(ossimRefPtr<ossimImageHandler>& ih);
442 
443    void createHistogram(ossimRefPtr<ossimImageHandler>& ih,
444                        ossim_uint32 entry,
445                        bool useEntryIndex);
446 
447    void computeMinMax(ossimRefPtr<ossimImageHandler>& ih);
448 
449    void computeMinMax(ossimRefPtr<ossimImageHandler>& ih,
450                       ossim_uint32 entry,
451                       bool useEntryIndex);
452 
453    /** @brief Initializes arg parser and outputs usage. */
454    void usage(ossimArgumentParser& ap);
455 
456    void outputOverviewWriterTypes() const;
457 
458    /**
459     * @return true if file is a directory based image and the stager should go
460     * on to next directory; false if stager should continue with directory.
461     */
462    bool isDirectoryBasedImage(const ossimImageHandler* ih) const;
463 
464    /**
465     * @brief Initializes type from OVERVIEW_TYPE_KW or sets to default
466     * ossim_tiff_box if not found.
467     */
468    void getOverviewType(std::string& type) const;
469 
470    /** @brief set reader or writer properties based on cast of pi. */
471    void setProps(ossimPropertyInterface* pi) const;
472 
473    /**
474     * @return Threads to use.  Defaults to 1 if THREADS_KW is not found.
475     */
476    ossim_uint32 getNumberOfThreads() const;
477 
478    /** @return the next writer prop index. */
479    ossim_uint32 getNextWriterPropIndex() const;
480 
481    /** @return the next reader prop index. */
482    ossim_uint32 getNextReaderPropIndex() const;
483 
484    /** @return the next reader prop index. */
485    ossim_uint32 getThumbnailSize() const;
486 
487    int getThumbnailStretchType()const;
488    std::string getThumbnailType()const;
489    std::string getThumbnailFilename(ossimImageHandler *ih) const;
490    /**
491     * @brief Adds option to m_kwl with mutex lock.
492     * @param key
493     * @param value
494     */
495    void addOption(const std::string &key, ossim_uint32 value);
496    void addOption( const std::string& key, const std::string& value );
497 
498    /**
499     * @brief Sets the m_errorStatus for return on execute.
500     */
501    void setErrorStatus( ossim_int32 status );
502 
503    /** @brief run prep system commands. */
504    void executePrepCommands() const;
505 
506    /** @brief run per file system commands. */
507    void executeFileCommands( const ossimFilename& file ) const;
508 
509    /** @brief run post system commands. */
510    void executePostCommands() const;
511 
512    /** @brief system commands. */
513    void executeCommands( const std::string& prefix,
514                          const ossimFilename& file ) const;
515 
516     /** @brief Expands variables in a command string. */
517    void substituteCommandString( const ossimFilename& file,
518                                  const std::string& prefix,
519                                  const std::string& commandKey,
520                                  ossimString& command ) const;
521 
522    /** @brief Expands file level variables in a command string. */
523    void substituteFileStrings( const ossimFilename& file,
524                                ossimString& command ) const;
525 
526     /** @brief Expands date variables in a command string. */
527    void gsubDate( const std::string& commandPrefix,
528                   ossimString& command ) const;
529 
530    /** Holds all options passed into intialize except writer props. */
531    ossimRefPtr<ossimKeywordlist> m_kwl;
532 
533    ossimFileWalker*   m_fileWalker;
534    std::mutex m_mutex;
535 
536    ossim_int32 m_errorStatus;
537 
538    /** Hold images we never want to process. */
539    std::vector<std::string> m_filteredImages;
540 };
541 
542 #endif /* #ifndef ossimImageUtil_HEADER */
543