Skip to content

Commit

Permalink
Updated exception handling to use std::invalid_argument and a new der…
Browse files Browse the repository at this point in the history
…ived file_error exception within the IIPImage and derived classes. Allows better distinguishing between HTTP status errors
  • Loading branch information
ruven committed Aug 6, 2014
1 parent 3512f1c commit e79cf0e
Show file tree
Hide file tree
Showing 11 changed files with 93 additions and 57 deletions.
6 changes: 6 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
06/08/2014:
- Updated exception handling to use std::invalid_argument and a new derived file_error
exception within the IIPImage and derived classes. Allows better distinguishing between
HTTP status errors.


05/08/2014:
- Added flip function to Transforms.
- Modified JTL, DeepZoom, Zoomify and CVT to avoid float conversion if not required.
Expand Down
1 change: 1 addition & 0 deletions src/CVT.cc
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ void CVT::run( Session* session, const std::string& a ){
session->out->printf( (const char*) str );
#endif


// Get our requested region from our TileManager
TileManager tilemanager( session->tileCache, *session->image, session->watermark, session->jpeg, session->logfile, session->loglevel );
RawTile complete_image = tilemanager.getRegion( requested_res,
Expand Down
2 changes: 1 addition & 1 deletion src/FIF.cc
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ void FIF::run( Session* session, const string& src ){

// Check whether cache is empty
if( session->imageCache->empty() ){
if( session->loglevel >= 1 ) *(session->logfile) << "FIF :: Image cache initialisation" << endl;
if( session->loglevel >= 1 ) *(session->logfile) << "FIF :: Image cache initialization" << endl;
test = IIPImage( argument );
test.setFileNamePattern( filename_pattern );
test.setFileSystemPrefix( filesystem_prefix );
Expand Down
18 changes: 9 additions & 9 deletions src/IIPImage.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

/* IIP fcgi server module
Copyright (C) 2000-2013 Ruven Pillay.
Copyright (C) 2000-2014 Ruven Pillay.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -75,7 +75,7 @@ void IIPImage::swap( IIPImage& first, IIPImage& second ) // nothrow



void IIPImage::testImageType()
void IIPImage::testImageType() throw(file_error)
{
// Check whether it is a regular file
struct stat sb;
Expand All @@ -91,7 +91,7 @@ void IIPImage::testImageType()
FILE *im = fopen( path.c_str(), "rb" );
if( im == NULL ){
string message = "Unable to open file '" + path + "'";
throw message;
throw file_error( message );
}

// Read and close immediately
Expand All @@ -101,7 +101,7 @@ void IIPImage::testImageType()
// Make sure we were able to read enough bytes
if( len < 10 ){
string message = "Unable to read initial byte sequence from file '" + path + "'";
throw message;
throw file_error( message );
}

// Magic file signature for JPEG2000
Expand Down Expand Up @@ -133,12 +133,12 @@ void IIPImage::testImageType()
if( glob( filename.c_str(), 0, NULL, &gdat ) != 0 ){
globfree( &gdat );
string message = path + string( " is neither a file nor part of an image sequence" );
throw message;
throw file_error( message );
}
if( gdat.gl_pathc != 1 ){
globfree( &gdat );
string message = string( "There are multiple file extensions matching " ) + filename;
throw message;
throw file_error( message );
}

string tmp( gdat.gl_pathv[0] );
Expand All @@ -155,7 +155,7 @@ void IIPImage::testImageType()

#else
string message = path + string( " is not a regular file and no glob support enabled" );
throw message;
throw file_error( message );
#endif

}
Expand All @@ -164,14 +164,14 @@ void IIPImage::testImageType()



void IIPImage::updateTimestamp( const string& path ) throw(string)
void IIPImage::updateTimestamp( const string& path ) throw(file_error)
{
// Get a modification time for our image
struct stat sb;

if( stat( path.c_str(), &sb ) == -1 ){
string message = string( "Unable to open file " ) + path;
throw message;
throw file_error( message );
}
timestamp = sb.st_mtime;
}
Expand Down
17 changes: 13 additions & 4 deletions src/IIPImage.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

/* IIP fcgi server module
Copyright (C) 2000-2013 Ruven Pillay.
Copyright (C) 2000-2014 Ruven Pillay.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -34,10 +34,19 @@
#include <list>
#include <vector>
#include <map>
#include <stdexcept>

#include "RawTile.h"


/// Define our own derived exception class for file errors
class file_error : public std::runtime_error {
public:
file_error(std::string s) : std::runtime_error(s) { }
};



/// Main class to handle the pyramidal image source
/** Provides functions to open, get various information from an image source
and get individual tiles. This class is the base class for specific image
Expand Down Expand Up @@ -65,7 +74,7 @@ class IIPImage {
std::string suffix;

/// Private function to determine the image type
void testImageType();
void testImageType() throw( file_error );

/// If we have a sequence of images, determine which horizontal angles exist
void measureHorizontalAngles();
Expand Down Expand Up @@ -223,7 +232,7 @@ class IIPImage {
/// Get the image timestamp
/** @param s file path
*/
void updateTimestamp( const std::string& s ) throw( std::string );
void updateTimestamp( const std::string& s ) throw( file_error );

/// Get a HTTP RFC 1123 formatted timestamp
const std::string getTimestamp();
Expand Down Expand Up @@ -297,7 +306,7 @@ class IIPImage {
virtual const std::string getDescription() { return std::string( "IIPImage Base Class" ); };

/// Open the image: Overloaded by child class.
virtual void openImage() { throw std::string( "IIPImage openImage called" ); };
virtual void openImage() { throw file_error( "IIPImage openImage called" ); };

/// Load information about the image eg. number of channels, tile size etc.
/** @param x horizontal sequence angle
Expand Down
36 changes: 18 additions & 18 deletions src/KakaduImage.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
Culture of the Czech Republic.
Copyright (C) 2009-2013 IIPImage.
Authors: Ruven Pillay & Petr Pridal
Copyright (C) 2009-2014 IIPImage.
Authors: Ruven Pillay
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -52,7 +52,7 @@ unsigned int get_nprocs_conf(){


#include "Timer.h"
#define DEBUG 0
#define DEBUG 1


using namespace std;
Expand All @@ -62,7 +62,7 @@ extern std::ofstream logfile;
#endif


void KakaduImage::openImage() throw (string)
void KakaduImage::openImage() throw (file_error)
{
string filename = getFileName( currentX, currentY );

Expand All @@ -84,20 +84,20 @@ void KakaduImage::openImage() throw (string)
if( jpx_input.open( &src, false ) != 1 ) throw 1;
}
catch (...){
throw string( "Kakadu :: Unable to open '"+filename+"'"); // Rethrow the exception
throw file_error( "Kakadu :: Unable to open '"+filename+"'"); // Rethrow the exception
}

// Get our JPX codestream
jpx_stream = jpx_input.access_codestream(0);
if( !jpx_stream.exists() ) throw string( "Kakadu :: No codestream in file '"+filename+"'"); // Throw exception
if( !jpx_stream.exists() ) throw file_error( "Kakadu :: No codestream in file '"+filename+"'"); // Throw exception

// Open the underlying JPEG2000 codestream
input = NULL;
input = jpx_stream.open_stream();

// Create codestream
codestream.create(input);
if( !codestream.exists() ) throw string( "Kakadu :: Unable to create codestream for '"+filename+"'"); // Throw exception
if( !codestream.exists() ) throw file_error( "Kakadu :: Unable to create codestream for '"+filename+"'"); // Throw exception

// Set up the cache size and allow restarting
//codestream.augment_cache_threshold(1024);
Expand All @@ -115,7 +115,7 @@ void KakaduImage::openImage() throw (string)
}


void KakaduImage::loadImageInfo( int seq, int ang ) throw(string)
void KakaduImage::loadImageInfo( int seq, int ang ) throw(file_error)
{
jp2_channels j2k_channels;
jp2_palette j2k_palette;
Expand Down Expand Up @@ -262,7 +262,7 @@ void KakaduImage::closeImage()


// Get an invidual tile
RawTile KakaduImage::getTile( int seq, int ang, unsigned int res, int layers, unsigned int tile ) throw (string)
RawTile KakaduImage::getTile( int seq, int ang, unsigned int res, int layers, unsigned int tile ) throw (file_error)
{

// Scale up our output bit depth to the nearest factor of 8
Expand All @@ -278,7 +278,7 @@ RawTile KakaduImage::getTile( int seq, int ang, unsigned int res, int layers, un
if( res > numResolutions ){
ostringstream tile_no;
tile_no << "Kakadu :: Asked for non-existant resolution: " << res;
throw tile_no.str();
throw file_error( tile_no.str() );
}

int vipsres = ( numResolutions - 1 ) - res;
Expand All @@ -299,7 +299,7 @@ RawTile KakaduImage::getTile( int seq, int ang, unsigned int res, int layers, un
if( tile >= ntlx*ntly ){
ostringstream tile_no;
tile_no << "Kakadu :: Asked for non-existant tile: " << tile;
throw tile_no.str();
throw file_error( tile_no.str() );
}

// Alter the tile size if it's in the last column
Expand Down Expand Up @@ -329,7 +329,7 @@ RawTile KakaduImage::getTile( int seq, int ang, unsigned int res, int layers, un
// Create our raw tile buffer and initialize some values
if( obpp == 16 ) rawtile.data = new unsigned short[tw*th*channels];
else if( obpp == 8 ) rawtile.data = new unsigned char[tw*th*channels];
else throw string( "Kakadu :: Unsupported number of bits" );
else throw file_error( "Kakadu :: Unsupported number of bits" );

rawtile.dataLength = tw*th*channels*obpp/8;
rawtile.filename = getImagePath();
Expand All @@ -350,7 +350,7 @@ RawTile KakaduImage::getTile( int seq, int ang, unsigned int res, int layers, un


// Get an entire region and not just a tile
RawTile KakaduImage::getRegion( int seq, int ang, unsigned int res, int layers, int x, int y, unsigned int w, unsigned int h ) throw (string)
RawTile KakaduImage::getRegion( int seq, int ang, unsigned int res, int layers, int x, int y, unsigned int w, unsigned int h ) throw (file_error)
{
// Scale up our output bit depth to the nearest factor of 8
unsigned int obpp = bpp;
Expand All @@ -366,7 +366,7 @@ RawTile KakaduImage::getRegion( int seq, int ang, unsigned int res, int layers,

if( obpp == 16 ) rawtile.data = new unsigned short[w*h*channels];
else if( obpp == 8 ) rawtile.data = new unsigned char[w*h*channels];
else throw string( "Kakadu :: Unsupported number of bits" );
else throw file_error( "Kakadu :: Unsupported number of bits" );

rawtile.dataLength = w*h*channels*obpp/8;
rawtile.filename = getImagePath();
Expand All @@ -384,7 +384,7 @@ RawTile KakaduImage::getRegion( int seq, int ang, unsigned int res, int layers,


// Main processing function
void KakaduImage::process( unsigned int res, int layers, int xoffset, int yoffset, unsigned int tw, unsigned int th, void *d ) throw (string)
void KakaduImage::process( unsigned int res, int layers, int xoffset, int yoffset, unsigned int tw, unsigned int th, void *d ) throw (file_error)
{
// Scale up our output bit depth to the nearest factor of 8
unsigned int obpp = bpp;
Expand Down Expand Up @@ -418,7 +418,7 @@ void KakaduImage::process( unsigned int res, int layers, int xoffset, int yoffse
canvas_dims.size = kdu_coords( tw, th );

// Check our codestream status - throw exception for malformed codestreams
if( !codestream.exists() ) throw string( "Kakadu :: Malformed JPEG2000 - unable to access codestream");
if( !codestream.exists() ) throw file_error( "Kakadu :: Malformed JPEG2000 - unable to access codestream");

// Apply our resolution restrictions to calculate the rendering zone on the highest resolution
// canvas
Expand Down Expand Up @@ -565,7 +565,7 @@ void KakaduImage::process( unsigned int res, int layers, int xoffset, int yoffse


if( !decompressor.finish() ){
throw( "Kakadu :: Error indicated by finish()" );
throw file_error( "Kakadu :: Error indicated by finish()" );
}


Expand Down Expand Up @@ -610,7 +610,7 @@ void KakaduImage::process( unsigned int res, int layers, int xoffset, int yoffse
delete_buffer( stripe_buffer );
delete_buffer( buffer );
if( stripe_heights ) delete[] stripe_heights;
throw string( "Kakadu :: Core Exception Caught"); // Rethrow the exception
throw file_error( "Kakadu :: Core Exception Caught"); // Rethrow the exception
}


Expand Down
14 changes: 7 additions & 7 deletions src/KakaduImage.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
Culture of the Czech Republic.
Copyright (C) 2009-2013 IIPImage.
Authors: Ruven Pillay & Petr Pridal
Copyright (C) 2009-2014 IIPImage.
Authors: Ruven Pillay
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -116,7 +116,7 @@ class KakaduImage : public IIPImage {
@param h height of region
@param d buffer to fill
*/
void process( unsigned int r, int l, int x, int y, unsigned int w, unsigned int h, void* d ) throw (std::string);
void process( unsigned int r, int l, int x, int y, unsigned int w, unsigned int h, void* d ) throw (file_error);

/// Convenience function to delete allocated buffers
/** @param b pointer to buffer
Expand Down Expand Up @@ -166,14 +166,14 @@ class KakaduImage : public IIPImage {
~KakaduImage() { closeImage(); };

/// Overloaded function for opening a TIFF image
void openImage() throw (std::string);
void openImage() throw (file_error);


/// Overloaded function for loading TIFF image information
/** @param x horizontal sequence angle
@param y vertical sequence angle
*/
void loadImageInfo( int x, int y ) throw (std::string);
void loadImageInfo( int x, int y ) throw (file_error);

/// Overloaded function for closing a JPEG2000 image
void closeImage();
Expand All @@ -188,7 +188,7 @@ class KakaduImage : public IIPImage {
@param l number of quality layers to decode
@param t tile number
*/
RawTile getTile( int x, int y, unsigned int r, int l, unsigned int t ) throw (std::string);
RawTile getTile( int x, int y, unsigned int r, int l, unsigned int t ) throw (file_error);

/// Overloaded function for returning a region for a given angle and resolution
/** Return a RawTile object: Overloaded by child class.
Expand All @@ -202,7 +202,7 @@ class KakaduImage : public IIPImage {
@param h height of region
@param b buffer to fill
*/
RawTile getRegion( int ha, int va, unsigned int r, int l, int x, int y, unsigned int w, unsigned int h ) throw (std::string);
RawTile getRegion( int ha, int va, unsigned int r, int l, int x, int y, unsigned int w, unsigned int h ) throw (file_error);


};
Expand Down
20 changes: 20 additions & 0 deletions src/Main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -661,6 +661,26 @@ int main( int argc, char *argv[] )

}

// Image file errors
catch( const file_error& error ){
string status = "Status: 404 Not Found\r\nServer: iipsrv/" + version + "\r\n\r\n" + error.what();
writer.printf( status.c_str() );
writer.flush();
if( loglevel >= 2 ){
logfile << "Sending HTTP 404 Not Found" << endl;
}
}

// Parameter errors
catch( const invalid_argument& error ){
string status = "Status: 400 Bad Request\r\nServer: iipsrv/" + version + "\r\n\r\n" + error.what();
writer.printf( status.c_str() );
writer.flush();
if( loglevel >= 2 ){
logfile << "Sending HTTP 400 Bad Request" << endl;
}
}

/* Default catch
*/
catch( ... ){
Expand Down
Loading

0 comments on commit e79cf0e

Please sign in to comment.