TuttleOFX  1
J2KReader.cpp
Go to the documentation of this file.
00001 #include "J2KReader.hpp"
00002 #include "J2KCommon.hpp"
00003 
00004 #include <tuttle/plugin/global.hpp>
00005 #include <tuttle/plugin/exceptions.hpp>
00006 
00007 #include "ofxsMemory.h"
00008 #include "ofxsCore.h"
00009 
00010 #include <openjpeg.h>
00011 
00012 #include <boost/filesystem.hpp>
00013 
00014 #include <cstdlib>
00015 #include <cstring>
00016 
00017 namespace tuttle {
00018 namespace io {
00019 
00020 namespace fs = boost::filesystem;
00021 
00022 J2KReader::J2KReader()
00023 {
00024         _fileData = NULL;
00025         _dataLength = 0;
00026         memset(&_openjpeg, 0, sizeof(OpenJpegStuffs));
00027 }
00028 
00029 J2KReader::~J2KReader()
00030 {
00031         close();
00032 }
00033 
00034 void J2KReader::open(const std::string & filename)
00035 {
00036         close();
00037         if( ! fs::exists( filename ) )
00038         {
00039                 BOOST_THROW_EXCEPTION( exception::FileNotExist()
00040                         << exception::filename(filename) );
00041         }
00042 
00043         fs::ifstream inputDataStream;
00044         inputDataStream.open(filename, std::ios_base::binary);
00045 
00046         if( ! inputDataStream.is_open() )
00047         {
00048                 BOOST_THROW_EXCEPTION( exception::File()
00049                         << exception::user( "Unable to open file." )
00050                         <<exception::filename(filename) );
00051         }
00052         uint32_t magic;
00053 
00054         // read the input file and put it in memory
00055         // ----------------------------------------
00056         inputDataStream.read( (char*)&magic, sizeof( int ) );
00057         if( inputDataStream.fail() )
00058         {
00059                 inputDataStream.close();
00060                 BOOST_THROW_EXCEPTION( exception::Value()
00061                         << exception::dev( "Unable to read magic number." )
00062                         <<exception::filename(filename) );
00063         }
00064         if( magic != MAYBE_MAGIC && magic != MAYBE_REV_MAGIC )
00065         {
00066                 inputDataStream.close();
00067                 BOOST_THROW_EXCEPTION( exception::Value()
00068                         << exception::dev( "Invalid magic number." )
00069                         << exception::filename(filename) );
00070         }
00071 
00072         inputDataStream.seekg(0, std::ios::end);
00073         std::ssize_t dataLength = inputDataStream.tellg();
00074         inputDataStream.seekg(0, std::ios::beg);
00075         if( dataLength != _dataLength || !_fileData )
00076         {
00077                 if( _fileData )
00078                 {
00079                         OFX::memory::free(_fileData);
00080                 }
00081                 _fileData = (uint8_t*)OFX::memory::allocate(dataLength);
00082         }
00083         inputDataStream.read( (char*)_fileData, dataLength );
00084         if( inputDataStream.fail() )
00085         {
00086                 inputDataStream.close();
00087                 OFX::memory::free(_fileData);
00088                 _fileData = NULL;
00089                 _dataLength = 0;
00090                 BOOST_THROW_EXCEPTION( exception::Value()
00091                         << exception::dev( "Unable to read image data." )
00092                         << exception::filename(filename) );
00093         }
00094         inputDataStream.close();
00095         _dataLength = dataLength;
00096 }
00097 
00098 void J2KReader::decode(bool headeronly)
00099 {
00100         if( !_fileData || !_dataLength )
00101         {
00102                 BOOST_THROW_EXCEPTION( exception::Bug()
00103                         << exception::dev( "Need to open the file before decoding." ) );
00104         }
00105         opj_dparameters_t       parameters;       // decompression parameters
00106         opj_dinfo_t             *dinfo = NULL;    // handle to a decompressor
00107         opj_cio_t               *cio = NULL;
00108 
00109         _openjpeg.event_mgr.error_handler = NULL;
00110         _openjpeg.event_mgr.warning_handler = NULL;
00111         _openjpeg.event_mgr.info_handler = NULL;
00112         opj_set_default_decoder_parameters(&parameters);
00113 
00114         if (headeronly)
00115         {
00116                 parameters.cp_limit_decoding = LIMIT_TO_MAIN_HEADER;
00117         }
00118 
00119         // Decompress a JPEG-2000 codestream
00120         // get a decoder handle
00121         dinfo = opj_create_decompress(CODEC_J2K);
00122         // Catch events using our callbacks and give a local context
00123         opj_set_event_mgr((opj_common_ptr) dinfo, &_openjpeg.event_mgr, stderr );
00124         // setup the decoder decoding parameters using user parameters
00125         opj_setup_decoder(dinfo, &parameters);
00126         if( !dinfo )
00127         {
00128                 BOOST_THROW_EXCEPTION( exception::Unknown()
00129                         << exception::dev( "Failed to open decoder for image." ) );
00130         }
00131         // open a byte stream
00132         cio = opj_cio_open((opj_common_ptr)dinfo, _fileData, _dataLength);
00133         if( !cio )
00134         {
00135                 opj_destroy_decompress( dinfo );
00136                 BOOST_THROW_EXCEPTION( exception::Unknown()
00137                         << exception::dev( "Failed to open decoder for image." ) );
00138         }
00139         // Start decoding to get an image
00140         if( _openjpeg.image )
00141         {
00142                 opj_image_destroy( _openjpeg.image );
00143         }
00144         _openjpeg.image = opj_decode( dinfo, cio );
00145         // close the byte stream
00146         opj_destroy_decompress( dinfo );
00147         opj_cio_close( cio );
00148         if( !_openjpeg.image )
00149         {
00150                 BOOST_THROW_EXCEPTION( exception::Unknown()
00151                         << exception::dev( "Failed to decode image." ) );
00152         }
00153 }
00154 
00155 void J2KReader::close()
00156 {
00157         if ( _openjpeg.image )
00158         {
00159                 opj_image_destroy( _openjpeg.image );
00160                 _openjpeg.image = NULL;
00161         }
00162 
00163         if (_fileData)
00164         {
00165                 OFX::memory::free(_fileData);
00166                 _fileData = NULL;
00167         }
00168         _dataLength = 0;
00169         memset(&_openjpeg, 0, sizeof(OpenJpegStuffs));
00170 }
00171 
00172 }
00173 }
00174