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