TuttleOFX
1
|
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(¶meters); 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, ¶meters); 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