23 # include <vcl_msvc_warnings.h> 28 #include <vbl/vbl_smart_ptr.h> 29 #include <vbl/vbl_smart_ptr.hxx> 33 #define USE_OPJ_DEPRECATED 55 if ( !im->is_valid() )
68 unsigned int ,
unsigned int ,
unsigned int ,
71 assert(!
"openjpeg write support is currently not implemented");
100 bool error(
void)
const;
105 unsigned int w,
unsigned int h);
107 opj_image_t *
decode(
void);
128 vxl_uint_32 p_nb_bytes,
131 vxl_uint_32 p_nb_bytes,
167 std::memset(&this->encode_params_, 0,
sizeof(opj_cparameters_t));
168 std::memset(&this->header_, 0,
sizeof(
opj_header));
180 : codec_(nullptr), image_(nullptr), stream_(nullptr), opj_codec_format_(opj_codec_format),
181 error_(false), silent_(false)
183 std::memset(&this->params_, 0,
sizeof(opj_dparameters_t));
184 std::memset(&this->header_, 0,
sizeof(
opj_header));
194 opj_stream_destroy(this->stream_);
195 this->stream_ =
nullptr;
199 opj_destroy_codec(this->codec_);
200 this->codec_ =
nullptr;
204 opj_image_destroy(this->image_);
205 this->image_ =
nullptr;
222 this->silent_ =
true;
230 if ( !init_stream(stream) )
233 if ( !init_decoder(reduction) )
236 if ( !read_header() )
249 opj_stream_destroy(this->stream_);
250 this->stream_ =
nullptr;
254 this->stream_ = opj_stream_default_create(
true);
255 if ( !this->stream_ )
259 opj_stream_set_user_data(this->stream_, stream);
260 opj_stream_set_read_function(this->stream_,
262 opj_stream_set_write_function(this->stream_,
264 opj_stream_set_skip_function(this->stream_,
266 opj_stream_set_seek_function(this->stream_,
279 opj_destroy_codec(this->codec_);
280 this->codec_ =
nullptr;
284 std::memset(&this->params_, 0,
sizeof(opj_dparameters_t));
285 opj_set_default_decoder_parameters(&this->params_);
286 this->params_.cp_reduce = reduction;
287 this->params_.cp_layer = 0;
290 this->codec_ = opj_create_decompress(this->opj_codec_format_);
295 opj_set_info_handler(this->codec_,
297 opj_set_warning_handler(this->codec_,
299 opj_set_error_handler(this->codec_,
303 if ( !opj_setup_decoder( this->codec_, &this->params_) )
318 opj_image_destroy(this->image_);
319 this->image_ =
nullptr;
322 return opj_read_header( this->codec_,
326 &this->header_.tile_width_,
327 &this->header_.tile_height_,
328 &this->header_.num_tiles_x_,
329 &this->header_.num_tiles_y_,
330 this->stream_) && !this->error_;
337 unsigned int w,
unsigned int h)
339 this->error_ =
false;
340 return opj_set_decode_area( this->codec_, x, y, w, h ) && !this->error_;
348 opj_image_t *image = this->image_;
349 this->image_ =
nullptr;
358 this->error_ =
false;
359 return opj_decode(this->codec_, this->stream_);
367 return &this->header_;
378 vxl_uint_32 p_nb_bytes,
381 auto *stream = reinterpret_cast<vil_stream*>(p_user_data);
383 if ( b == 0 || !stream->ok() )
385 return static_cast<vxl_uint_32>(-1);
387 if ( b > static_cast<vil_streampos>(std::numeric_limits<vxl_uint_32>::max()) )
389 throw std::runtime_error(
"Stream position outof range");
391 return static_cast<vxl_uint_32>(b);
398 vxl_uint_32 p_nb_bytes,
401 auto *stream = reinterpret_cast<vil_stream*>(p_user_data);
403 if ( b == 0 || !stream->ok() )
405 return static_cast<vxl_uint_32>(-1);
407 if ( b > static_cast<vil_streampos>(std::numeric_limits<vxl_uint_32>::max()) )
409 throw std::runtime_error(
"Stream position outof range");
411 return static_cast<vxl_uint_32>(b);
420 auto *stream = reinterpret_cast<vil_stream*>(p_user_data);
422 stream->seek(start+p_nb_bytes);
425 return static_cast<vxl_uint_32>(-1);
429 if ( b > static_cast<vil_streampos>(std::numeric_limits<vxl_uint_32>::max()) )
431 throw std::runtime_error(
"Stream position outof range");
433 return static_cast<vxl_uint_32>(b);
442 auto *stream = reinterpret_cast<vil_stream*>(p_user_data);
443 stream->seek(p_nb_bytes);
449 if ( pos > static_cast<vil_streampos>(std::numeric_limits<vxl_uint_32>::max()) )
451 throw std::runtime_error(
"Stream position outof range");
453 return p_nb_bytes == static_cast<vxl_uint_32>(pos);
465 std::clog <<
"vil_openjpeg_decoder::INFO : " << msg << std::endl;
473 std::clog <<
"vil_openjpeg_decoder::WARN : " << msg << std::endl;
481 auto *decoder = reinterpret_cast<vil_openjpeg_decoder*>(data);
482 if ( !decoder->silent_ )
483 std::cerr <<
"vil_openjpeg_decoder::ERROR : " << msg << std::endl;
484 decoder->error_ =
true;
494 unsigned int ,
unsigned int ,
unsigned int ,
498 assert(!
"openjpeg write support is currently not implemented");
514 this->impl_->vstream_ = is;
515 this->impl_->vstream_start_ = is->
tell();
517 if ( !this->validate_format() )
520 this->impl_->vstream_->seek(this->impl_->vstream_start_);
530 this->impl_->header_.num_reductions_ = static_cast<vxl_uint_32>(-1);
532 #if 0 // Move to a lazy evaluation 539 this->impl_->vstream_->seek(this->impl_->vstream_start_);
541 this->impl_->vstream_.as_pointer()) )
544 ++this->impl_->header_.num_reductions_;
549 this->impl_->is_valid_ =
true;
557 if ( this->impl_->image_ )
559 opj_image_destroy(this->impl_->image_);
560 this->impl_->image_ =
nullptr;
572 switch ( this->impl_->opj_codec_format_ )
577 unsigned char sig[12] =
578 {0x00, 0x00, 0x00, 0x0C, 0x6A, 0x50, 0x20, 0x20, 0x0D, 0x0A, 0x87, 0x0A};
579 unsigned char sig_file[12];
580 this->impl_->vstream_->read(sig_file, 12);
581 if ( std::memcmp( sig, sig_file, 12) == 0 )
583 this->impl_->vstream_->seek(pos_start);
588 case CODEC_JPT:
break;
594 unsigned char sig[2] = {0xFF, 0x4F};
595 unsigned char sig_file[2];
596 this->impl_->vstream_->read(sig_file, 2);
597 if ( std::memcmp( sig, sig_file, 2) == 0 )
599 this->impl_->vstream_->seek(pos_start);
615 return this->impl_->is_valid_;
623 if ( !this->impl_->is_valid_ )
624 return static_cast<unsigned int>(-1);
625 if ( this->impl_->header_.num_reductions_ == static_cast<vxl_uint_32>(-1) )
631 unsigned int num_reductions = 0;
635 this->impl_->vstream_->seek(this->impl_->vstream_start_);
637 this->impl_->vstream_.as_pointer()) )
642 this->impl_->header_.num_reductions_ = num_reductions;
644 return this->impl_->header_.num_reductions_;
652 if ( !this->impl_->is_valid_ )
653 return static_cast<unsigned int>(-1);
654 return this->impl_->image_->numcomps;
662 if ( !this->impl_->is_valid_ )
663 return static_cast<unsigned int>(-1);
664 return this->impl_->image_->comps[0].w;
672 if ( !this->impl_->is_valid_ )
673 return static_cast<unsigned int>(-1);
674 return this->impl_->image_->comps[0].h;
682 if ( !this->impl_->is_valid_ )
685 int maxbpp = this->impl_->image_->comps[0].prec;
686 for (
unsigned int i = 1; i < this->impl_->image_->numcomps; ++i )
688 if ( static_cast<unsigned int>(maxbpp) < this->impl_->image_->comps[i].prec )
689 maxbpp = this->impl_->image_->comps[i].prec;
704 switch ( this->maxbpp() )
718 switch ( this->impl_->opj_codec_format_ )
720 case CODEC_JP2:
return "jp2";
721 case CODEC_JPT:
return "jpt";
722 case CODEC_J2K:
return "j2k";
723 default:
return "openjpeg";
731 unsigned int j0,
unsigned int nj)
const 733 return this->get_copy_view_reduced(i0, ni, j0, nj, 0);
740 unsigned int j0,
unsigned int nj,
741 unsigned int reduction)
const 743 if ( !this->impl_->is_valid_ )
746 if ( reduction > this->impl_->header_.num_reductions_ )
754 this->impl_->vstream_->seek(this->impl_->vstream_start_);
756 if ( !decoder.
init_from_stream(reduction, this->impl_->vstream_.as_pointer()) )
760 int adj_mask = ~( (1 << reduction) - 1);
761 i0 &= adj_mask; j0 &= adj_mask;
762 ni &= adj_mask; nj &= adj_mask;
767 opj_image_t *opj_view = decoder.
decode();
768 if ( !opj_view || decoder.
error() )
778 switch ( pixel_format )
781 return this->opj2vil<vxl_byte>(opj_view, i0, ni, j0, nj);
783 return this->opj2vil<vxl_uint_16>(opj_view, i0, ni, j0, nj);
785 return this->opj2vil<vxl_uint_32>(opj_view, i0, ni, j0, nj);
786 default:
return nullptr;
791 template<
typename T_PIXEL>
796 unsigned int i0,
unsigned int ni,
unsigned int j0,
unsigned int nj)
const 798 auto *opj_view_t = reinterpret_cast<opj_image_t*>(opj_view);
799 unsigned int np = opj_view_t->numcomps;
805 chunk, reinterpret_cast<T_PIXEL*>(chunk->data()),
806 ni, nj, np, 1, ni, ni*nj);
808 for (
unsigned int p = 0; p < np; ++p )
810 T_PIXEL sign = opj_view_t->comps[p].sgnd ?
811 1 << (opj_view_t->comps[p].prec - 1) : 0;
813 int *src_plane = opj_view_t->comps[p].data;
814 T_PIXEL *dst_plane = vil_view_t->begin() + p*vil_view_t->planestep();
816 for (
unsigned int j = 0; j < nj; ++j)
818 int *src_row = src_plane + (j0+j)*opj_view_t->comps[p].w + i0;
819 T_PIXEL *dst_row = dst_plane + j*vil_view_t->jstep();
821 for (
unsigned int i = 0; i < ni; ++i )
823 *(dst_row + i*vil_view_t->istep()) = src_row[i] + sign;
836 assert(!
"openjpeg write support is currently not implemented");
Stream interface for VIL image loaders.
An abstract base class of smart pointers to actual image data in memory.
~vil_openjpeg_image(void) override
OPJ_CODEC_FORMAT opj_codec_format_
static void opj_event_error(const char *msg, void *data)
virtual vil_streampos tell() const =0
Return file pointer.
vil_openjpeg_image(vil_stream *is, unsigned int ni, unsigned int nj, unsigned int nplanes, vil_pixel_format format, vil_openjpeg_format opjfmt)
unsigned int nplanes() const override
Dimensions: Planes x ni x nj.
vil_image_view_base_sptr opj2vil(void *opj_view, unsigned int i0, unsigned int ni, unsigned int j0, unsigned int nji) const
vbl_smart_ptr< vil_stream > vil_stream_sptr
Concrete view of image data of type T held in memory.
opj_codec_t * encode_codec_
virtual unsigned int nreductions() const
Reductions.
bool get_property(char const *tag, void *property_value=nullptr) const override
Extra property information.
bool init_stream(void *stream)
bool is_valid(void) const
bool init_decoder(unsigned int reduction)
const opj_header * header(void) const
opj_cparameters_t encode_params_
opj_image_t * decode(void)
static vxl_uint_32 opj_vil_stream_read(void *p_buffer, vxl_uint_32 p_nb_bytes, void *p_user_data)
Stream interface for VIL image loaders.
static void opj_event_info(const char *msg, void *data)
opj_image_t * take_image(void)
vil_openjpeg_decoder(OPJ_CODEC_FORMAT opj_codec_format)
enum vil_pixel_format pixel_format() const override
Pixel Format.
unsigned int nj() const override
Dimensions: Planes x ni x nj.
vil_openjpeg_format
OpenJPEG Codec.
bool init_from_stream(unsigned int reduction, void *stream)
vil_image_view_base_sptr get_copy_view() const
Create a read/write view of a copy of all the data.
opj_dparameters_t params_
virtual vil_image_view_base_sptr get_copy_view_reduced(unsigned i0, unsigned ni, unsigned j0, unsigned nj, unsigned reduction) const
Create a read/write view of a copy of this data.
Image I/O for JPEG2000 imagery using OpenJPEG.
Ref. counted block of data on the heap.
unsigned int ni() const override
Dimensions: Planes x ni x nj.
static void opj_event_warning(const char *msg, void *data)
bool put_view(const vil_image_view_base &im, unsigned int i0, unsigned int j0) override
const char * file_format() const override
Return a string describing the file format.
static vxl_uint_32 opj_vil_stream_write(void *p_buffer, vxl_uint_32 p_nb_bytes, void *p_user_data)
bool set_decode_area(unsigned int x, unsigned int y, unsigned int w, unsigned int h)
static vxl_uint_32 opj_vil_stream_skip(vxl_uint_32 p_nb_bytes, void *p_user_data)
static bool opj_vil_stream_seek(vxl_uint_32 p_nb_bytes, void *p_user_data)
Represent images of one or more planes of Ts.
OPJ_CODEC_FORMAT opj_codec_format_
Derived image resource for JPEG2000 imagery using OpenJPEG.
~vil_openjpeg_decoder(void)
vil_streampos vstream_start_
vil_openjpeg_image_impl(void)