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