core/vil/file_formats/vil_j2k_image.h
Go to the documentation of this file.
00001 //:
00002 // \file
00003 // vil_j2k: Written by Rob Radtke (rob@) and Harry Voorhees (hlv@) of
00004 // Stellar Science Ltd. Co. (stellarscience.com) for
00005 // Air Force Research Laboratory, 2005.
00006 // Write capability added by J. Mundy, April 2009
00007 // Do not remove the following notice
00008 // Modifications approved for public Release, distribution unlimited
00009 // DISTAR Case 14074
00010 //
00011 #ifndef VIL_J2K_H
00012 #define VIL_J2K_H
00013 
00014 #include <vil/vil_image_resource.h>
00015 #include <vil/vil_file_format.h>
00016 #include <NCSECWClient.h>
00017 class CNCSFile;
00018 class vil_stream;
00019 class CNCSJPCVilIOStream;
00020 class vil_j2k_file_format : public vil_file_format
00021 {
00022  public:
00023   vil_j2k_file_format() : compression_ratio_(1){}
00024   virtual char const *tag() const;
00025   virtual vil_image_resource_sptr make_input_image(vil_stream *vs);
00026   virtual
00027     vil_image_resource_sptr make_output_image(vil_stream* vs,
00028                                               unsigned ni,
00029                                               unsigned nj,
00030                                               unsigned nplanes,
00031                                               enum vil_pixel_format format);
00032   //: This compression ratio is set as a target for the ermapper compression algorithm. The default is lossless compression (ratio == 1).
00033   void set_compression_ratio(unsigned ratio)
00034     {compression_ratio_ = ratio;}
00035  private:
00036   unsigned compression_ratio_;
00037 };
00038 
00039 //:
00040 //  Class capable of reading JPEG2000 Part I files and ECW (ER Mapper's proprietary format)
00041 //  image files.  They can either be local or hosted on an Image Web Server.  Either way, you
00042 //  just pass in the file path or url (eg. "ecwp://www.earthetc.com/images/australia/Sydney.ecw")
00043 //  to the ctor.  The call get_copy_view() to get the image data that you want.  The class efficiently
00044 //  handles reading large images (Terrabytes) -- and can read image portions without loading the whole file
00045 //  into memory.
00046 //
00047 //  Because the source image can be really big, it is possible (through the get_copy_view() API) to
00048 //  ask for more data than you can handle in memory -- or more than you download for the remote case.
00049 //  That is why the setMaxImageDimension() guard is in place.  You can set a max image dimension
00050 //  for both remote and local files (different values for each).  Then if you call get_copy_view()
00051 //  asking for an image that is too big, get_copy_view() will scale down the image to the max dimension
00052 //  you specified.  It does this silently -- perhaps we could/should change this?
00053 //
00054 //  Note that, in order to use this class, you need to use cmake to configure VXL to link against
00055 //  Er Mapper's freely available ECW JPEG 2000 SDK (http://ermapper.com/downloads/sdks.aspx#16).
00056 //
00057 // Writing implemented by J. Mundy April 2009
00058 // The SDK appears not to support float or double pixel types only integral
00059 // forms; both signed or unsigned are supported. Another caveat is that the
00060 // actual compression rate is only loosely related to the targeted compression
00061 // rate specified upon creating the resource
00062 //
00063 class vil_j2k_image : public vil_image_resource
00064 {
00065  public:
00066   //:
00067   //  \param filelOrUrl: can either be a local file (eg. /home/beavis/file1.jp2) or
00068   //  it can be a url to a file hosted on an Image Web Server (eg.
00069   //  ecwp://www.earthetc.com/images/australia/Sydney.ecw or
00070   //  ecwp://www.earthetc.com/images/usa/1metercalif.ecw
00071   vil_j2k_image( const vcl_string& fileOrUrl );
00072   //:
00073   //  Read a jpeg 2000 image from a stream containing either a raw j2k codestream
00074   //  or a jp2 file stream.  is' current position needs to be pointing at the beginning of
00075   //  one of these two things.  In other words, the beginning of the stream must contain one
00076   //  of the two signatures:
00077   //  - Hex( FF 4F )                                -- (codestream)
00078   //  - Hex( 00 00 00 0C 6A 50 20 20 0D 0A 87 0A )  -- jp2 file
00079   //
00080   //  Note that some references state that jp2 files start with ( 00 00 00 0C 6A 50 1A 1A 0D 0A 87 0A )
00081   //  [note the 1A 1A difference].  I believe this was changed between the last draft and the final version
00082   //  of ISO/IEC 155444-1 (JPEG standard).  I have never seen a real jp2 file with this old signature (including
00083   //  the official jpeg conformance test files)
00084   //
00085   //  also note: Don't use is while I'm trying to use it... it'll screw us both up.
00086   vil_j2k_image( vil_stream* is );
00087   vil_j2k_image( vil_stream* vs, unsigned ni, unsigned nj,
00088                  unsigned nplanes, enum vil_pixel_format format,
00089                  unsigned compression_ratio = 1);
00090   ~vil_j2k_image();
00091   //: Dimensions:  planes x width x height x components
00092   virtual unsigned nplanes() const;
00093   virtual unsigned ni() const;
00094   virtual unsigned nj() const;
00095   virtual enum vil_pixel_format pixel_format() const;
00096   //: returns j2k
00097   char const* file_format() const;
00098   virtual bool get_property(char const* /* tag */, void* /* property_value */ = 0) const
00099     { return false; }
00100 
00101   //: Create a read/write view of a copy of this data.
00102   // \return 0 if unable to get view of correct size.
00103   virtual vil_image_view_base_sptr get_copy_view(unsigned i0, unsigned ni,
00104                                                  unsigned j0, unsigned nj) const;
00105 
00106   virtual vil_image_view_base_sptr get_copy_view_decimated(unsigned i0, unsigned ni,
00107                                                            unsigned j0, unsigned nj,
00108                                                            double i_factor, double j_factor) const;
00109   virtual vil_image_view_base_sptr
00110     get_copy_view_decimated_by_size(unsigned i0, unsigned ni,
00111                                     unsigned j0, unsigned nj,
00112                                     unsigned int output_width,
00113                                     unsigned int output_height) const;
00114 
00115 
00116   vil_image_view_base_sptr  get_copy_view () const
00117     { return get_copy_view( 0, ni(), 0, nj() ); }
00118 
00119   //:
00120   //  Call this after construction to see if you can get valid data from me.
00121   //  If this returns false, then this image is of no use to you
00122   bool is_valid() const { return mFileResource != 0; }
00123 
00124   //:
00125   //  When calling get_copy_view(), the function will scale down the output image_view
00126   //  so that neither dimension (x or y) is greater than widthOrHeight.  This feature
00127   //  is here to protect you in the case that your code asks for an excessively large
00128   //  image that will crash your program.  You can turn this checking off with \sa unsetMaxImageDimension()
00129   //  By default, this value is set to 5000.
00130   void setMaxImageDimension( unsigned int widthOrHeight, bool remote = false );
00131   //:
00132   //  Call this if you don't want get_copy_view() to do size checking.
00133   //  Be warned that jpeg 2000 codestreams can be really big, so you could
00134   //  cause a program crash.
00135   void unsetMaxImageDimension( bool remote = false );
00136 
00137   //:
00138   //  Static function that can be used to decode a JPEG2000 codestream
00139   //  or file (jp2 file).  The stream must start at vs' current position.
00140   static vil_image_view_base_sptr s_decode_jpeg_2000( vil_stream* vs,
00141                                                       unsigned i0, unsigned ni,
00142                                                       unsigned j0, unsigned nj,
00143                                                       double i_factor, double j_factor );
00144   static vil_image_view_base_sptr
00145     s_decode_jpeg_2000_by_size( vil_stream* vs,
00146                                 unsigned i0, unsigned ni,
00147                                 unsigned j0, unsigned nj,
00148                                 unsigned int output_width,
00149                                 unsigned int output_height );
00150 
00151 
00152   //:
00153   //  Encode an entire image by loading the input resource from stream
00154   //  and compressing the input line by line by extracting an image view
00155   //  of a block of lines at a time, thus works for arbitrarily large images.
00156   //  The num_lines_block parameter is the number of image rows in the
00157   //  block which is read into memory from the resource
00158   static bool s_encode_jpeg2000(vil_stream* vs,
00159                                 const char* out_filename,
00160                                 unsigned compression_ratio = 1,
00161                                 unsigned num_lines_block = 1024,
00162                                 bool verbose = false);
00163 
00164   //: encode an entire image by loading the input resource from file
00165   //  Uses the stream-based method of the same name
00166   static bool s_encode_jpeg2000(const char* in_filename,
00167                                 const char* out_filename,
00168                                 unsigned compression_ratio = 1,
00169                                 unsigned num_lines_block = 1024,
00170                                 bool verbose = false);
00171 
00172   //: JPEG2K compress the data from the full image view and insert in resource
00173   // The compression ratio is determined when the resource is created by
00174   // the file_format class.
00175   virtual bool put_view(const vil_image_view_base& im);
00176 
00177   //: JPEG2K compress the data from an image view and insert in resource
00178   // This method cannot be implemented because the J2K SDK does not support
00179   // compressing arbitrary views. Only inserting strictly successive lines
00180   // is allowed.
00181   virtual bool put_view(const vil_image_view_base& im, unsigned i0, unsigned j0){return false;}
00182 
00183   //: JPEG2K compress by inserting an image row (line) at a time.
00184   //  When the full image has been inserted, the resource is closed
00185   //  and is no longer valid. The lines must be inserted in strict row order.
00186   bool put_line(const vil_image_view_base& im);
00187 
00188   //: Check that a view will fit into the data at the given offset.
00189   virtual bool view_fits(const vil_image_view_base& im, unsigned i0, unsigned j0);
00190  protected:
00191   //: The ermapper file
00192   CNCSFile* mFileResource;
00193   //: The ermapper stream
00194   CNCSJPCVilIOStream* mStr;
00195   //:
00196   //  \sa setMaxImageDimension and \sa unsetMaxImageDimension
00197   //
00198   //  if this equals vcl_numeric_limits<unsigned int>::max(), then this feature is turned off
00199   //  Of course I'm ignored if mRemoteFile is true
00200   unsigned int mMaxLocalDimension;
00201   //:
00202   //  Same as \sa mMaxLocalDimension but applies to remote files.
00203   //  This is typically a smaller number because of the speed concerns of downloading
00204   //  a very largeimage
00205   unsigned int mMaxRemoteDimension;
00206   //:file is remote
00207   bool mRemoteFile;
00208   //: band information array
00209   NCSFileBandInfo* mBandinfo;
00210   //: the file information block
00211   NCSFileViewFileInfoEx* mFinfo;
00212   //: the current line being written for compression
00213   unsigned line_index_;
00214 };
00215 
00216 #endif // VIL_J2K_H