1 // IIPImage class
2 
3 /*  IIP fcgi server module
4 
5     Copyright (C) 2000-2019 Ruven Pillay.
6 
7     This program is free software; you can redistribute it and/or modify
8     it under the terms of the GNU General Public License as published by
9     the Free Software Foundation; either version 3 of the License, or
10     (at your option) any later version.
11 
12     This program is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15     GNU General Public License for more details.
16 
17     You should have received a copy of the GNU General Public License
18     along with this program; if not, write to the Free Software Foundation,
19     Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
20 */
21 
22 
23 #ifndef _IIPIMAGE_H
24 #define _IIPIMAGE_H
25 
26 
27 // Fix missing snprintf in Windows
28 #if defined _MSC_VER && _MSC_VER<1900
29 #define snprintf _snprintf
30 #endif
31 
32 
33 #include <string>
34 #include <list>
35 #include <vector>
36 #include <map>
37 #include <stdexcept>
38 
39 #include "RawTile.h"
40 
41 
42 /// Define our own derived exception class for file errors
43 class file_error : public std::runtime_error {
44  public:
45   /** @param s error message */
file_error(std::string s)46   file_error(std::string s) : std::runtime_error(s) { }
47 };
48 
49 
50 // Supported image formats
51 enum ImageFormat { TIF, JPEG2000, UNSUPPORTED };
52 
53 
54 
55 /// Main class to handle the pyramidal image source
56 /** Provides functions to open, get various information from an image source
57     and get individual tiles. This class is the base class for specific image
58     file formats such as Tiled Pyramidal TIFF images via TPTImage.h and
59     JPEG2000 via Kakadu.h
60  */
61 
62 class IIPImage {
63 
64  private:
65 
66   /// Image path supplied
67   std::string imagePath;
68 
69   /// Prefix to add to paths
70   std::string fileSystemPrefix;
71 
72   /// Pattern for sequences
73   std::string fileNamePattern;
74 
75   /// Indicates whether our image is a single file or part or a sequence
76   bool isFile;
77 
78   /// Image file name suffix
79   std::string suffix;
80 
81   /// Private function to determine the image type
82   void testImageType();
83 
84   /// If we have a sequence of images, determine which horizontal angles exist
85   void measureHorizontalAngles();
86 
87   /// If we have a sequence of images, determine which vertical angles exist
88   void measureVerticalAngles();
89 
90   /// The list of available horizontal angles (for image sequences)
91   std::list <int> horizontalAnglesList;
92 
93   /// The list of available vertical angles (for image sequences)
94   std::list <int> verticalAnglesList;
95 
96 
97  protected:
98 
99   /// LUT
100   std::vector <int> lut;
101 
102   /// Number of resolution levels that don't physically exist in file
103   unsigned int virtual_levels;
104 
105   /// Return the image format e.g. tif
106   ImageFormat format;
107 
108 
109  public:
110 
111   /// The image pixel dimensions
112   std::vector <unsigned int> image_widths, image_heights;
113 
114   /// The base tile pixel dimensions
115   unsigned int tile_width, tile_height;
116 
117   /// The colour space of the image
118   ColourSpaces colourspace;
119 
120   /// The number of available resolutions in this image
121   unsigned int numResolutions;
122 
123   /// The bits per channel for this image
124   unsigned int bpc;
125 
126   /// The number of channels for this image
127   unsigned int channels;
128 
129   /// The sample format type (fixed or floating point)
130   SampleType sampleType;
131 
132   /// The min and max sample value for each channel
133   std::vector <float> min, max;
134 
135   /// Quality layers
136   unsigned int quality_layers;
137 
138   /// Indicate whether we have opened and initialised some parameters for this image
139   bool isSet;
140 
141   /// If we have an image sequence, the current X and Y position
142   int currentX, currentY;
143 
144   /// Image histogram
145   std::vector<unsigned int> histogram;
146 
147   /// STL map to hold string metadata
148   std::map <const std::string, std::string> metadata;
149 
150   /// Image modification timestamp
151   time_t timestamp;
152 
153 
154  public:
155 
156   /// Default Constructor
IIPImage()157   IIPImage()
158    : isFile( false ),
159     virtual_levels( 0 ),
160     format( UNSUPPORTED ),
161     tile_width( 0 ),
162     tile_height( 0 ),
163     colourspace( NONE ),
164     numResolutions( 0 ),
165     bpc( 0 ),
166     channels( 0 ),
167     sampleType( FIXEDPOINT ),
168     quality_layers( 0 ),
169     isSet( false ),
170     currentX( 0 ),
171     currentY( 90 ),
172     timestamp( 0 ) {};
173 
174   /// Constructer taking the image path as parameter
175   /** @param s image path
176    */
IIPImage(const std::string & s)177   IIPImage( const std::string& s )
178    : imagePath( s ),
179     isFile( false ),
180     virtual_levels( 0 ),
181     format( UNSUPPORTED ),
182     tile_width( 0 ),
183     tile_height( 0 ),
184     colourspace( NONE ),
185     numResolutions( 0 ),
186     bpc( 0 ),
187     channels( 0 ),
188     sampleType( FIXEDPOINT ),
189     quality_layers( 0 ),
190     isSet( false ),
191     currentX( 0 ),
192     currentY( 90 ),
193     timestamp( 0 ) {};
194 
195   /// Copy Constructor taking reference to another IIPImage object
196   /** @param image IIPImage object
197    */
IIPImage(const IIPImage & image)198   IIPImage( const IIPImage& image )
199    : imagePath( image.imagePath ),
200     fileSystemPrefix( image.fileSystemPrefix ),
201     fileNamePattern( image.fileNamePattern ),
202     isFile( image.isFile ),
203     suffix( image.suffix ),
204     horizontalAnglesList( image.horizontalAnglesList ),
205     verticalAnglesList( image.verticalAnglesList ),
206     lut( image.lut ),
207     virtual_levels( image.virtual_levels ),
208     format( image.format ),
209     image_widths( image.image_widths ),
210     image_heights( image.image_heights ),
211     tile_width( image.tile_width ),
212     tile_height( image.tile_height ),
213     colourspace( image.colourspace ),
214     numResolutions( image.numResolutions ),
215     bpc( image.bpc ),
216     channels( image.channels ),
217     sampleType( image.sampleType ),
218     min( image.min ),
219     max( image.max ),
220     quality_layers( image.quality_layers ),
221     isSet( image.isSet ),
222     currentX( image.currentX ),
223     currentY( image.currentY ),
224     histogram( image.histogram ),
225     metadata( image.metadata ),
226     timestamp( image.timestamp ) {};
227 
228   /// Virtual Destructor
~IIPImage()229   virtual ~IIPImage() { ; };
230 
231   /// Test the image and initialise some parameters
232   void Initialise();
233 
234   /// Swap function
235   /** @param a Object to copy to
236       @param b Object to copy from
237    */
238   void swap( IIPImage& a, IIPImage& b );
239 
240   /// Return a list of available vertical angles
getVerticalViewsList()241   std::list <int> getVerticalViewsList(){ return verticalAnglesList; };
242 
243   /// Return a list of horizontal angles
getHorizontalViewsList()244   std::list <int> getHorizontalViewsList(){ return horizontalAnglesList; };
245 
246   /// Return the image path
getImagePath()247   const std::string& getImagePath() { return imagePath; };
248 
249   /// Return the full file path for a particular horizontal and vertical angle
250   /** @param x horizontal sequence angle
251       @param y vertical sequence angle
252    */
253   const std::string getFileName( int x, int y );
254 
255   /// Get the image format
256   //  const std::string& getImageFormat() { return format; };
getImageFormat()257   ImageFormat getImageFormat() { return format; };
258 
259   /// Get the image timestamp
260   /** @param s file path
261    */
262   void updateTimestamp( const std::string& s );
263 
264   /// Get a HTTP RFC 1123 formatted timestamp
265   const std::string getTimestamp();
266 
267   /// Check whether this object has been initialised
set()268   bool set() { return isSet; };
269 
270   /// Set a file system prefix for added security
setFileSystemPrefix(const std::string & prefix)271   void setFileSystemPrefix( const std::string& prefix ) { fileSystemPrefix = prefix; };
272 
273   /// Set the file name pattern used in image sequences
setFileNamePattern(const std::string & pattern)274   void setFileNamePattern( const std::string& pattern ) { fileNamePattern = pattern; };
275 
276   /// Return the number of available resolutions in the image
getNumResolutions()277   unsigned int getNumResolutions() { return numResolutions; };
278 
279   /// Return the number of bits per pixel for this image
getNumBitsPerPixel()280   unsigned int getNumBitsPerPixel() { return bpc; };
281 
282   /// Return the number of channels for this image
getNumChannels()283   unsigned int getNumChannels() { return channels; };
284 
285   /// Return the minimum sample value for each channel
286   /** @param n channel index
287    */
288   float getMinValue( int n=0 ) { return min[n]; };
289 
290   /// Return the minimum sample value for each channel
291   /** @param n channel index
292    */
293   float getMaxValue( int n=0 ) { return max[n]; };
294 
295   /// Return the sample format type
getSampleType()296   SampleType getSampleType(){ return sampleType; };
297 
298   /// Return the image width in pixels for a given resolution
299   /** @param n resolution number (0 is default and full size image)
300    */
301   unsigned int getImageWidth( int n=0 ) { return image_widths[n]; };
302 
303   /// Return the image height in pixels for a given resolution
304   /** @param n resolution number (0 is default and full size image)
305    */
306   unsigned int getImageHeight( int n=0 ) { return image_heights[n]; };
307 
308   /// Return the base tile height in pixels for a given resolution
getTileHeight()309   unsigned int getTileHeight() { return tile_height; };
310 
311   /// Return the base tile width in pixels
getTileWidth()312   unsigned int getTileWidth() { return tile_width; };
313 
314   /// Return the colour space for this image
getColourSpace()315   ColourSpaces getColourSpace() { return colourspace; };
316 
317   /// Return image metadata
318   /** @param index metadata field name */
getMetadata(const std::string & index)319   const std::string& getMetadata( const std::string& index ) {
320     return metadata[index];
321   };
322 
323   /// Return whether this image type directly handles region decoding
regionDecoding()324   virtual bool regionDecoding(){ return false; };
325 
326   /// Load the appropriate codec module for this image type
327   /** Used only for dynamically loading codec modules. Overloaded by DSOImage class.
328       @param module the codec module path
329    */
Load(const std::string & module)330   virtual void Load( const std::string& module ) {;};
331 
332   /// Return codec description: Overloaded by child class.
getDescription()333   virtual const std::string getDescription() { return std::string( "IIPImage Base Class" ); };
334 
335   /// Open the image: Overloaded by child class.
openImage()336   virtual void openImage() { throw file_error( "IIPImage openImage called" ); };
337 
338   /// Load information about the image eg. number of channels, tile size etc.
339   /** @param x horizontal sequence angle
340       @param y vertical sequence angle
341    */
loadImageInfo(int x,int y)342   virtual void loadImageInfo( int x, int y ) { ; };
343 
344   /// Close the image: Overloaded by child class.
closeImage()345   virtual void closeImage() {;};
346 
347 
348   /// Return an individual tile for a given angle and resolution
349   /** Return a RawTile object: Overloaded by child class.
350       @param h horizontal angle
351       @param v vertical angle
352       @param r resolution
353       @param l quality layers
354       @param t tile number
355    */
getTile(int h,int v,unsigned int r,int l,unsigned int t)356   virtual RawTile getTile( int h, int v, unsigned int r, int l, unsigned int t ) { return RawTile(); };
357 
358 
359   /// Return a region for a given angle and resolution
360   /** Return a RawTile object: Overloaded by child class.
361       @param ha horizontal angle
362       @param va vertical angle
363       @param r resolution
364       @param layers number of layers to decode
365       @param x offset in x direction
366       @param y offset in y direction
367       @param w width of region
368       @param h height of region
369       @return RawTile image
370   */
getRegion(int ha,int va,unsigned int r,int layers,int x,int y,unsigned int w,unsigned int h)371   virtual RawTile getRegion( int ha, int va, unsigned int r, int layers, int x, int y, unsigned int w, unsigned int h ){ return RawTile(); };
372 
373   /// Assignment operator
374   /** @param image IIPImage object */
375   IIPImage& operator = ( IIPImage image ){
376     swap( *this, image );
377     return *this;
378   };
379 
380   /// Comparison equality operator
381   friend int operator == ( const IIPImage&, const IIPImage& );
382 
383   /// Comparison non-equality operator
384   friend int operator != ( const IIPImage&, const IIPImage& );
385 
386 };
387 
388 
389 #endif
390