vil_openjpeg.cxx
Go to the documentation of this file.
1 //==========
2 // Kitware (c) 2010
3 //
4 // Restrictions applicable to use by the US Government:
5 //
6 // UNLIMITED RIGHTS
7 //
8 // Restrictions applicable for all other users:
9 //
10 // This software and all information and expression are the property of Kitware, Inc. All Rights Reserved.
11 //==========
12 //:
13 // \file
14 // \brief Image I/O for JPEG2000 imagery using OpenJPEG
15 // \author Chuck Atkins
16 
17 #include <cmath>
18 #include <cstring>
19 #include <iostream>
20 #include <stdexcept>
21 #include <limits>
22 #ifdef _MSC_VER
23 # include <vcl_msvc_warnings.h>
24 #endif
25 #include <cassert>
26 
27 #include <vil/vil_stream.h>
28 #include <vbl/vbl_smart_ptr.h>
29 #include <vbl/vbl_smart_ptr.hxx>
30 #include <vil/vil_image_view.hxx>
31 
32 // TODO: How can we avoid using the "deprecated" functions?
33 #define USE_OPJ_DEPRECATED
34 extern "C" {
35  #include <openjpeg.h>
36 }
37 
38 #include "vil_openjpeg.h"
39 
40 
41 typedef vbl_smart_ptr<vil_stream> vil_stream_sptr;
42 
43 //------------------------------------------------------------------------------
44 // Taken from
45 //------------------------------------------------------------------------------
46 // class vil_openjpeg_file_format
47 //
48 
52 {
53  auto *im = new vil_openjpeg_image(vs, opjfmt);
54 
55  if ( !im->is_valid() )
56  {
57  delete im;
58  return nullptr;
59  }
60  else
61  return im;
62 }
63 
64 
68  unsigned int /*ni*/, unsigned int /*nj*/, unsigned int /*nplanes*/,
69  vil_pixel_format /*format*/, vil_openjpeg_format /*opjfmt*/)
70 {
71  assert(!"openjpeg write support is currently not implemented");
72  return nullptr;
73 }
74 
75 
76 //------------------------------------------------------------------------------
77 // Various OpenJPEG parameters and data structures
78 //
79 struct opj_header
80 {
81  vxl_uint_32 tile_width_;
82  vxl_uint_32 tile_height_;
83  vxl_uint_32 num_tiles_x_;
84  vxl_uint_32 num_tiles_y_;
85  vxl_int_32 x0_;
86  vxl_int_32 y0_;
87  vxl_uint_32 num_reductions_;
88 };
89 
90 
91 //------------------------------------------------------------------------------
92 // OpenJPEG decoder helper class
93 //
95 {
96  public:
97  vil_openjpeg_decoder(OPJ_CODEC_FORMAT opj_codec_format);
99 
100  bool error(void) const;
101  void silence(void);
102 
103  bool init_from_stream(unsigned int reduction, void *stream);
104  bool set_decode_area(unsigned int x, unsigned int y,
105  unsigned int w, unsigned int h);
106  opj_image_t * take_image(void);
107  opj_image_t * decode(void);
108 
109  const opj_header * header(void) const;
110 
111  private:
112  opj_dparameters_t params_;
113  opj_codec_t *codec_;
114  opj_image_t *image_;
115  opj_stream_t *stream_;
117  OPJ_CODEC_FORMAT opj_codec_format_;
118 
119  bool error_;
120  bool silent_;
121 
122  bool init_decoder(unsigned int reduction);
123  bool init_stream(void *stream);
124  bool read_header(void);
125 
126  // OpenJPEG I/O helper functions
127  static vxl_uint_32 opj_vil_stream_read(void *p_buffer,
128  vxl_uint_32 p_nb_bytes,
129  void *p_user_data);
130  static vxl_uint_32 opj_vil_stream_write(void *p_buffer,
131  vxl_uint_32 p_nb_bytes,
132  void *p_user_data);
133  static vxl_uint_32 opj_vil_stream_skip(vxl_uint_32 p_nb_bytes,
134  void *p_user_data);
135  static bool opj_vil_stream_seek(vxl_uint_32 p_nb_bytes,
136  void *p_user_data);
137 
138  // OpenJPEG logging functions
139  static void opj_event_info(const char *msg, void *data);
140  static void opj_event_warning(const char *msg, void *data);
141  static void opj_event_error(const char *msg, void *data);
142 };
143 
144 
145 //------------------------------------------------------------------------------
146 // OpenJPEG image internal implementation
147 //
149 {
150  // OpenJPEG data structures
151  opj_cparameters_t encode_params_;
152  opj_codec_t *encode_codec_;
153  opj_image_t *image_;
155  OPJ_CODEC_FORMAT opj_codec_format_;
156 
157  // Fields needed for the vil implementation
160  bool is_valid_;
161  bool error_;
162 
164  : encode_codec_(nullptr), image_(nullptr), vstream_(nullptr), vstream_start_(0),
165  is_valid_(false), error_(false)
166  {
167  std::memset(&this->encode_params_, 0, sizeof(opj_cparameters_t));
168  std::memset(&this->header_, 0, sizeof(opj_header));
169  }
170 };
171 
172 
173 //------------------------------------------------------------------------------
174 // class vil_openjpeg_decoder
175 //
176 
177 
179 ::vil_openjpeg_decoder(OPJ_CODEC_FORMAT opj_codec_format)
180 : codec_(nullptr), image_(nullptr), stream_(nullptr), opj_codec_format_(opj_codec_format),
181  error_(false), silent_(false)
182 {
183  std::memset(&this->params_, 0, sizeof(opj_dparameters_t));
184  std::memset(&this->header_, 0, sizeof(opj_header));
185 }
186 
187 
190 {
191  // De-allocate any necessary OpenJPEG data structures
192  if ( this->stream_ )
193  {
194  opj_stream_destroy(this->stream_);
195  this->stream_ = nullptr;
196  }
197  if ( this->codec_ )
198  {
199  opj_destroy_codec(this->codec_);
200  this->codec_ = nullptr;
201  }
202  if ( this->image_ )
203  {
204  opj_image_destroy(this->image_);
205  this->image_ = nullptr;
206  }
207 }
208 
209 
210 bool
212 ::error(void) const
213 {
214  return this->error_;
215 }
216 
217 
218 void
221 {
222  this->silent_ = true;
223 }
224 
225 
226 bool
228 ::init_from_stream(unsigned int reduction, void *stream)
229 {
230  if ( !init_stream(stream) )
231  return false;
232 
233  if ( !init_decoder(reduction) )
234  return false;
235 
236  if ( !read_header() )
237  return false;
238 
239  return true;
240 }
241 
242 
243 bool
245 ::init_stream(void *stream)
246 {
247  if ( this->stream_ )
248  {
249  opj_stream_destroy(this->stream_);
250  this->stream_ = nullptr;
251  }
252 
253  // Setup the input stream
254  this->stream_ = opj_stream_default_create(true);
255  if ( !this->stream_ )
256  return false;
257 
258  // Configure the I/O methods for the opj stream using vil operations
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_,
268 
269  return true;
270 }
271 
272 
273 bool
275 ::init_decoder(unsigned int reduction)
276 {
277  if ( this->codec_ )
278  {
279  opj_destroy_codec(this->codec_);
280  this->codec_ = nullptr;
281  }
282 
283  // Set decoder parameters
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;
288 
289  // Create the decoder
290  this->codec_ = opj_create_decompress(this->opj_codec_format_);
291  if ( !this->codec_ )
292  return false;
293 
294  // Configure the OpenJPEG event manager
295  opj_set_info_handler(this->codec_,
297  opj_set_warning_handler(this->codec_,
299  opj_set_error_handler(this->codec_,
301 
302  // Initialize the decoder
303  if ( !opj_setup_decoder( this->codec_, &this->params_) )
304  return false;
305  if ( this->error_ )
306  return false;
307 
308  return true;
309 }
310 
311 
312 bool
315 {
316  if ( this->image_ )
317  {
318  opj_image_destroy(this->image_);
319  this->image_ = nullptr;
320  }
321 
322  return opj_read_header( this->codec_,
323  &this->image_,
324  &this->header_.x0_,
325  &this->header_.y0_,
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_;
331 }
332 
333 
334 bool
336 ::set_decode_area(unsigned int x, unsigned int y,
337  unsigned int w, unsigned int h)
338 {
339  this->error_ = false;
340  return opj_set_decode_area( this->codec_, x, y, w, h ) && !this->error_;
341 }
342 
343 
344 opj_image_t *
347 {
348  opj_image_t *image = this->image_;
349  this->image_ = nullptr;
350  return image;
351 }
352 
353 
354 opj_image_t *
356 ::decode(void)
357 {
358  this->error_ = false;
359  return opj_decode(this->codec_, this->stream_);
360 }
361 
362 
363 const opj_header *
365 ::header(void) const
366 {
367  return &this->header_;
368 }
369 
370 
371 //------------------------------------------------------------------------------
372 // Helper functions to read from vil_stream objects
373 //
374 
375 vxl_uint_32
377 ::opj_vil_stream_read(void *p_buffer,
378  vxl_uint_32 p_nb_bytes,
379  void *p_user_data)
380 {
381  auto *stream = reinterpret_cast<vil_stream*>(p_user_data);
382  vil_streampos b = stream->read(p_buffer, p_nb_bytes);
383  if ( b == 0 || !stream->ok() )
384  {
385  return static_cast<vxl_uint_32>(-1);
386  }
387  if ( b > static_cast<vil_streampos>(std::numeric_limits<vxl_uint_32>::max()) )
388  {
389  throw std::runtime_error("Stream position outof range");
390  }
391  return static_cast<vxl_uint_32>(b);
392 }
393 
394 
395 vxl_uint_32
397 ::opj_vil_stream_write(void *p_buffer,
398  vxl_uint_32 p_nb_bytes,
399  void *p_user_data)
400 {
401  auto *stream = reinterpret_cast<vil_stream*>(p_user_data);
402  vil_streampos b = stream->write(p_buffer, p_nb_bytes);
403  if ( b == 0 || !stream->ok() )
404  {
405  return static_cast<vxl_uint_32>(-1);
406  }
407  if ( b > static_cast<vil_streampos>(std::numeric_limits<vxl_uint_32>::max()) )
408  {
409  throw std::runtime_error("Stream position outof range");
410  }
411  return static_cast<vxl_uint_32>(b);
412 }
413 
414 
415 vxl_uint_32
417 ::opj_vil_stream_skip(vxl_uint_32 p_nb_bytes,
418  void *p_user_data)
419 {
420  auto *stream = reinterpret_cast<vil_stream*>(p_user_data);
421  vil_streampos start = stream->tell();
422  stream->seek(start+p_nb_bytes);
423  if ( !stream->ok() )
424  {
425  return static_cast<vxl_uint_32>(-1);
426  }
427  vil_streampos end = stream->tell();
428  vil_streampos b = end-start;
429  if ( b > static_cast<vil_streampos>(std::numeric_limits<vxl_uint_32>::max()) )
430  {
431  throw std::runtime_error("Stream position outof range");
432  }
433  return static_cast<vxl_uint_32>(b);
434 }
435 
436 
437 bool
439 ::opj_vil_stream_seek( vxl_uint_32 p_nb_bytes,
440  void *p_user_data)
441 {
442  auto *stream = reinterpret_cast<vil_stream*>(p_user_data);
443  stream->seek(p_nb_bytes);
444  if ( !stream->ok() )
445  {
446  return false;
447  }
448  vil_streampos pos = stream->tell();
449  if ( pos > static_cast<vil_streampos>(std::numeric_limits<vxl_uint_32>::max()) )
450  {
451  throw std::runtime_error("Stream position outof range");
452  }
453  return p_nb_bytes == static_cast<vxl_uint_32>(pos);
454 }
455 
456 
457 //------------------------------------------------------------------------------
458 // Helper functions for OpenJPEG error handling
459 //
460 
461 void
463 ::opj_event_info(const char *msg, void * /*data*/)
464 {
465  std::clog << "vil_openjpeg_decoder::INFO : " << msg << std::endl;
466 }
467 
468 
469 void
471 ::opj_event_warning(const char *msg, void * /*data*/)
472 {
473  std::clog << "vil_openjpeg_decoder::WARN : " << msg << std::endl;
474 }
475 
476 
477 void
479 ::opj_event_error(const char *msg, void *data)
480 {
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;
485 }
486 
487 
488 //------------------------------------------------------------------------------
489 // class vil_openjpeg_image
490 //
491 
494  unsigned int /*ni*/, unsigned int /*nj*/, unsigned int /*nplanes*/,
495  vil_pixel_format /*format*/, vil_openjpeg_format /*opjfmt*/)
496 : impl_(new vil_openjpeg_image_impl)
497 {
498  assert(!"openjpeg write support is currently not implemented");
499 }
500 
501 
504 : impl_(new vil_openjpeg_image_impl)
505 {
506  switch ( opjfmt )
507  {
508  case VIL_OPENJPEG_JP2: this->impl_->opj_codec_format_ = CODEC_JP2; break;
509  case VIL_OPENJPEG_JPT: this->impl_->opj_codec_format_ = CODEC_JPT; break;
510  case VIL_OPENJPEG_J2K: this->impl_->opj_codec_format_ = CODEC_J2K; break;
511  default: return;
512  }
513 
514  this->impl_->vstream_ = is;
515  this->impl_->vstream_start_ = is->tell();
516 
517  if ( !this->validate_format() )
518  return;
519 
520  this->impl_->vstream_->seek(this->impl_->vstream_start_);
521  vil_openjpeg_decoder decoder(this->impl_->opj_codec_format_);
522  if ( !decoder.init_from_stream(0, this->impl_->vstream_.as_pointer()) )
523  return;
524 
525  // Copy headers and image from decoder
526  std::memcpy(&this->impl_->header_, decoder.header(), sizeof(opj_header));
527  this->impl_->image_ = decoder.take_image();
528 
529  // Delay num reduction computation until requested
530  this->impl_->header_.num_reductions_ = static_cast<vxl_uint_32>(-1);
531 
532 #if 0 // Move to a lazy evaluation
533  // Find out how many reductions are available
534  // There ought to be a better way to do this, but I haven't found one yet :-(
535  decoder.silence();
536  for (;;)
537  {
538  // This will fail when we ask for a reduction that doesn't exist
539  this->impl_->vstream_->seek(this->impl_->vstream_start_);
540  if ( !decoder.init_from_stream(this->impl_->header_.num_reductions_ + 1,
541  this->impl_->vstream_.as_pointer()) )
542  break;
543  // If init_from_stream succeeded, that reduction is available
544  ++this->impl_->header_.num_reductions_;
545  }
546 #endif // 0
547 
548  // No errors have occurred (except expected one) so mark success
549  this->impl_->is_valid_ = true;
550 }
551 
552 
555 {
556  // De-allocate any necessary OpenJPEG data structures
557  if ( this->impl_->image_ )
558  {
559  opj_image_destroy(this->impl_->image_);
560  this->impl_->image_ = nullptr;
561  }
562  delete this->impl_;
563 }
564 
565 
566 bool
569 {
570  vil_streampos pos_start = this->impl_->vstream_->tell();
571 
572  switch ( this->impl_->opj_codec_format_ )
573  {
574  case CODEC_JP2 :
575  {
576  // See specification ISO/IEC 15444-1 Part 1
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 )
582  {
583  this->impl_->vstream_->seek(pos_start);
584  return true;
585  }
586  break;
587  }
588  case CODEC_JPT: break; // Although supported by OpenJPEG, the JPT codec
589  // (JPEG2000 JPIP) is not yet implemented by the
590  // vil implementation
591  case CODEC_J2K:
592  {
593  // See specification ISO/IEC 15444-1 Part 1
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 )
598  {
599  this->impl_->vstream_->seek(pos_start);
600  return true;
601  }
602  break;
603  }
604  default : break;
605  }
606 
607  return false;
608 }
609 
610 
611 bool
613 ::is_valid(void) const
614 {
615  return this->impl_->is_valid_;
616 }
617 
618 
619 unsigned int
621 ::nreductions(void) const
622 {
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) )
626  {
627  vil_openjpeg_decoder decoder(this->impl_->opj_codec_format_);
628  // Find out how many reductions are available
629  // There ought to be a better way to do this, but I haven't found one yet
630  decoder.silence();
631  unsigned int num_reductions = 0;
632  for (;;)
633  {
634  // This will fail when we ask for a reduction that doesn't exist
635  this->impl_->vstream_->seek(this->impl_->vstream_start_);
636  if ( !decoder.init_from_stream(num_reductions + 1,
637  this->impl_->vstream_.as_pointer()) )
638  break;
639  // If init_from_stream succeeded, that reduction is available
640  ++num_reductions;
641  }
642  this->impl_->header_.num_reductions_ = num_reductions;
643  }
644  return this->impl_->header_.num_reductions_;
645 }
646 
647 
648 unsigned int
650 ::nplanes() const
651 {
652  if ( !this->impl_->is_valid_ )
653  return static_cast<unsigned int>(-1);
654  return this->impl_->image_->numcomps;
655 }
656 
657 
658 unsigned int
660 ::ni() const
661 {
662  if ( !this->impl_->is_valid_ )
663  return static_cast<unsigned int>(-1);
664  return this->impl_->image_->comps[0].w;
665 }
666 
667 
668 unsigned int
670 ::nj() const
671 {
672  if ( !this->impl_->is_valid_ )
673  return static_cast<unsigned int>(-1);
674  return this->impl_->image_->comps[0].h;
675 }
676 
677 
678 int
680 ::maxbpp(void) const
681 {
682  if ( !this->impl_->is_valid_ )
683  return -1;
684 
685  int maxbpp = this->impl_->image_->comps[0].prec;
686  for ( unsigned int i = 1; i < this->impl_->image_->numcomps; ++i )
687  {
688  if ( static_cast<unsigned int>(maxbpp) < this->impl_->image_->comps[i].prec )
689  maxbpp = this->impl_->image_->comps[i].prec;
690  }
691  return maxbpp;
692 }
693 
694 
695 enum vil_pixel_format
698 {
699  // NOTE:
700  // 1. Up to 32 bit pixels are supported
701  // 2. An assumption is also made by OpenJPEG that all components are integral
702  // 3. This current vil implementation will always generate unsigned
703  // components
704  switch ( this->maxbpp() )
705  {
706  case 8 : return VIL_PIXEL_FORMAT_BYTE;
707  case 16 : return VIL_PIXEL_FORMAT_UINT_16;
708  case 32 : return VIL_PIXEL_FORMAT_UINT_32;
709  default : return VIL_PIXEL_FORMAT_UNKNOWN;
710  }
711 }
712 
713 
714 const char *
717 {
718  switch ( this->impl_->opj_codec_format_ )
719  {
720  case CODEC_JP2: return "jp2";
721  case CODEC_JPT: return "jpt";
722  case CODEC_J2K: return "j2k";
723  default: return "openjpeg";
724  }
725 }
726 
727 
730 ::get_copy_view(unsigned int i0, unsigned int ni,
731  unsigned int j0, unsigned int nj) const
732 {
733  return this->get_copy_view_reduced(i0, ni, j0, nj, 0);
734 }
735 
736 
739 ::get_copy_view_reduced(unsigned int i0, unsigned int ni,
740  unsigned int j0, unsigned int nj,
741  unsigned int reduction) const
742 {
743  if ( !this->impl_->is_valid_ )
744  return nullptr;
745 
746  if ( reduction > this->impl_->header_.num_reductions_ )
747  return nullptr;
748 
749  vil_pixel_format pixel_format = this->pixel_format();
750  if ( pixel_format == VIL_PIXEL_FORMAT_UNKNOWN )
751  return nullptr;
752 
753  // Set up decoder
754  this->impl_->vstream_->seek(this->impl_->vstream_start_);
755  vil_openjpeg_decoder decoder(this->impl_->opj_codec_format_);
756  if ( !decoder.init_from_stream(reduction, this->impl_->vstream_.as_pointer()) )
757  return nullptr;
758 
759  // Configure the ROI
760  int adj_mask = ~( (1 << reduction) - 1);
761  i0 &= adj_mask; j0 &= adj_mask;
762  ni &= adj_mask; nj &= adj_mask;
763  if ( !decoder.set_decode_area( i0, j0, i0 + ni, j0 + nj ) )
764  return nullptr;
765 
766  // Decode the JPEG2000 data
767  opj_image_t *opj_view = decoder.decode();
768  if ( !opj_view || decoder.error() )
769  return nullptr;
770 
771  // Adjust ROI for reduction
772  i0 >>= reduction;
773  j0 >>= reduction;
774  ni >>= reduction;
775  nj >>= reduction;
776 
777  // Copy pixels
778  switch ( pixel_format )
779  {
780  case VIL_PIXEL_FORMAT_BYTE :
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;
787  }
788 }
789 
790 
791 template<typename T_PIXEL>
795  void *opj_view,
796  unsigned int i0, unsigned int ni, unsigned int j0, unsigned int nj) const
797 {
798  auto *opj_view_t = reinterpret_cast<opj_image_t*>(opj_view);
799  unsigned int np = opj_view_t->numcomps;
800 
801  vil_memory_chunk_sptr chunk =
802  new vil_memory_chunk(ni*nj*np*sizeof(T_PIXEL), this->pixel_format());
803 
804  auto *vil_view_t = new vil_image_view<T_PIXEL>(
805  chunk, reinterpret_cast<T_PIXEL*>(chunk->data()),
806  ni, nj, np, 1, ni, ni*nj);
807 
808  for ( unsigned int p = 0; p < np; ++p )
809  {
810  T_PIXEL sign = opj_view_t->comps[p].sgnd ?
811  1 << (opj_view_t->comps[p].prec - 1) : 0;
812 
813  int *src_plane = opj_view_t->comps[p].data;
814  T_PIXEL *dst_plane = vil_view_t->begin() + p*vil_view_t->planestep();
815 
816  for ( unsigned int j = 0; j < nj; ++j)
817  {
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();
820 
821  for ( unsigned int i = 0; i < ni; ++i )
822  {
823  *(dst_row + i*vil_view_t->istep()) = src_row[i] + sign;
824  }
825  }
826  }
827 
828  return vil_view_t;
829 }
830 
831 
832 bool
834 ::put_view(const vil_image_view_base& /*im*/, unsigned int /*i0*/, unsigned int /*j0*/)
835 {
836  assert(!"openjpeg write support is currently not implemented");
837  return false;
838 }
839 
840 
841 bool
843 ::get_property(char const* /*tag*/, void* /*property_value*/) const
844 {
845  return false;
846 }
Stream interface for VIL image loaders.
An abstract base class of smart pointers to actual image data in memory.
vil_pixel_format
Describes the type of the concrete data.
~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)
vil_stream_sptr vstream_
vil_image_resource_sptr make_input_image(vil_stream *vs, vil_openjpeg_format opjfmt)
unsigned int nplanes() const override
Dimensions: Planes x ni x nj.
vxl_uint_32 num_tiles_y_
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.
Definition: vil_fwd.h:13
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)
opj_image_t * image_
bool is_valid(void) const
bool init_decoder(unsigned int reduction)
const opj_header * header(void) const
vxl_uint_32 num_reductions_
opj_cparameters_t encode_params_
opj_image_t * decode(void)
vxl_uint_32 tile_height_
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.
Definition: vil_stream.h:21
vxl_uint_32 tile_width_
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)
bool error(void) const
enum vil_pixel_format pixel_format() const override
Pixel Format.
vil_image_resource_sptr make_output_image(vil_stream *vs, unsigned int ni, unsigned int nj, unsigned int nplanes, vil_pixel_format format, vil_openjpeg_format opjfmt)
unsigned int nj() const override
Dimensions: Planes x ni x nj.
vxl_uint_32 num_tiles_x_
vil_openjpeg_format
OpenJPEG Codec.
Definition: vil_openjpeg.h:25
vxl_int_32 x0_
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_stream_t * stream_
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)
vxl_int_32 vil_streampos
Definition: vil_stream.h:16
static bool opj_vil_stream_seek(vxl_uint_32 p_nb_bytes, void *p_user_data)
opj_codec_t * codec_
Represent images of one or more planes of Ts.
OPJ_CODEC_FORMAT opj_codec_format_
Derived image resource for JPEG2000 imagery using OpenJPEG.
Definition: vil_openjpeg.h:121
vxl_int_32 y0_
vil_streampos vstream_start_
int maxbpp(void) const