diff --git a/Utilities/otbossim/include/ossim/imaging/ossimImageModel.h b/Utilities/otbossim/include/ossim/imaging/ossimImageModel.h new file mode 100644 index 0000000000000000000000000000000000000000..ba82afbcd98b7981b0c12cd7a43b613f94dfbb91 --- /dev/null +++ b/Utilities/otbossim/include/ossim/imaging/ossimImageModel.h @@ -0,0 +1,189 @@ +//----------------------------------------------------------------------------- +// +// License: LGPL +// +// See LICENSE.txt file in the top level directory for more details. +// +// Author: David Burken +// +// Description: Class declaration of ossimImageModel. +// +//----------------------------------------------------------------------------- +// $Id$ + +#ifndef ossimImageModel_HEADER +#define ossimImageModel_HEADER 1 + +#include <vector> +#include <ossim/base/ossimConstants.h> +#include <ossim/base/ossimObject.h> +#include <ossim/base/ossimDpt.h> +#include <ossim/base/ossimRtti.h> + +class ossimDrect; +class ossimImageHandler; + +/** + * @brief Class to handle transforming image points, rectangles, and offsets + * from one reduced resolution data set (rrds) level to another. + * + * Derived from ossimObject only so users can pass via the + * ossimViewInterface::setView method. + */ +class OSSIM_DLL ossimImageModel : public ossimObject +{ +public: + + /** @brief default constructor */ + ossimImageModel(); + + /** @brief virtual destructor */ + virtual ~ossimImageModel(); + + /** + * @brief Method to initialize class from an image handler. + * + * @param ih Image handler. + */ + virtual void initialize(const ossimImageHandler& ih); + + /** + * @brief Get r0 point from rn point. + * + * @param rrds Source (rnPt) reduced resolution data set. + * + * @param rnPt The image point to tranform. + * + * @param r0Pt the Point to initialize. + * + * @note Throws ossimException on out of range rrds. + */ + void rnToR0(ossim_uint32 rrds, + const ossimDpt& rnPt, + ossimDpt& r0Pt) const; + + /** + * @brief Get r0 point from rn point. + * + * This requires calling setTargetRrds(ossim_uint32 rrds) to the level + * for rnPt. + * + * @param rnPt The image point to tranform. + * + * @param r0Pt the Point to initialize. + * + * @note Throws ossimException on out of range rrds. + * + * @see setTargetRrds + */ + void rnToR0(const ossimDpt& rnPt, ossimDpt& r0Pt) const; + + /** + * @brief Get rn point from r0 point. + * + * @param rrds Target (rnPt) reduced resolution data set. + * + * @param r0Pt The image point to tranform. + * + * @param rnPt the Point to initialize. + * + * @note Throws ossimException on out of range rrds. + */ + void r0ToRn(ossim_uint32 rrds, + const ossimDpt& r0Pt, + ossimDpt& rnPt) const; + + /** + * @brief Get rn point from r0 point. + * + * This requires calling setTargetRrds(ossim_uint32 rrds) to the level + * for rnPt. + * + * @param r0Pt The image point to tranform. + * + * @param rnPt the Point to initialize. + * + * @note Throws ossimException on out of range rrds. + * + * @see setTargetRrds + */ + void r0ToRn(const ossimDpt& r0Pt, + ossimDpt& rnPt) const; + + /** + * @brief Get the sub image offset for a given resolution level. + * + * @param rrds The reduced resolution data set. + * + * @param offset the Point to initialize. + * + * @note Throws ossimException on out of range rrds. + */ + void getSubImageOffset(ossim_uint32 rrds, ossimDpt& offset) const; + + /** + * @brief Gets the zero-based image rectangle for a given reduced resolution + * data set. + * + * @param rrds The reduced resolution data set. + * + * @param rect Initialized with image rectangle for rrds. + * + * @note Throws ossimException on out of range rrds. + */ + void getImageRectangle(ossim_uint32 rrds, ossimDrect& rect) const; + + /** + * @brief Gets the model-based image rectangle for a given reduced + * resolution data set. + * + * If this image is a sub image the offset is applied. So if the image + * has a sub image offset of (1024, 1024), and has 1024 lines and 1024 + * samples the rectangle for r0 will be: (1024, 1024) (2047, 2047) + * + * @param rrds The reduced resolution data set. + * + * @param rect Initialized with image rectangle for rrds. + * + * @note Throws ossimException on out of range rrds. + */ + void getBoundingRectangle(ossim_uint32 rrds, ossimDrect& rect) const; + + /** + * @return This returns the total number of decimation levels. + */ + ossim_uint32 getNumberOfDecimationLevels()const; + + /** + * @brief Set theTargetRrds data member. + * + * This is used by methods rnToR0 and r0ToRn that do not take a rrds + * argument. + * + * @param rrds Target reduced resolution data set. + */ + void setTargetRrds(ossim_uint32 rrds); + + /** + * @return The target reduced resolution data set. + */ + ossim_uint32 getTargetRrds() const; + + + +protected: + + /** Offset from the full image. */ + ossimDpt theSubImageOffset; + + /** Decimation factors for each rrds level. */ + std::vector<ossimDpt> theDecimationFactors; + + ossim_uint32 theLines; + ossim_uint32 theSamples; + ossim_uint32 theTargetRrds; + +TYPE_DATA +}; + +#endif /* #ifndef ossimImageModel_HEADER */ diff --git a/Utilities/otbossim/include/ossim/imaging/ossimNitf20Writer.h b/Utilities/otbossim/include/ossim/imaging/ossimNitf20Writer.h new file mode 100644 index 0000000000000000000000000000000000000000..61c098302bef3e0965350e7998ebe1950aaeef74 --- /dev/null +++ b/Utilities/otbossim/include/ossim/imaging/ossimNitf20Writer.h @@ -0,0 +1,202 @@ +//******************************************************************* +// Copyright (C) 2000 ImageLinks Inc. +// +// License: See top level LICENSE.txt file. +// +// Author: Garrett Potts +// +//******************************************************************* +// $Id: ossimNitfWriter.h 9256 2006-07-14 15:28:19Z dburken $ +#ifndef ossimNitf20Writer_HEADER +#define ossimNitf20Writer_HEADER + +#include <iosfwd> +#include <ossim/imaging/ossimImageFileWriter.h> +#include <ossim/base/ossimKeywordlist.h> +#include <ossim/projection/ossimMapProjectionInfo.h> +#include <ossim/base/ossimRgbLutDataObject.h> +#include <ossim/base/ossimRefPtr.h> +#include <ossim/support_data/ossimNitfFileHeaderV2_0.h> +#include <ossim/support_data/ossimNitfImageHeaderV2_0.h> + +class ossimProjection; + +class OSSIM_DLL ossimNitf20Writer : public ossimImageFileWriter +{ +public: + ossimNitf20Writer(const ossimFilename& filename=ossimFilename(""), + ossimImageSource* inputSource = (ossimImageSource*)NULL); + virtual ~ossimNitf20Writer(); + virtual bool isOpen()const; + virtual bool open(); + virtual void close(); + + /** + * void getImageTypeList(std::vector<ossimString>& imageTypeList)const + * + * Appends this writer image types to list "imageTypeList". + * + * This writer has the following types: + * nitf_block_band_separate + * nitf_block_band_sequential + * + * @param imageTypeList stl::vector<ossimString> list to append to. + */ + virtual void getImageTypeList(std::vector<ossimString>& imageTypeList)const; + + virtual void setProperty(ossimRefPtr<ossimProperty> property); + virtual ossimRefPtr<ossimProperty> getProperty( + const ossimString& name)const; + + /** + * @param propertyNames Array to populate with property names. + * + * @note The following names are handled: + * file_header + * image_header + * enable_rpcb_tag + * enable_blocka_tag + */ + virtual void getPropertyNames(std::vector<ossimString>& propertyNames)const; + + void addRegisteredTag(ossimRefPtr<ossimNitfRegisteredTag> registeredTag); + + /** + * Saves the state of the writer to kwl with prefix then calls + * base class ossimImageFileWriter::saveState + * + * @param kwl Keyword list to save to. + * + * @param prefix Usually something like: "object2." + + * @return true on success, false on failure. + * + * Keywords saved by saveState: + * + * enable_rpcb_tag: true + * + * enable_blocka_tag: true + */ + virtual bool saveState(ossimKeywordlist& kwl, const char* prefix=0) const; + + /** + * Initializes the state of the writer from kwl with prefix then calls + * base class ossimImageFileWriter::loadState + * + * @param kwl Keyword list to initialize from. + * + * @param prefix Usually something like: "object2." + + * @return true on success, false on failure. + * + * Keywords picked up by loadState: + * + * enable_rpcb_tag: true + * + * enable_blocka_tag: true + */ + virtual bool loadState(const ossimKeywordlist& kwl, const char* prefix=0); + +protected: + + /** + * @return true on success false on error. + */ + virtual bool writeFile(); + + /** + * write out block band separate + * + * @return true on success and false on error + */ + virtual bool writeBlockBandSeparate(); + + /** + * Outputs in band sequential format. Band 1 is followed by band + * 2, ... etc. + */ + virtual bool writeBlockBandSequential(); + + /** + * Populates tags with geometry info from projection. Will write an + * rpcb tag if theEnableRpcbTagFlag if set to true. + */ + void writeGeometry(); + + void addTags(); + /** + * Sets the complexity level of theFileHeader. + * + * @param endPosition This should be the end seek position of the file. + */ + void setComplexityLevel(ossim_uint64 endPosition); + + + /** + * Adds the BLOCKA tag. + * + * @param mapInfo ossimMapProjectionInfo to use to set tag with. + * + * @note Currently only used with map projected images. + */ + void addBlockaTag(ossimMapProjectionInfo& mapInfo); + + /** + * Adds the RPC00B tag. + * + * @param rect Requested rectangle of image to write. + * + * @param proj The output projection. + */ + void addRpcbTag(const ossimIrect& rect, + ossimRefPtr<ossimProjection> proj); + /** + * This is bits used. (OSSIM_USHORT11 = 11) + * + * @returns The actual bits per pixel. This will return 0 if the + * input connection is not hooked up or there is an unhandled scalar type. + */ + ossim_uint32 getActualBitsPerPixel() const; + + /** + * This the total bits per pixel. (OSSIM_USHORT11 = 16) + * + * @returns The bits per pixel. This will return 0 if the + * input connection is not hooked up or there is an unhandled scalar type. + */ + ossim_uint32 getBitsPerPixel() const; + + /** + * @return Pixel type as a string. Like: "INT", "R", "SI". . This will + * return an empty string if the input connection is not hooked up or + * there is an unhandled scalar type. + */ + ossimString getNitfPixelType() const; + + + std::ofstream* theOutputStream; + + ossimRefPtr<ossimNitfFileHeaderV2_0> theFileHeader; + ossimRefPtr<ossimNitfImageHeaderV2_0> theImageHeader; + + /** If true user wants to set RPC00B tag. (DEFAULT = false) */ + bool theEnableRpcbTagFlag; + + /** + * If true user wants to set BLOCKA tag. (DEFAULT = true) + * Currently only valid for map projected images. + */ + bool theEnableBlockaTagFlag; + + /** + * + * If true this will enable searching the input connnection for another NITF handler and + * bring the fields to this writers output fields and will maintin as many field values as possible + * + */ + bool theCopyFieldsFlag; + +TYPE_DATA +}; + +#endif /* #ifndef ossimNitfWriter_HEADER */ diff --git a/Utilities/otbossim/include/ossim/imaging/ossimTwoColorView.h b/Utilities/otbossim/include/ossim/imaging/ossimTwoColorView.h new file mode 100644 index 0000000000000000000000000000000000000000..6210e533602202c337fb527fa3ddb99cf1a79308 --- /dev/null +++ b/Utilities/otbossim/include/ossim/imaging/ossimTwoColorView.h @@ -0,0 +1,62 @@ +//------------------------------------------------------------------- +// License: LGPL. See top level LICENSE.txt file. +// +// Author: Garrett Potts +// +//------------------------------------------------------------------- +// $Id$ +#ifndef ossimTwoColorView_HEADER +#define ossimTwoColorView_HEADER 1 +#include <ossim/base/ossimConstants.h> +#include <ossim/imaging/ossimImageCombiner.h> + +/** + * This is a 2 color view of the input. It basically allows for a change detection and by default will take the first input and map + * it to the blue channel and takes the second input and maps to the red channel. The unused channel is mapped to a min pixel value. + */ +class OSSIM_DLL ossimTwoColorView : public ossimImageCombiner +{ +public: + ossimTwoColorView(); + virtual ossim_uint32 getNumberOfOutputBands() const; + /** + * @return the requested region of interest + */ + virtual ossimRefPtr<ossimImageData> getTile(const ossimIrect& rect, + ossim_uint32 resLevel=0); + ossimScalarType getOutputScalarType() const; + + double getNullPixelValue(ossim_uint32 band)const; + double getMinPixelValue(ossim_uint32 band)const; + double getMaxPixelValue(ossim_uint32 band)const; + + /** + * Will allow you to change the mapping of the new input and old input to the output band. + * Indexing from 0 based band numbering, by default the new channel (input 0) will be mapped to + * the output tile's blue channel (band 2) and the input 1 will be mapped to the red channel (band 0) + * and the green will have the value of min pix. Use this method to change the new and old default output + * mappings. + */ + void setIndexMapping(ossim_uint32 newIndex, + ossim_uint32 oldIndex); + virtual void initialize(); + +protected: + void allocate(); + void runAlgorithm(ossimImageData* newData, ossimImageData* oldData); + void runNative8(ossimImageData* newData, ossimImageData* oldData); + void runNorm(ossimImageData* newData, ossimImageData* oldData); + + bool theByPassFlag; + bool theNativeFlag; + ossimRefPtr<ossimImageData> theTwoColorTile; + ossimImageSource* theNewInput; + ossimImageSource* theOldInput; + ossim_uint32 theNewBufferDestinationIndex; + ossim_uint32 theOldBufferDestinationIndex; + ossim_uint32 theMinBufferDestinationIndex; + +TYPE_DATA +}; + +#endif diff --git a/Utilities/otbossim/include/ossim/projection/ossimImageProjectionModel.h b/Utilities/otbossim/include/ossim/projection/ossimImageProjectionModel.h new file mode 100644 index 0000000000000000000000000000000000000000..2e546fe364e26a6aefc1c94aa6762b9104b01666 --- /dev/null +++ b/Utilities/otbossim/include/ossim/projection/ossimImageProjectionModel.h @@ -0,0 +1,61 @@ +//----------------------------------------------------------------------------- +// +// License: LGPL +// +// See LICENSE.txt file in the top level directory for more details. +// +// Author: David Burken +// +// Description: Class declaration of ossimImageProjectionModel. +// +//----------------------------------------------------------------------------- +// $Id$ + +#ifndef ossimImageProjectionModel_HEADER +#define ossimImageProjectionModel_HEADER 1 + +#include <ossim/base/ossimConstants.h> +#include <ossim/base/ossimRtti.h> +#include <ossim/imaging/ossimImageModel.h> + +class ossimProjection; + +/** + * @brief Class derived from ossimImageModel, this adds an image projection + * for lineSampleToWorld and worldToLineSample. + * + * Note that image points fed to projection methods should be full + * resolution with any sub image offset applied. + */ +class OSSIM_DLL ossimImageProjectionModel : public ossimImageModel +{ +public: + + /** @brief default constructor */ + ossimImageProjectionModel(); + + /** @brief virtual destructor */ + virtual ~ossimImageProjectionModel(); + + /** + * @brief Method to initialize class from an image handler. + * + * @param ih Image handler. + */ + virtual void initialize(const ossimImageHandler& ih); + + /** + * @brief Method to get projection. + * + * @return Constant pointer to projection or 0 if not initialized. + */ + const ossimProjection* getProjection() const; + +private: + + ossimProjection* theProjection; + +TYPE_DATA +}; + +#endif /* #ifndef ossimImageProjectionModel_HEADER */ diff --git a/Utilities/otbossim/include/ossim/support_data/ossimJ2kSizRecord.h b/Utilities/otbossim/include/ossim/support_data/ossimJ2kSizRecord.h new file mode 100644 index 0000000000000000000000000000000000000000..6153c9acff8403b089563c9e440b386170d2d074 --- /dev/null +++ b/Utilities/otbossim/include/ossim/support_data/ossimJ2kSizRecord.h @@ -0,0 +1,126 @@ +//---------------------------------------------------------------------------- +// +// License: LGPL +// +// See LICENSE.txt file in the top level directory for more details. +// +// Author: David Burken +// +// Description: Container class for J2K Image and tile size (SIZ) record. +// +// See document BPJ2K01.00 Table 7-6 Image and tile size (15444-1 Annex A5.1) +// +//---------------------------------------------------------------------------- +// $Id: ossimJ2kSizRecord.h,v 1.5 2005/10/13 21:24:47 dburken Exp $ +#ifndef ossimJ2kSizRecord_HEADER +#define ossimJ2kSizRecord_HEADER + +#include <iosfwd> + +#include <ossim/base/ossimConstants.h> + +class OSSIM_DLL ossimJ2kSizRecord +{ +public: + + /** default constructor */ + ossimJ2kSizRecord(); + + /** destructor */ + ~ossimJ2kSizRecord(); + + /** + * Parse method. Performs byte swapping as needed. + * + * @param in Stream to parse. + * + * @note Marker is not read. + */ + void parseStream(std::istream& in); + + /** @return scalar type based on bit depth and signed bit from theSsiz. */ + ossimScalarType getScalarType() const; + + /** + * Print method. + * + * @param out Stream to print to. + * + * @return std::ostream& + */ + std::ostream& print(std::ostream& out) const; + + /** operator<< */ + friend OSSIM_DLL std::ostream& operator<<( + std::ostream& out, const ossimJ2kSizRecord& obj); + + /** segmet marker 0xff51 (big endian) */ + ossim_uint16 theSizMarker; + + /** length of segment minus marker */ + ossim_uint16 theLsiz; + + /** profile */ + ossim_uint16 theRsiz; + + /** width of reference grid */ + ossim_uint32 theXsiz; + + /** height of reference grid */ + ossim_uint32 theYziz; + + /** + * Horizontal offset from the orgin of reference grid to the left side + * of image. + */ + ossim_uint32 theXOsiz; + + /** + * Vertical offset from the orgin of reference grid to the top + * of image. + */ + ossim_uint32 theYOsiz; + + /** width of one reference tile */ + ossim_uint32 theXTsiz; + + /** height of one reference tile */ + ossim_uint32 theYTsiz; + + /** + * Horizontal offset from the orgin of reference grid to the left edge + * of first tile. + */ + ossim_uint32 theXTOsiz; + + /** + * Vertical offset from the orgin of reference grid to the top + * edge of first tile. + */ + ossim_uint32 theYTOsiz; + + /** number of component in the image */ + ossim_uint16 theCsiz; + + /** + * sign bit and bit depth of data + * unsigned = 0xxx xxxx (msb == 0) + * signed = 1xxx xxxx (msb == 1) + * bit depth = x000 0000 + 1 (first seven bits plus one) + */ + ossim_uint8 theSsiz; + + /** + * Horizontal separation of a sample of the component with respect to the + * reference grid. + */ + ossim_uint8 theXRsiz; + + /** + * Vertical separation of a sample of the component with respect to the + * reference grid. + */ + ossim_uint8 theYRsiz; +}; + +#endif /* End of "#ifndef ossimJ2kSizRecord_HEADER" */ diff --git a/Utilities/otbossim/include/ossim/support_data/ossimJ2kSotRecord.h b/Utilities/otbossim/include/ossim/support_data/ossimJ2kSotRecord.h new file mode 100644 index 0000000000000000000000000000000000000000..8738afb46b6f7be00ae3b64703b5dd790ba39cdb --- /dev/null +++ b/Utilities/otbossim/include/ossim/support_data/ossimJ2kSotRecord.h @@ -0,0 +1,80 @@ +//---------------------------------------------------------------------------- +// +// License: LGPL +// +// See LICENSE.txt file in the top level directory for more details. +// +// Author: David Burken +// +// Description: Container class for J2K "Start Of Tile" (SOT) record. +// +// See document BPJ2K01.00 Table 7-3 Image and tile size (15444-1 Annex A.4.2) +// +//---------------------------------------------------------------------------- +// $Id: ossimJ2kSotRecord.h,v 1.5 2005/10/13 21:24:47 dburken Exp $ +#ifndef ossimJ2kSotRecord_HEADER +#define ossimJ2kSotRecord_HEADER + +#include <iosfwd> + +#include <ossim/base/ossimConstants.h> + +class OSSIM_DLL ossimJ2kSotRecord +{ +public: + + /** default constructor */ + ossimJ2kSotRecord(); + + /** destructor */ + ~ossimJ2kSotRecord(); + + /** + * Parse method. Performs byte swapping as needed. + * + * @param in Stream to parse. + * + * @note Marker is not read. + */ + void parseStream(std::istream& in); + + /** + * Print method. + * + * @param out Stream to print to. + * + * @return std::ostream& + */ + std::ostream& print(std::ostream& out) const; + + /** + * operator<<. + */ + friend OSSIM_DLL std::ostream& operator<<( + std::ostream& out, const ossimJ2kSotRecord& obj); + + /** Start of tile-part marker code. 0xff90 */ + ossim_uint16 theSotMarker; + + /** Length in bytes of the marker segment. */ + ossim_uint16 theLsot; + + /** Tile index. Tiles are in raster order starting at 0. */ + ossim_uint16 theIsot; + + /** The length in bytes of this record including the SOT marker. */ + ossim_uint32 thePsot; + + /** Tile-Part index. */ + ossim_uint8 theTpsot; + + /** + * 0 = Number of tile-parts of this tile in the codestream is not defined + * in this header. + * + * 1-255 number of tile-parts of this tile in the codestream. + */ + ossim_uint8 theTnsot; +}; + +#endif /* End of "#ifndef ossimJ2kSotRecord_HEADER" */ diff --git a/Utilities/otbossim/include/ossim/vpfutil/vpfapi.h b/Utilities/otbossim/include/ossim/vpfutil/vpfapi.h new file mode 100644 index 0000000000000000000000000000000000000000..a6c22f7e594b4e149a9cc0172292182edf65ab76 --- /dev/null +++ b/Utilities/otbossim/include/ossim/vpfutil/vpfapi.h @@ -0,0 +1,13 @@ +#ifndef VPFAPI_HEADER +#define VPFAPI_HEADER +#ifdef __cplusplus +extern "C" { +#endif + float distance(double lat1, double lon1, double lat2, double lon2, + int units ); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/Utilities/otbossim/src/ossim/imaging/ossimImageModel.cpp b/Utilities/otbossim/src/ossim/imaging/ossimImageModel.cpp new file mode 100644 index 0000000000000000000000000000000000000000..edbf2ad9444440cb6c506dfb4ba9d281e9e08ec3 --- /dev/null +++ b/Utilities/otbossim/src/ossim/imaging/ossimImageModel.cpp @@ -0,0 +1,154 @@ +//----------------------------------------------------------------------------- +// +// License: LGPL +// +// See LICENSE.txt file in the top level directory for more details. +// +// Author: David Burken +// +// Description: Class definition of ossimImageModel. +// +//----------------------------------------------------------------------------- +// $Id$ + +#include <string> + +#include <ossim/imaging/ossimImageModel.h> +#include <ossim/base/ossimDrect.h> +#include <ossim/base/ossimException.h> +#include <ossim/imaging/ossimImageHandler.h> + +RTTI_DEF1(ossimImageModel, "ossimImageModel", ossimObject); + +ossimImageModel::ossimImageModel() + : ossimObject(), + theSubImageOffset(), + theDecimationFactors(), + theLines(0), + theSamples(0), + theTargetRrds(0) +{ +} + +ossimImageModel::~ossimImageModel() +{ +} + +void ossimImageModel::initialize(const ossimImageHandler& ih) +{ + theSubImageOffset = ih.getSubImageOffset(0); + theLines = ih.getNumberOfLines(0); + theSamples = ih.getNumberOfSamples(0); + ih.getDecimationFactors(theDecimationFactors); +} + +void ossimImageModel::rnToR0(ossim_uint32 rrds, + const ossimDpt& rnPt, + ossimDpt& r0Pt) const +{ + if ( rrds < theDecimationFactors.size() ) + { + r0Pt.x = rnPt.x / theDecimationFactors[rrds].x; + r0Pt.y = rnPt.y / theDecimationFactors[rrds].y; + } + else + { + std::string e = "ossimImageModel::rnToR0 rrds out of range!"; + throw ossimException(e); + } +} +void ossimImageModel::rnToR0(const ossimDpt& rnPt, ossimDpt& r0Pt) const +{ + rnToR0(theTargetRrds, rnPt, r0Pt); +} + +void ossimImageModel::r0ToRn(ossim_uint32 rrds, + const ossimDpt& r0Pt, + ossimDpt& rnPt) const +{ + if ( rrds < theDecimationFactors.size() ) + { + rnPt.x = r0Pt.x * theDecimationFactors[rrds].x; + rnPt.y = r0Pt.y * theDecimationFactors[rrds].y; + } + else + { + std::string e = "ossimImageModel::r0ToRn rrds out of range!"; + throw ossimException(e); + } +} + +void ossimImageModel::r0ToRn(const ossimDpt& r0Pt, ossimDpt& rnPt) const +{ + r0ToRn(theTargetRrds, r0Pt, rnPt); +} + +void ossimImageModel::getSubImageOffset(ossim_uint32 rrds, + ossimDpt& offset) const +{ + if ( rrds < theDecimationFactors.size() ) + { + offset.x = theSubImageOffset.x * theDecimationFactors[rrds].x; + offset.y = theSubImageOffset.y * theDecimationFactors[rrds].y; + } + else + { + std::string e = "ossimImageModel::getSubImageOffset rrds out of range!"; + throw ossimException(e); + } +} + +void ossimImageModel::getImageRectangle(ossim_uint32 rrds, + ossimDrect& rect) const +{ + if ( rrds < theDecimationFactors.size() ) + { + ossim_float64 lrX = theSamples * theDecimationFactors[rrds].x - 1.0; + ossim_float64 lrY = theLines * theDecimationFactors[rrds].y - 1.0; + ossimDrect r(0.0, 0.0, lrX, lrY); + rect = r; + } + else + { + std::string e = "ossimImageModel::getImageRectangle rrds out of range!"; + throw ossimException(e); + } +} + +void ossimImageModel::getBoundingRectangle(ossim_uint32 rrds, + ossimDrect& rect) const +{ + if ( rrds < theDecimationFactors.size() ) + { + ossim_float64 urX = theSubImageOffset.x * theDecimationFactors[rrds].x; + ossim_float64 urY = theSubImageOffset.y * theDecimationFactors[rrds].y; + + ossim_float64 lrX = urX + theSamples*theDecimationFactors[rrds].x - 1.0; + ossim_float64 lrY = urY + theLines *theDecimationFactors[rrds].y - 1.0; + ossimDrect r(0, 0, lrX, lrY); + rect = r; + } + else + { + std::string e = + "ossimImageModel::getBoundingRectangle rrds out of range!"; + throw ossimException(e); + } +} +ossim_uint32 ossimImageModel::getNumberOfDecimationLevels()const +{ + return theDecimationFactors.size(); +} + +void ossimImageModel::setTargetRrds(ossim_uint32 rrds) +{ + theTargetRrds = rrds; +} + +ossim_uint32 ossimImageModel::getTargetRrds() const +{ + return theTargetRrds; +} + + + diff --git a/Utilities/otbossim/src/ossim/imaging/ossimNitf20Writer.cpp b/Utilities/otbossim/src/ossim/imaging/ossimNitf20Writer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ed3ee412a17f5c572653dc9dd97b1250664ca632 --- /dev/null +++ b/Utilities/otbossim/src/ossim/imaging/ossimNitf20Writer.cpp @@ -0,0 +1,1154 @@ +//******************************************************************* +// +// License: See top level LICENSE.txt file. +// +// Author: Garrett Potts +// +//******************************************************************* +// $Id: ossimNitfWriter.cpp 11385 2007-07-25 13:56:38Z gpotts $ + +#include <fstream> +#include <algorithm> +#include <sstream> +#include <iomanip> +#include <tiffio.h> +#include <ossim/imaging/ossimNitf20Writer.h> +#include <ossim/imaging/ossimNitfTileSource.h> +#include <ossim/base/ossimDate.h> +#include <ossim/base/ossimPreferences.h> +#include <ossim/base/ossimRefPtr.h> +#include <ossim/base/ossimTrace.h> +#include <ossim/base/ossimEndian.h> +#include <ossim/projection/ossimProjection.h> +#include <ossim/projection/ossimRpcSolver.h> +#include <ossim/projection/ossimUtmProjection.h> +#include <ossim/projection/ossimMapProjectionInfo.h> +#include <ossim/projection/ossimProjectionFactoryRegistry.h> +#include <ossim/imaging/ossimRectangleCutFilter.h> +#include <ossim/base/ossimProperty.h> +#include <ossim/base/ossimContainerProperty.h> +#include <ossim/base/ossimStringProperty.h> +#include <ossim/base/ossimNumericProperty.h> +#include <ossim/base/ossimBooleanProperty.h> +#include <ossim/support_data/ossimNitfGeoPositioningTag.h> +#include <ossim/support_data/ossimNitfLocalGeographicTag.h> +#include <ossim/support_data/ossimNitfLocalCartographicTag.h> +#include <ossim/support_data/ossimNitfProjectionParameterTag.h> +#include <ossim/support_data/ossimNitfNameConversionTables.h> +#include <ossim/support_data/ossimNitfBlockaTag.h> + +RTTI_DEF1(ossimNitf20Writer, "ossimNitf20Writer", ossimImageFileWriter); + +static ossimTrace traceDebug(ossimString("ossimNitfWriter:debug")); + +static ossimString monthConversionTable[] = {" ", "JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"}; + +ossimNitf20Writer::ossimNitf20Writer(const ossimFilename& filename, + ossimImageSource* inputSource) + : ossimImageFileWriter(filename, inputSource, NULL), + theOutputStream(NULL), + theFileHeader(), + theImageHeader(), + theEnableRpcbTagFlag(false), + theEnableBlockaTagFlag(true), + theCopyFieldsFlag(false) +{ + //--- + // Since the internal nitf tags are not very accurate, write an external + // geometry out as default behavior. Users can disable this via the + // property interface or keyword list. + //--- + setWriteExternalGeometryFlag(true); + + theFileHeader = new ossimNitfFileHeaderV2_0; + theImageHeader = new ossimNitfImageHeaderV2_0; + theOutputImageType = "nitf20_block_band_separate"; +} + +ossimNitf20Writer::~ossimNitf20Writer() +{ + //--- + // This looks like a leak but it's not as both of these are ossimRefPtr's. + //--- + theFileHeader=NULL; + theImageHeader=NULL; + + close(); +} + +bool ossimNitf20Writer::isOpen()const +{ + return (theOutputStream != NULL); +} + +bool ossimNitf20Writer::open() +{ + if(isOpen()) + { + close(); + } + theOutputStream = new std::ofstream; + theOutputStream->open(theFilename.c_str(), ios::out|ios::binary); + + return theOutputStream->good(); +} + +void ossimNitf20Writer::close() +{ + if(theOutputStream) + { + theOutputStream->close(); + delete theOutputStream; + theOutputStream = (std::ofstream*)NULL; + } +} + +bool ossimNitf20Writer::writeFile() +{ + if(!theInputConnection->isMaster()) + { + theInputConnection->slaveProcessTiles(); + + return true; + } + + open(); + + if (!isOpen()) + { + if (traceDebug()) + { + ossimNotify(ossimNotifyLevel_DEBUG) + << "ossimNitf20Writer::writeFile ERROR:" + << " Could not open! Returning..." + << std::endl; + } + + return false; + } + + // Write out the geometry info. + writeGeometry(); + addTags(); + + bool result = false; + if((theOutputImageType == "nitf20_block_band_separate")|| + (theOutputImageType == "image/nitf20")) + { + result = writeBlockBandSeparate(); + } + else if(theOutputImageType == "nitf20_block_band_sequential") + { + result = writeBlockBandSequential(); + } + + close(); + + return result; +} + +void ossimNitf20Writer::getImageTypeList(std::vector<ossimString>& imageTypeList)const +{ + imageTypeList.push_back(ossimString("nitf20_block_band_separate")); + imageTypeList.push_back(ossimString("nitf20_block_band_sequential")); +} + +void ossimNitf20Writer::setProperty(ossimRefPtr<ossimProperty> property) +{ + if(!property) return; + + ossimString name = property->getName(); + + if(name == "file_header") + { + ossimContainerProperty* containerProperty = PTR_CAST(ossimContainerProperty, + property.get()); + if(containerProperty) + { + std::vector<ossimRefPtr<ossimProperty> > propertyList; + containerProperty->getPropertyList(propertyList); + theFileHeader->setProperties(propertyList); + } + } + else if(name == "image_header") + { + ossimContainerProperty* containerProperty = PTR_CAST(ossimContainerProperty, + property.get()); + if(containerProperty) + { + std::vector<ossimRefPtr<ossimProperty> > propertyList; + containerProperty->getPropertyList(propertyList); + theImageHeader->setProperties(propertyList); + } + } + else if (name == "enable_rpcb_tag") + { + theEnableRpcbTagFlag = property->valueToString().toBool(); + } + else if (name == "enable_blocka_tag") + { + theEnableBlockaTagFlag = property->valueToString().toBool(); + } + else if(name == "copy_fields_flag") + { + theCopyFieldsFlag = property->valueToString().toBool(); + } + else + { + // just in case it was an nitf specific tag we can pass it safely like this + theFileHeader->setProperty(property); + theImageHeader->setProperty(property); + ossimImageFileWriter::setProperty(property); + } +} + +ossimRefPtr<ossimProperty> ossimNitf20Writer::getProperty(const ossimString& name)const +{ + ossimRefPtr<ossimProperty> result = NULL; + + if(name == "file_header") + { + ossimContainerProperty* container = new ossimContainerProperty(name); + std::vector<ossimRefPtr<ossimProperty> > propertyList; + + theFileHeader->getPropertyList(propertyList); + container->addChildren(propertyList); + + result = container; + } + else if(name == "image_header") + { + ossimContainerProperty* container = new ossimContainerProperty(name); + std::vector<ossimRefPtr<ossimProperty> > propertyList; + + theImageHeader->getPropertyList(propertyList); + container->addChildren(propertyList); + + result = container; + } + else if(name == "enable_rpcb_tag") + { + ossimBooleanProperty* boolProperty = + new ossimBooleanProperty(name, theEnableRpcbTagFlag); + + result = boolProperty; + } + else if(name == "enable_blocka_tag") + { + ossimBooleanProperty* boolProperty = + new ossimBooleanProperty(name, theEnableBlockaTagFlag); + + result = boolProperty; + } + else if(name == "copy_fields_flag") + { + ossimBooleanProperty* boolProperty = + new ossimBooleanProperty(name, theCopyFieldsFlag); + + result = boolProperty; + } + else + { + return ossimImageFileWriter::getProperty(name); + } + + return result; +} + +void ossimNitf20Writer::getPropertyNames(std::vector<ossimString>& propertyNames)const +{ + ossimImageFileWriter::getPropertyNames(propertyNames); + + propertyNames.push_back("file_header"); + propertyNames.push_back("image_header"); + propertyNames.push_back("enable_rpcb_tag"); + propertyNames.push_back("enable_blocka_tag"); + propertyNames.push_back("copy_fields_flag"); +} + +bool ossimNitf20Writer::writeBlockBandSeparate() +{ + ossimScalarType scalarType = theInputConnection->getOutputScalarType(); + ossim_uint64 byteSize = ossim::scalarSizeInBytes(scalarType); + ossimIrect rect = theInputConnection->getBoundingRect(); + ossim_uint64 bands = theInputConnection->getNumberOfOutputBands(); + ossim_uint64 idx = 0; + ossim_uint64 headerStart = (ossim_uint64)theOutputStream->tellp(); + + ossimIpt blockSize(64, 64); + ossim_uint64 blocksHorizontal = (ossim_uint32)ceil(((double)rect.width()/(double)blockSize.x)); + ossim_uint64 blocksVertical = (ossim_uint32)ceil(((double)rect.height()/(double)blockSize.y)); + + ossimNitfImageInfoRecordV2_0 imageInfoRecord; + //imageInfoRecord.setSubheaderLength(439); // ok if no tags + imageInfoRecord.setImageLength(bands*byteSize*blocksVertical*blockSize.y*blocksHorizontal*blockSize.x); + + theFileHeader->addImageInfoRecord(imageInfoRecord); + + //--- + // This makes space for the file header; it is written again at the end of + // this method with updated values + // need a better way to get the length. This should be queried on the + // header before writing + //--- + theFileHeader->writeStream(*theOutputStream); + ossim_uint64 headerLength = ((ossim_uint64)theOutputStream->tellp() - headerStart) /* + 1 */; + + ossimString representation; + theImageHeader->setActualBitsPerPixel(getActualBitsPerPixel()); + theImageHeader->setBitsPerPixel(getBitsPerPixel()); + theImageHeader->setPixelType(getNitfPixelType()); + theImageHeader->setNumberOfBands(bands); + theImageHeader->setImageMode('B');// blocked + + if((bands == 3)&& + (scalarType == OSSIM_UCHAR)) + { + theImageHeader->setRepresentation("RGB"); + theImageHeader->setCategory("VIS"); + } + else if(bands == 1) + { + theImageHeader->setRepresentation("MONO"); + theImageHeader->setCategory("MS"); + } + else + { + theImageHeader->setRepresentation("MULTI"); + theImageHeader->setCategory("MS"); + } + + theImageHeader->setBlocksPerRow(blocksHorizontal); + theImageHeader->setBlocksPerCol(blocksVertical); + theImageHeader->setNumberOfPixelsPerBlockRow(blockSize.x); + theImageHeader->setNumberOfPixelsPerBlockCol(blockSize.y); + theImageHeader->setNumberOfRows(rect.height()); + theImageHeader->setNumberOfCols(rect.width()); + + ossimNitfImageBandV2_0 bandInfo; + for(idx = 0; idx < bands; ++idx) + { + std::ostringstream out; + + out << std::setfill('0') + << std::setw(2) + << idx; + + bandInfo.setBandRepresentation(out.str().c_str()); + theImageHeader->setBandInfo(idx, + bandInfo); + } + + ossim_uint64 imageHeaderStart = theOutputStream->tellp(); + theImageHeader->writeStream(*theOutputStream); + ossim_uint64 imageHeaderEnd = theOutputStream->tellp(); + ossim_uint64 imageHeaderSize = imageHeaderEnd - imageHeaderStart; + + theInputConnection->setTileSize(blockSize); + ossim_uint64 numberOfTiles = theInputConnection->getNumberOfTiles(); + theInputConnection->setToStartOfSequence(); + ossimRefPtr<ossimImageData> data = theInputConnection->getNextTile(); + ossim_uint64 tileNumber = 1; + ossimEndian endian; + + + while( data.valid() && !needsAborting()) + { + if(endian.getSystemEndianType() == OSSIM_LITTLE_ENDIAN) + { + switch(data->getScalarType()) + { + case OSSIM_USHORT16: + case OSSIM_USHORT11: + { + endian.swap((ossim_uint16*)data->getBuf(), + data->getWidth()*data->getHeight()*data->getNumberOfBands()); + break; + } + case OSSIM_SSHORT16: + { + endian.swap((ossim_sint16*)data->getBuf(), + data->getWidth()*data->getHeight()*data->getNumberOfBands()); + break; + } + case OSSIM_FLOAT: + case OSSIM_NORMALIZED_FLOAT: + { + endian.swap((ossim_float32*)data->getBuf(), + data->getWidth()*data->getHeight()*data->getNumberOfBands()); + break; + } + case OSSIM_DOUBLE: + case OSSIM_NORMALIZED_DOUBLE: + { + endian.swap((ossim_float64*)data->getBuf(), + data->getWidth()*data->getHeight()*data->getNumberOfBands()); + break; + } + default: + break; + } + } + + theOutputStream->write((char*)(data->getBuf()), + data->getSizeInBytes()); + + setPercentComplete(((double)tileNumber / (double)numberOfTiles) * 100); + + if(!needsAborting()) + { + data = theInputConnection->getNextTile(); + } + ++tileNumber; + } + + ossim_uint64 pos = theOutputStream->tellp(); + + setComplexityLevel(pos); + + /* + * Need to change the way I compute file length and header length later + * We need to figure out a better way to compute. + */ + theFileHeader->setFileLength(pos); + theFileHeader->setHeaderLength(headerLength); + theOutputStream->seekp(0, ios::beg); + imageInfoRecord.setSubheaderLength(imageHeaderSize); + theFileHeader->replaceImageInfoRecord(0, imageInfoRecord); + theFileHeader->writeStream(*theOutputStream); + + return true; +} + +bool ossimNitf20Writer::writeBlockBandSequential() +{ + ossimScalarType scalarType = theInputConnection->getOutputScalarType(); + ossim_uint64 byteSize = ossim::scalarSizeInBytes(scalarType); + ossimIrect rect = theInputConnection->getBoundingRect(); + ossim_uint64 bands = theInputConnection->getNumberOfOutputBands(); + ossim_uint64 idx = 0; + ossim_uint64 headerStart = (ossim_uint64)theOutputStream->tellp(); + + ossimIpt blockSize(64, 64); + + ossim_uint64 blocksHorizontal = theInputConnection->getNumberOfTilesHorizontal(); + ossim_uint64 blocksVertical = theInputConnection->getNumberOfTilesVertical(); + theInputConnection->setTileSize(blockSize); + ossim_uint64 numberOfTiles = theInputConnection->getNumberOfTiles(); + theInputConnection->setToStartOfSequence(); + + ossimNitfImageInfoRecordV2_0 imageInfoRecord; + // imageInfoRecord.setSubheaderLength(439); + imageInfoRecord.setImageLength(bands*byteSize*blocksHorizontal*blocksVertical*blockSize.x*blockSize.y); + + ossimDate currentDate; + + theFileHeader->setDate(currentDate); + theFileHeader->addImageInfoRecord(imageInfoRecord); + + //--- + // This makes space for the file header; it is written again at the end of + // this method with updated values + // need a better way to get the length. This should be queried on the + // header before writing + //--- + theFileHeader->writeStream(*theOutputStream); + ossim_uint64 headerLength = ((ossim_uint64)theOutputStream->tellp() - headerStart) /* + 1 */; + + ossimString representation; + theImageHeader->setActualBitsPerPixel(getActualBitsPerPixel()); + theImageHeader->setBitsPerPixel(getBitsPerPixel()); + theImageHeader->setPixelType(getNitfPixelType()); + theImageHeader->setNumberOfBands(bands); + theImageHeader->setImageMode('S');// blocked + + if((bands == 3)&& + (scalarType == OSSIM_UCHAR)) + { + theImageHeader->setRepresentation("RGB"); + theImageHeader->setCategory("VIS"); + } + else if(bands == 1) + { + theImageHeader->setRepresentation("MONO"); + theImageHeader->setCategory("MS"); + } + else + { + theImageHeader->setRepresentation("MULTI"); + theImageHeader->setCategory("MS"); + } + theImageHeader->setBlocksPerRow(blocksHorizontal); + theImageHeader->setBlocksPerCol(blocksVertical); + theImageHeader->setNumberOfPixelsPerBlockRow(blockSize.x); + theImageHeader->setNumberOfPixelsPerBlockCol(blockSize.y); + theImageHeader->setNumberOfRows(rect.height()); + theImageHeader->setNumberOfCols(rect.width()); + + ossimNitfImageBandV2_0 bandInfo; + for(idx = 0; idx < bands; ++idx) + { + std::ostringstream out; + + out << std::setfill('0') + << std::setw(2) + << idx; + + bandInfo.setBandRepresentation(out.str().c_str()); + theImageHeader->setBandInfo(idx, + bandInfo); + } + + int imageHeaderStart = theOutputStream->tellp(); + theImageHeader->writeStream(*theOutputStream); + int imageHeaderEnd = theOutputStream->tellp(); + int imageHeaderSize = imageHeaderEnd - imageHeaderStart; + + ossimIpt ul = rect.ul(); + ossimRefPtr<ossimImageData> data = theInputConnection->getNextTile(); + ossim_uint64 tileNumber = 0; + ossimEndian endian; + + // get the start to the first band of data block + // + ossim_uint64 streamOffset = theOutputStream->tellp(); + + // holds the total pixels to the next band + + ossim_uint64 blockSizeInBytes = blockSize.x*blockSize.y*ossim::scalarSizeInBytes(data->getScalarType()); + ossim_uint64 bandOffsetInBytes = (blockSizeInBytes*blocksHorizontal*blocksVertical); + + bool needSwapping = endian.getSystemEndianType() == OSSIM_LITTLE_ENDIAN; + while(data.valid() && !needsAborting()) + { + if(needSwapping) + { + switch(data->getScalarType()) + { + case OSSIM_USHORT16: + case OSSIM_USHORT11: + { + endian.swap((ossim_uint16*)data->getBuf(), + data->getWidth()*data->getHeight()*data->getNumberOfBands()); + break; + } + case OSSIM_SSHORT16: + { + endian.swap((ossim_sint16*)data->getBuf(), + data->getWidth()*data->getHeight()*data->getNumberOfBands()); + break; + } + case OSSIM_FLOAT: + case OSSIM_NORMALIZED_FLOAT: + { + endian.swap((ossim_float32*)data->getBuf(), + data->getWidth()*data->getHeight()*data->getNumberOfBands()); + break; + } + case OSSIM_DOUBLE: + case OSSIM_NORMALIZED_DOUBLE: + { + endian.swap((ossim_float64*)data->getBuf(), + data->getWidth()*data->getHeight()*data->getNumberOfBands()); + break; + } + default: + break; + } + } + + for(idx = 0; idx < bands; ++idx) + { + theOutputStream->seekp(streamOffset+ // start of image stream + tileNumber*blockSizeInBytes + // start of block for band separate output + bandOffsetInBytes*idx, // which band offset is it + ios::beg); + + theOutputStream->write((char*)(data->getBuf(idx)), + blockSizeInBytes); + } + ++tileNumber; + + setPercentComplete(((double)tileNumber / (double)numberOfTiles) * 100); + + if(!needsAborting()) + { + data = theInputConnection->getNextTile(); + } + } + + ossim_uint64 pos = theOutputStream->tellp(); + + setComplexityLevel(pos); + + /* + * Need to change the way I compute file length and header length later + * We need to figure out a better way to compute. + */ + theFileHeader->setFileLength(pos); + theFileHeader->setHeaderLength(headerLength); + theOutputStream->seekp(0, ios::beg); + imageInfoRecord.setSubheaderLength(imageHeaderSize); + theFileHeader->replaceImageInfoRecord(0, imageInfoRecord); + theFileHeader->writeStream(*theOutputStream); + + return true; +} + + +void ossimNitf20Writer::addRegisteredTag( + ossimRefPtr<ossimNitfRegisteredTag> registeredTag) +{ + ossimNitfTagInformation tagInfo; + tagInfo.setTagData(registeredTag.get()); + theImageHeader->addTag(tagInfo); +} + +void ossimNitf20Writer::writeGeometry() +{ + if ( (theImageHeader.valid() == false) || !theInputConnection ) + { + return; + } + ossimKeywordlist kwl; + theInputConnection->getImageGeometry(kwl); + ossimRefPtr<ossimProjection> proj = + ossimProjectionFactoryRegistry::instance()->createProjection(kwl); + + if(proj.valid() == false) + { + // No projection info. + return; + } + + // Get the requested bounding rectangles. + ossimIrect rect = theInputConnection->getBoundingRect(); + + // See if it's a map projection; else, a sensor model. + ossimMapProjection* mapProj = PTR_CAST(ossimMapProjection, proj.get()); + if (mapProj) + { + // Use map info to get the corners. + ossimMapProjectionInfo mapInfo(mapProj, rect); + mapInfo.setPixelType(OSSIM_PIXEL_IS_AREA); + + // See if it's utm. + ossimUtmProjection* utmProj = PTR_CAST(ossimUtmProjection, proj.get()); + if(utmProj) + { + ossimDpt ul = mapInfo.ulEastingNorthingPt(); + ossimDpt ur = mapInfo.urEastingNorthingPt(); + ossimDpt lr = mapInfo.lrEastingNorthingPt(); + ossimDpt ll = mapInfo.llEastingNorthingPt(); + + if(utmProj->getHemisphere() == 'N') + { + theImageHeader->setUtmNorth(utmProj->getZone(), ul, ur, lr, ll); + } + else + { + theImageHeader->setUtmSouth(utmProj->getZone(), ul, ur, lr, ll); + } + } + else + { + ossimGpt ul = mapInfo.ulGroundPt(); + ossimGpt ur = mapInfo.urGroundPt(); + ossimGpt lr = mapInfo.lrGroundPt(); + ossimGpt ll = mapInfo.llGroundPt(); + theImageHeader->setGeographicLocationDms(ul, ur, lr, ll); + } + + if (theEnableBlockaTagFlag) + { + addBlockaTag(mapInfo); + } + } + + if (theEnableRpcbTagFlag) + { + addRpcbTag(rect, proj); + } +} + +void ossimNitf20Writer::addTags() +{ + ossimDate currentDate; + theFileHeader->setDate(currentDate); + + if(theCopyFieldsFlag) + { + ossimConnectableObject* obj = findObjectOfType("ossimImageHandler", + ossimConnectableObject::CONNECTABLE_DIRECTION_INPUT); + ossimNitfTileSource* nitf = dynamic_cast<ossimNitfTileSource*>(obj); + if(nitf) + { + ossimString value; + ossimPropertyInterface* fileHeaderProperties = dynamic_cast<ossimPropertyInterface*>(theFileHeader.get()); + ossimPropertyInterface* imageHeaderProperties = dynamic_cast<ossimPropertyInterface*>(theImageHeader.get()); + bool nitf21Flag = false; + const ossimNitfFileHeader* header = nitf->getFileHeader(); + const ossimNitfImageHeader* imageHeader = nitf->getCurrentImageHeader(); + if(header) + { + ossimString version = header->getPropertyValueAsString("fhdr"); + nitf21Flag = version.contains("2.1"); + value = header->getPropertyValueAsString("stype"); + if(value.size()) + { + fileHeaderProperties->setProperty("stype", value); + } + value = header->getPropertyValueAsString("ostaid"); + if(value.size()) + { + fileHeaderProperties->setProperty("ostaid", value); + } + value = header->getPropertyValueAsString("ftitle"); + if(value.size()) + { + fileHeaderProperties->setProperty("ftitle", value); + } + value = header->getPropertyValueAsString("fsclas"); + if(value.size()) + { + fileHeaderProperties->setProperty("fsclas", value); + } + value = header->getPropertyValueAsString("oname"); + if(value.size()) + { + fileHeaderProperties->setProperty("oname", value); + } + value = header->getPropertyValueAsString("ophone"); + if(value.size()) + { + fileHeaderProperties->setProperty("ophone", value); + } + int idx = 0; + for(idx = 0; idx < header->getNumberOfTags(); ++idx) + { + ossimNitfTagInformation info; + header->getTagInformation(info, + idx); + theFileHeader->addTag(info); + } + value = header->getPropertyValueAsString(""); + if(value.size()) + { + fileHeaderProperties->setProperty("", value); + } + value = header->getPropertyValueAsString("fdt"); + if(value.size()==14) + { + if(nitf21Flag) + { + ossimString year(value.begin()+2, value.begin()+4); + ossimString mon(value.begin()+4, value.begin()+6); + ossimString day(value.begin()+6, value.begin()+8); + ossimString hour(value.begin()+8, value.begin()+10); + ossimString min(value.begin()+10, value.begin()+12); + ossimString sec(value.begin()+12, value.begin()+14); + if(mon.toUInt32() < 13) + { + mon = monthConversionTable[mon.toUInt32()]; + } + fileHeaderProperties->setProperty("fdt", day+hour+min+sec+"Z"+mon+year); + } + else + { + fileHeaderProperties->setProperty("fdt", value); + } + } + } + if(imageHeader) + { + ossim_uint32 idx = 0; + for(idx = 0; idx < imageHeader->getNumberOfTags(); ++idx) + { + ossimNitfTagInformation info; + imageHeader->getTagInformation(info, + idx); + theImageHeader->addTag(info); + } + value = imageHeader->getPropertyValueAsString("tgtid"); + if(value.size()) + { + imageHeaderProperties->setProperty("tgtid", value); + } + value = imageHeader->getPropertyValueAsString("isclas"); + if(value.size()) + { + imageHeaderProperties->setProperty("isclas", value); + } + value = imageHeader->getPropertyValueAsString("igeolo"); + if(value.size()) + { + imageHeaderProperties->setProperty("igeolo", value); + } + value = imageHeader->getPropertyValueAsString("ititle"); + if(nitf21Flag) + { + value = imageHeader->getPropertyValueAsString("iid2"); + } + if(value.size()) + { + imageHeaderProperties->setProperty("ititle", value); + } + if(!nitf21Flag) + { + value = imageHeader->getPropertyValueAsString("iscaut"); + if(value.size()) + { + imageHeaderProperties->setProperty("iscaut", value); + } + value = imageHeader->getPropertyValueAsString("iscode"); + if(value.size()) + { + imageHeaderProperties->setProperty("iscode", value); + } + value = imageHeader->getPropertyValueAsString("isctlh"); + if(value.size()) + { + imageHeaderProperties->setProperty("isctlh", value); + } + value = imageHeader->getPropertyValueAsString("isrel"); + if(value.size()) + { + imageHeaderProperties->setProperty("isrel", value); + } + value = imageHeader->getPropertyValueAsString("isctln"); + if(value.size()) + { + imageHeaderProperties->setProperty("isctln", value); + } + value = imageHeader->getPropertyValueAsString("isdwng"); + if(value.size()) + { + imageHeaderProperties->setProperty("isdevt", value); + } + value = imageHeader->getPropertyValueAsString("isorce"); + if(value.size()) + { + imageHeaderProperties->setProperty("isorce", value); + } + } + value = imageHeader->getPropertyValueAsString("idatim"); + if(value.size()==14) + { + if(nitf21Flag) + { + ossimString year(value.begin()+2, value.begin()+4); + ossimString mon(value.begin()+4, value.begin()+6); + ossimString day(value.begin()+6, value.begin()+8); + ossimString hour(value.begin()+8, value.begin()+10); + ossimString min(value.begin()+10, value.begin()+12); + ossimString sec(value.begin()+12, value.begin()+14); + if(mon.toUInt32() < 13) + { + mon = monthConversionTable[mon.toUInt32()]; + } + imageHeaderProperties->setProperty("idatim", day+hour+min+sec+"Z"+mon+year); + } + else + { + imageHeaderProperties->setProperty("idatim", value); + } + } + } + + // we will port over only a selected few + } + } +} + +void ossimNitf20Writer::setComplexityLevel(ossim_uint64 endPosition) +{ + //--- + // See MIL-STD-2500C, Table A-10: + // + // Lots of rules here, but for now we will key off of file size. + //--- + + if (!theFileHeader) + { + return; + } + + const ossim_uint64 MB = 1024 * 1024; + const ossim_uint64 MB50 = 50 * MB; + const ossim_uint64 GIG = 1000 * MB; + const ossim_uint64 GIG2 = 2 * GIG; + + ossimString complexity = "03"; // Less than 50 mb. + + + if ( (endPosition >= MB50) && (endPosition < GIG) ) + { + complexity = "05"; + } + else if ( (endPosition >= GIG) && (endPosition < GIG2) ) + { + complexity = "06"; + } + else if (endPosition >= GIG2) + { + complexity = "07"; + } + + theFileHeader->setComplexityLevel(complexity); +} + + +void ossimNitf20Writer::addBlockaTag(ossimMapProjectionInfo& mapInfo) +{ + if (!theImageHeader) + { + return; + } + + // Capture the current pixel type. + ossimPixelType originalPixelType = mapInfo.getPixelType(); + + // This tag wants corners as area: + mapInfo.setPixelType(OSSIM_PIXEL_IS_AREA); + + // Stuff the blocka tag which has six digit precision. + ossimNitfBlockaTag* blockaTag = new ossimNitfBlockaTag(); + + // Set the block number. + blockaTag->setBlockInstance(1); + + // Set the number of lines. + blockaTag->setLLines(mapInfo.linesPerImage()); + + // Set first row, first column. + blockaTag->setFrfcLoc(ossimDpt(mapInfo.ulGroundPt())); + + // Set first row, last column. + blockaTag->setFrlcLoc(ossimDpt(mapInfo.urGroundPt())); + + // Set last row, last column. + blockaTag->setLrlcLoc(ossimDpt(mapInfo.lrGroundPt())); + + // Set last row, first column. + blockaTag->setLrfcLoc(ossimDpt(mapInfo.llGroundPt())); + + if (traceDebug()) + { + ossimNotify(ossimNotifyLevel_DEBUG) + << "ossimNitf20Writer::writeGeometry DEBUG:" + << "\nBLOCKA Tag:" << *((ossimObject*)(blockaTag)) + << std::endl; + } + + // Add the tag to the header. + ossimRefPtr<ossimNitfRegisteredTag> blockaTagRp = blockaTag; + ossimNitfTagInformation blockaTagInfo(blockaTagRp); + theImageHeader->addTag(blockaTagInfo); + + // Reset the pixel type to original value + mapInfo.setPixelType(originalPixelType); +} + +void ossimNitf20Writer::addRpcbTag(const ossimIrect& rect, + ossimRefPtr<ossimProjection> proj) +{ + if (!proj.valid()) + { + return; + } + + bool useElevation = false; + + if (PTR_CAST(ossimMapProjection, proj.get())) + { + // If we're already map projected turn the elevation off. + useElevation = false; + } + + // Make an rpc solver. + ossimRpcSolver rs(useElevation); + + // Compute the coefficients. + rs.solveCoefficients(ossimDrect(rect), + *proj.get(), + 64, + 64); + + // Add the tag. + ossimRefPtr<ossimNitfRegisteredTag> tag = rs.getNitfRpcBTag(); + ossimNitfTagInformation tagInfo(tag); + theImageHeader->addTag(tagInfo); + + if (traceDebug()) + { + ossimNotify(ossimNotifyLevel_DEBUG) + << "ossimNitf20Writer::addRpcbTag DEBUG:" + << "\nRPCB Tag:" << *((ossimObject*)(tag.get())) + << "\nProjection:" << std::endl; + + proj->print(ossimNotify(ossimNotifyLevel_DEBUG)); + + ossimNotify(ossimNotifyLevel_DEBUG) + << "\nRect: " << rect << std::endl; + } +} + +ossim_uint32 ossimNitf20Writer::getActualBitsPerPixel() const +{ + ossim_uint32 actualBitsPerPixel = 0; + if (theInputConnection) + { + ossimScalarType scalarType = theInputConnection->getOutputScalarType(); + switch(scalarType) + { + case OSSIM_UCHAR: + { + actualBitsPerPixel = 8; + break; + } + case OSSIM_USHORT11: + { + actualBitsPerPixel = 11; + break; + } + case OSSIM_USHORT16: + case OSSIM_SSHORT16: + { + actualBitsPerPixel = 16; + break; + } + case OSSIM_FLOAT: + case OSSIM_NORMALIZED_FLOAT: + { + actualBitsPerPixel = 32; + break; + } + case OSSIM_DOUBLE: + case OSSIM_NORMALIZED_DOUBLE: + { + actualBitsPerPixel = 64; + break; + } + default: + { + break; + } + } + } + + return actualBitsPerPixel; +} + +ossim_uint32 ossimNitf20Writer::getBitsPerPixel() const +{ + ossim_uint32 bitsPerPixel = 0; + + if (theInputConnection) + { + ossimScalarType scalarType = theInputConnection->getOutputScalarType(); + switch(scalarType) + { + case OSSIM_UCHAR: + { + bitsPerPixel = 8; + break; + } + case OSSIM_USHORT11: + { + bitsPerPixel = 16; + break; + } + case OSSIM_USHORT16: + case OSSIM_SSHORT16: + { + bitsPerPixel = 16; + break; + } + case OSSIM_FLOAT: + case OSSIM_NORMALIZED_FLOAT: + { + bitsPerPixel = 32; + break; + } + case OSSIM_DOUBLE: + case OSSIM_NORMALIZED_DOUBLE: + { + bitsPerPixel = 64; + break; + } + default: + { + break; + } + } + } + return bitsPerPixel; +} + +ossimString ossimNitf20Writer::getNitfPixelType() const +{ + ossimString pixelType; + if (theInputConnection) + { + ossimScalarType scalarType = theInputConnection->getOutputScalarType(); + switch(scalarType) + { + case OSSIM_UCHAR: + case OSSIM_USHORT11: + case OSSIM_USHORT16: + { + pixelType = "INT"; + break; + } + case OSSIM_SSHORT16: + { + pixelType = "SI"; + break; + } + case OSSIM_FLOAT: + case OSSIM_NORMALIZED_FLOAT: + case OSSIM_DOUBLE: + case OSSIM_NORMALIZED_DOUBLE: + { + pixelType = "R"; + break; + } + default: + { + break; + } + } + } + return pixelType; +} + +bool ossimNitf20Writer::saveState(ossimKeywordlist& kwl, + const char* prefix) const +{ + kwl.add(prefix, "enable_rpcb_tag", theEnableRpcbTagFlag, true); + kwl.add(prefix, "enable_blocka_tag", theEnableBlockaTagFlag, true); + + return ossimImageFileWriter::saveState(kwl, prefix); +} + +bool ossimNitf20Writer::loadState(const ossimKeywordlist& kwl, + const char* prefix) +{ + // Look for the rpcb enable flag keyword. + const char* lookup = kwl.find(prefix, "enable_rpcb_tag"); + if(lookup) + { + ossimString os = lookup; + theEnableRpcbTagFlag = os.toBool(); + } + + // Look for the blocka enable flag keyword. + lookup = kwl.find(prefix, "enable_blocka_tag"); + if(lookup) + { + ossimString os = lookup; + theEnableBlockaTagFlag = os.toBool(); + } + + return ossimImageFileWriter::loadState(kwl, prefix); +} diff --git a/Utilities/otbossim/src/ossim/imaging/ossimTwoColorView.cpp b/Utilities/otbossim/src/ossim/imaging/ossimTwoColorView.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8ad091d838467966eb789476c240ace34978ee3e --- /dev/null +++ b/Utilities/otbossim/src/ossim/imaging/ossimTwoColorView.cpp @@ -0,0 +1,559 @@ +//------------------------------------------------------------------- +// License: LGPL. See top level LICENSE.txt file. +// +// Author: Garrett Potts +// +//------------------------------------------------------------------- +// $Id$ +#include <ossim/imaging/ossimTwoColorView.h> +#include <ossim/imaging/ossimImageDataFactory.h> + +RTTI_DEF1(ossimTwoColorView, + "ossimTwoColorView" , + ossimImageCombiner); + +ossimTwoColorView::ossimTwoColorView() +:ossimImageCombiner(0, 2, 0, true, false) , +theByPassFlag(true), +theNativeFlag(false), +theNewInput(0), +theOldInput(0), +theNewBufferDestinationIndex(2), +theOldBufferDestinationIndex(0), +theMinBufferDestinationIndex(1){ +} + +ossim_uint32 ossimTwoColorView::getNumberOfOutputBands() const +{ + if(theByPassFlag||!isSourceEnabled()) + { + return ossimImageCombiner::getNumberOfOutputBands(); + } + return 3; +} + +ossimScalarType ossimTwoColorView::getOutputScalarType() const +{ + if(theByPassFlag||!isSourceEnabled()) + { + return ossimImageCombiner::getOutputScalarType(); + } + return OSSIM_UINT8; +} + +void ossimTwoColorView::setIndexMapping(ossim_uint32 newIndex, + ossim_uint32 oldIndex) +{ + if(((newIndex < 3)&&(oldIndex < 3))&& + (newIndex != oldIndex)) + { + theNewBufferDestinationIndex = newIndex; + theOldBufferDestinationIndex = oldIndex; + if((theNewBufferDestinationIndex != 0)&& + (theOldBufferDestinationIndex != 0)) + { + theMinBufferDestinationIndex = 0; + } + else if((theNewBufferDestinationIndex != 1)&& + (theOldBufferDestinationIndex != 1)) + { + theMinBufferDestinationIndex = 1; + } + else if((theNewBufferDestinationIndex != 2)&& + (theOldBufferDestinationIndex != 2)) + { + theMinBufferDestinationIndex = 2; + } + } +} + +double ossimTwoColorView::getNullPixelValue(ossim_uint32 band)const +{ + if(theByPassFlag||!isSourceEnabled()) + { + return ossimImageCombiner::getNullPixelValue(band); + } + return 0; +} + +double ossimTwoColorView::getMinPixelValue(ossim_uint32 band)const +{ + if(theByPassFlag||!isSourceEnabled()) + { + return ossimImageCombiner::getMinPixelValue(band); + } + return 1; +} + +double ossimTwoColorView::getMaxPixelValue(ossim_uint32 band)const +{ + if(theByPassFlag||!isSourceEnabled()) + { + return ossimImageCombiner::getMaxPixelValue(band); + } + return 256; +} + +ossimRefPtr<ossimImageData> ossimTwoColorView::getTile(const ossimIrect& rect, + ossim_uint32 resLevel) +{ + ossim_uint32 tileIdx = 0; + if(theByPassFlag||!isSourceEnabled()) + { + return getNextTile(tileIdx, 0, rect, resLevel); + } + if(!theTwoColorTile.valid()) + { + allocate(); + } + if(!theTwoColorTile.valid()) + { + return theTwoColorTile; + } + theTwoColorTile->setImageRectangle(rect); + theTwoColorTile->makeBlank(); + + ossimRefPtr<ossimImageData> newData = theNewInput->getTile(rect, resLevel); + ossimRefPtr<ossimImageData> oldData = theOldInput->getTile(rect, resLevel); + runAlgorithm(newData.get(), oldData.get()); + +#if 0 + // do the new band first + ossimRefPtr<ossimImageData> newData = getNextNormTile(tileIdx, 0, rect, resLevel); + newData = newData.valid()?(ossimImageData*)newData->dup():(ossimImageData*)0; + ossimRefPtr<ossimImageData> oldData = getNextNormTile(tileIdx,rect, resLevel); + oldData = oldData.valid()?(ossimImageData*)oldData->dup():(ossimImageData*)0; + + ossim_float32 newNullPix = 0.0; + ossim_float32 oldNullPix = 0.0; + const ossim_float32* newBuf = 0; + const ossim_float32* oldBuf = 0; + ossim_float32 tempValue = 0.0; + ossim_uint32 idx = 0; + ossim_uint32 maxIdx = theTwoColorTile->getWidth()*theTwoColorTile->getHeight(); + ossim_uint8* newDestBuf = static_cast<ossim_uint8*>(theTwoColorTile->getBuf(theNewBufferDestinationIndex)); + ossim_uint8* oldDestBuf = static_cast<ossim_uint8*>(theTwoColorTile->getBuf(theOldBufferDestinationIndex)); + ossim_uint8* minDestBuf = static_cast<ossim_uint8*>(theTwoColorTile->getBuf(theMinBufferDestinationIndex)); + + + if(newData.valid()) + { + newBuf = static_cast<ossim_float32*>(newData->getBuf(0)); + newNullPix = static_cast<ossim_float32>(newData->getNullPix(0)); + } + if(oldData.valid()) + { + oldBuf = static_cast<ossim_float32*>(oldData->getBuf(0)); + oldNullPix = static_cast<ossim_float32>(oldData->getNullPix(0)); + } + + if(!newBuf&&!oldBuf) + { + return theTwoColorTile; + } + if(newBuf&&oldBuf) + { + + for(idx = 0; idx < maxIdx;++idx) + { + if((*newBuf == newNullPix)&& + (*oldBuf == oldNullPix)) + { + *newDestBuf = 0; + *oldDestBuf = 0; + *minDestBuf = 0; + } + else + { + if(*newBuf == newNullPix) + { + *newDestBuf = 1; + } + else + { + tempValue = (*newBuf)*255; + if(tempValue < 1) tempValue = 1; + else if(tempValue > 255) tempValue = 255; + + *newDestBuf = (ossim_uint8)(tempValue); + } + if(*oldBuf == oldNullPix) + { + *oldDestBuf = 1; + } + else + { + // do old buffer channel + tempValue = (*oldBuf)*255; + if(tempValue < 1) tempValue = 1; + else if(tempValue > 255) tempValue = 255; + + *oldDestBuf = (ossim_uint8)(tempValue); + } + *minDestBuf = 1; + } + ++newBuf; + ++oldBuf; + ++minDestBuf; + ++newDestBuf; + ++oldDestBuf; + } + } + else if(newBuf) + { + for(idx = 0; idx < maxIdx;++idx) + { + if(*newBuf == newNullPix) + { + *newDestBuf = 0; + *oldDestBuf = 0; + *minDestBuf = 0; + } + else + { + tempValue = (*newBuf)*255; + if(tempValue < 1) tempValue = 1; + else if(tempValue > 255) tempValue = 255; + + *newDestBuf = (ossim_uint8)(tempValue); + *oldDestBuf = 1; + *minDestBuf = 1; + } + ++newBuf; + ++minDestBuf; + ++newDestBuf; + ++oldDestBuf; + } + } + else if(oldBuf) + { + for(idx = 0; idx < maxIdx;++idx) + { + if(*oldBuf == oldNullPix) + { + *newDestBuf = 0; + *oldDestBuf = 0; + *minDestBuf = 0; + } + else + { + tempValue = (*oldBuf)*255; + if(tempValue < 1) tempValue = 1; + else if(tempValue > 255) tempValue = 255; + + *oldDestBuf = (ossim_uint8)(tempValue); + *newDestBuf = 1; + *minDestBuf = 1; + } + ++oldBuf; + ++minDestBuf; + ++newDestBuf; + ++oldDestBuf; + } + } + +#endif + theTwoColorTile->validate(); + return theTwoColorTile; + +} +void ossimTwoColorView::runAlgorithm(ossimImageData* newData, ossimImageData* oldData) +{ + if(theNativeFlag) + { + runNative8(newData, oldData); + } + else + { + runNorm(newData, oldData); + } +} + +void ossimTwoColorView::runNative8(ossimImageData* newData, ossimImageData* oldData) +{ + // do the new band first + ossim_uint8 newNullPix = 0.0; + ossim_uint8 oldNullPix = 0.0; + const ossim_uint8* newBuf = 0; + const ossim_uint8* oldBuf = 0; + ossim_uint32 idx = 0; + ossim_uint32 maxIdx = theTwoColorTile->getWidth()*theTwoColorTile->getHeight(); + ossim_uint8* newDestBuf = static_cast<ossim_uint8*>(theTwoColorTile->getBuf(theNewBufferDestinationIndex)); + ossim_uint8* oldDestBuf = static_cast<ossim_uint8*>(theTwoColorTile->getBuf(theOldBufferDestinationIndex)); + ossim_uint8* minDestBuf = static_cast<ossim_uint8*>(theTwoColorTile->getBuf(theMinBufferDestinationIndex)); + + if(newData) + { + newBuf = static_cast<ossim_uint8*>(newData->getBuf(0)); + newNullPix = static_cast<ossim_uint8>(newData->getNullPix(0)); + + } + if(oldData) + { + oldBuf = static_cast<ossim_uint8*>(oldData->getBuf(0)); + oldNullPix = static_cast<ossim_uint8>(oldData->getNullPix(0)); + } + if(!newBuf&&!oldBuf) + { + return; + } + if(newBuf&&oldBuf) + { + for(idx = 0; idx < maxIdx;++idx) + { + if((*newBuf == newNullPix)&& + (*oldBuf == oldNullPix)) + { + *newDestBuf = 0; + *oldDestBuf = 0; + *minDestBuf = 0; + } + else + { + if(*newBuf == newNullPix) + { + *newDestBuf = 1; + } + else + { + *newDestBuf = *newBuf; + } + if(*oldBuf == oldNullPix) + { + *oldDestBuf = 1; + } + else + { + *oldDestBuf = *oldBuf; + } + *minDestBuf = 1; + } + ++newBuf; + ++oldBuf; + ++minDestBuf; + ++newDestBuf; + ++oldDestBuf; + } + } + else if(newBuf) + { + for(idx = 0; idx < maxIdx;++idx) + { + if(*newBuf == newNullPix) + { + *newDestBuf = 0; + *oldDestBuf = 0; + *minDestBuf = 0; + } + else + { + *newDestBuf = *newBuf; + *oldDestBuf = 1; + *minDestBuf = 1; + } + ++newBuf; + ++minDestBuf; + ++newDestBuf; + ++oldDestBuf; + } + } + else if(oldBuf) + { + for(idx = 0; idx < maxIdx;++idx) + { + if(*oldBuf == oldNullPix) + { + *newDestBuf = 0; + *oldDestBuf = 0; + *minDestBuf = 0; + } + else + { + *oldDestBuf = *oldBuf; + *newDestBuf = 1; + *minDestBuf = 1; + } + ++oldBuf; + ++minDestBuf; + ++newDestBuf; + ++oldDestBuf; + } + } +} + +void ossimTwoColorView::runNorm(ossimImageData* newData, ossimImageData* oldData) +{ + // do the new band first + ossim_float32 tempValue=0.0; + ossim_uint8 newNullPix = 0.0; + ossim_uint8 oldNullPix = 0.0; + std::vector<ossim_float32> newDataBuffer; + std::vector<ossim_float32> oldDataBuffer; + + ossim_float32* newBuf = 0; + ossim_float32* oldBuf = 0; + ossim_uint32 idx = 0; + ossim_uint32 maxIdx = theTwoColorTile->getWidth()*theTwoColorTile->getHeight(); + ossim_uint8* newDestBuf = static_cast<ossim_uint8*>(theTwoColorTile->getBuf(theNewBufferDestinationIndex)); + ossim_uint8* oldDestBuf = static_cast<ossim_uint8*>(theTwoColorTile->getBuf(theOldBufferDestinationIndex)); + ossim_uint8* minDestBuf = static_cast<ossim_uint8*>(theTwoColorTile->getBuf(theMinBufferDestinationIndex)); + + if(newData&&newData->getBuf()) + { + newDataBuffer.resize(theTwoColorTile->getWidth()*theTwoColorTile->getHeight()); + newBuf = &newDataBuffer.front(); + newData->copyTileBandToNormalizedBuffer(0, newBuf); + newNullPix = 0; + } + if(oldData&&oldData->getBuf()) + { + oldDataBuffer.resize(theTwoColorTile->getWidth()*theTwoColorTile->getHeight()); + oldBuf = &oldDataBuffer.front(); + oldData->copyTileBandToNormalizedBuffer(0, oldBuf); + oldNullPix = 0; + } + if(!newBuf&&!oldBuf) + { + return; + } + if(newBuf&&oldBuf) + { + for(idx = 0; idx < maxIdx;++idx) + { + if((*newBuf == newNullPix)&& + (*oldBuf == oldNullPix)) + { + *newDestBuf = 0; + *oldDestBuf = 0; + *minDestBuf = 0; + } + else + { + if(*newBuf == newNullPix) + { + *newDestBuf = 1; + } + else + { + tempValue = (*newBuf)*255; + if(tempValue < 1) tempValue = 1; + else if(tempValue > 255) tempValue = 255; + + *newDestBuf = (ossim_uint8)(tempValue); + } + if(*oldBuf == oldNullPix) + { + *oldDestBuf = 1; + } + else + { + // do old buffer channel + tempValue = (*oldBuf)*255; + if(tempValue < 1) tempValue = 1; + else if(tempValue > 255) tempValue = 255; + + *oldDestBuf = (ossim_uint8)(tempValue); + } + *minDestBuf = 1; + } + ++newBuf; + ++oldBuf; + ++minDestBuf; + ++newDestBuf; + ++oldDestBuf; + } + } + else if(newBuf) + { + for(idx = 0; idx < maxIdx;++idx) + { + if(*newBuf == newNullPix) + { + *newDestBuf = 0; + *oldDestBuf = 0; + *minDestBuf = 0; + } + else + { + tempValue = (*newBuf)*255; + if(tempValue < 1) tempValue = 1; + else if(tempValue > 255) tempValue = 255; + + *newDestBuf = (ossim_uint8)(tempValue); + *oldDestBuf = 1; + *minDestBuf = 1; + } + ++newBuf; + ++minDestBuf; + ++newDestBuf; + ++oldDestBuf; + } + } + else if(oldBuf) + { + for(idx = 0; idx < maxIdx;++idx) + { + if(*oldBuf == oldNullPix) + { + *newDestBuf = 0; + *oldDestBuf = 0; + *minDestBuf = 0; + } + else + { + tempValue = (*oldBuf)*255; + if(tempValue < 1) tempValue = 1; + else if(tempValue > 255) tempValue = 255; + + *oldDestBuf = (ossim_uint8)(tempValue); + *newDestBuf = 1; + *minDestBuf = 1; + } + ++oldBuf; + ++minDestBuf; + ++newDestBuf; + ++oldDestBuf; + } + } +} + +void ossimTwoColorView::allocate() +{ + theTwoColorTile = ossimImageDataFactory::instance()->create(this, this); + if(theTwoColorTile.valid()) + { + theTwoColorTile->initialize(); + } +} + + +void ossimTwoColorView::initialize() +{ + ossimImageCombiner::initialize(); + theNewInput = 0; + theOldInput = 0; + theTwoColorTile = 0; + theNativeFlag = false; + theByPassFlag = false; + if(getNumberOfInputs() < 2) + { + theByPassFlag = true; + } + else + { + theNewInput = PTR_CAST(ossimImageSource, getInput(0)); + theOldInput = PTR_CAST(ossimImageSource, getInput(1)); + if(!theNewInput||!theOldInput) + { + theByPassFlag = true; + } + else + { + if((theNewInput->getOutputScalarType() == OSSIM_UINT8)&& + (theOldInput->getOutputScalarType() == OSSIM_UINT8)) + { + theNativeFlag = true; + } + } + } +} diff --git a/Utilities/otbossim/src/ossim/projection/ossimImageProjectionModel.cpp b/Utilities/otbossim/src/ossim/projection/ossimImageProjectionModel.cpp new file mode 100644 index 0000000000000000000000000000000000000000..66d2ef71c6c3db161a4b949a69fae69dbbe1361b --- /dev/null +++ b/Utilities/otbossim/src/ossim/projection/ossimImageProjectionModel.cpp @@ -0,0 +1,65 @@ +//----------------------------------------------------------------------------- +// +// License: LGPL +// +// See LICENSE.txt file in the top level directory for more details. +// +// Author: David Burken +// +// Description: Class definition of ossimImageProjectionModel. +// +//----------------------------------------------------------------------------- +// $Id$ + +#include <string> + +#include <ossim/projection/ossimImageProjectionModel.h> +#include <ossim/imaging/ossimImageHandler.h> +#include <ossim/projection/ossimProjection.h> +#include <ossim/projection/ossimProjectionFactoryRegistry.h> + +RTTI_DEF1(ossimImageProjectionModel, + "ossimImageProjectionModel", + ossimImageModel) + +ossimImageProjectionModel::ossimImageProjectionModel() + : ossimImageModel(), + theProjection(0) +{ +} + +ossimImageProjectionModel::~ossimImageProjectionModel() +{ + if (theProjection) + { + delete theProjection; + theProjection = 0; + } +} + +void ossimImageProjectionModel::initialize(const ossimImageHandler& ih) +{ + // Initialize base. + ossimImageModel::initialize(ih); + + if (theProjection) + { + delete theProjection; + theProjection = 0; + } + + // cast away constness for ossimImageHandler::getImageGeometry call. + ossimImageHandler* iih = const_cast<ossimImageHandler*>(&ih); + + ossimKeywordlist kwl; + if ( iih->getImageGeometry(kwl, 0) ) + { + theProjection = ossimProjectionFactoryRegistry::instance()-> + createProjection(kwl); + } +} + +const ossimProjection* ossimImageProjectionModel::getProjection() const +{ + return theProjection; +} diff --git a/Utilities/otbossim/src/ossim/support_data/ossimJ2kSizRecord.cpp b/Utilities/otbossim/src/ossim/support_data/ossimJ2kSizRecord.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c6ad0a866ff5102e1b5ae98685a12b1d43fc6c07 --- /dev/null +++ b/Utilities/otbossim/src/ossim/support_data/ossimJ2kSizRecord.cpp @@ -0,0 +1,154 @@ +//---------------------------------------------------------------------------- +// +// License: LGPL +// +// See LICENSE.txt file in the top level directory for more details. +// +// Author: David Burken +// +// Description: Container class for J2K Image and tile size (SIZ) record. +// +// See document BPJ2K01.00 Table 7-6 Image and tile size (15444-1 Annex A5.1) +// +//---------------------------------------------------------------------------- +// $Id: ossimJ2kSizRecord.h,v 1.5 2005/10/13 21:24:47 dburken Exp $ + +#include <iostream> +#include <iomanip> + +#include <ossim/support_data/ossimJ2kSizRecord.h> +#include <ossim/base/ossimConstants.h> +#include <ossim/base/ossimCommon.h> +#include <ossim/base/ossimEndian.h> + + +ossimJ2kSizRecord::ossimJ2kSizRecord() + : + theSizMarker(0xff51), + theLsiz(0), + theRsiz(0), + theXsiz(0), + theYziz(0), + theXOsiz(0), + theYOsiz(0), + theXTsiz(0), + theYTsiz(0), + theXTOsiz(0), + theYTOsiz(0), + theCsiz(0), + theSsiz(0), + theXRsiz(0), + theYRsiz(0) +{ +} + +ossimJ2kSizRecord::~ossimJ2kSizRecord() +{ +} + +void ossimJ2kSizRecord::parseStream(std::istream& in) +{ + // Note: Marker is not read. + in.read((char*)&theLsiz, 2); + in.read((char*)&theRsiz, 2); + in.read((char*)&theXsiz, 4); + in.read((char*)&theYziz, 4); + in.read((char*)&theXOsiz, 4); + in.read((char*)&theYOsiz, 4); + in.read((char*)&theXTsiz, 4); + in.read((char*)&theYTsiz, 4); + in.read((char*)&theXTOsiz, 4); + in.read((char*)&theYTOsiz, 4); + in.read((char*)&theCsiz, 2); + in.read((char*)&theSsiz, 1); + in.read((char*)&theXRsiz, 1); + in.read((char*)&theYRsiz, 1); + + if (ossim::byteOrder() == OSSIM_LITTLE_ENDIAN) + { + // Stored big endian, must swap. + ossimEndian s; + s.swap(theLsiz); + s.swap(theRsiz); + s.swap(theXsiz); + s.swap(theYziz); + s.swap(theXOsiz); + s.swap(theYOsiz); + s.swap(theXTsiz); + s.swap(theYTsiz); + s.swap(theXTOsiz); + s.swap(theYTOsiz); + s.swap(theCsiz); + } +} + +ossimScalarType ossimJ2kSizRecord::getScalarType() const +{ + ossimScalarType result = OSSIM_SCALAR_UNKNOWN; + + // Bits per pixel first seven bits plus one. + ossim_uint8 bpp = ( theSsiz & 0x3f ) + 1; + + // Signed bit is msb. + bool isSigned = ( theSsiz & 0x80 ) ? true : false; + + // std::cout << "bpp: " << int(bpp) << " signed: " << isSigned << std::endl; + + if(bpp <= 8) + { + if(isSigned == 0) + { + result = OSSIM_UINT8; + } + else if(isSigned == 1) + { + result = OSSIM_SINT8; + } + } + else if(bpp <= 16) + { + if(isSigned == 0) + { + result = OSSIM_UINT16; + } + else if(isSigned == 1) + { + result = OSSIM_SINT16; + } + } + return result; +} + +std::ostream& ossimJ2kSizRecord::print(std::ostream& out) const +{ + // Capture the original flags. + std::ios_base::fmtflags f = out.flags(); + + out << std::setiosflags(std::ios::left) << "ossimJ2kSizRecord::print" + << std::setw(24) << "\ntheSizMarker:" << std::hex << theSizMarker + << std::setw(24) << "\ntheLsiz:" << std::dec << theLsiz + << std::setw(24) << "\ntheRsiz:" << theRsiz + << std::setw(24) << "\ntheXsiz:" << theXsiz + << std::setw(24) << "\ntheYziz:" << theYziz + << std::setw(24) << "\ntheXOsiz:" << theXOsiz + << std::setw(24) << "\ntheYOsiz:" << theYOsiz + << std::setw(24) << "\ntheXTsiz:" << theXTsiz + << std::setw(24) << "\ntheYTsiz:" << theYTsiz + << std::setw(24) << "\ntheXTOsiz:" << theXTOsiz + << std::setw(24) << "\ntheYTOsiz:" << theYTOsiz + << std::setw(24) << "\ntheCsiz:" << theCsiz + << std::setw(24) << "\ntheSsiz:" << int(theSsiz) + << std::setw(24) << "\ntheXRsiz:" << int(theXRsiz) + << std::setw(24) << "\ntheYRsiz:" << int(theYRsiz) + << std::endl; + + // Reset flags. + out.setf(f); + + return out; +} + +std::ostream& operator<<(std::ostream& out, const ossimJ2kSizRecord& obj) +{ + return obj.print(out); +} diff --git a/Utilities/otbossim/src/ossim/support_data/ossimJ2kSotRecord.cpp b/Utilities/otbossim/src/ossim/support_data/ossimJ2kSotRecord.cpp new file mode 100644 index 0000000000000000000000000000000000000000..66d32d4828e8acc46bd5d4854fd02d160e81a12c --- /dev/null +++ b/Utilities/otbossim/src/ossim/support_data/ossimJ2kSotRecord.cpp @@ -0,0 +1,74 @@ +//---------------------------------------------------------------------------- +// +// License: LGPL +// +// See LICENSE.txt file in the top level directory for more details. +// +// Author: David Burken +// +// // Description: Container class for J2K "Start Of Tile" (SOT) record. +// +// See document BPJ2K01.00 Table 7-3 Image and tile size (15444-1 Annex A.4.2) +// +//---------------------------------------------------------------------------- +// $Id: ossimJ2kSotRecord.h,v 1.5 2005/10/13 21:24:47 dburken Exp $ + +#include <iostream> +#include <iomanip> + +#include <ossim/support_data/ossimJ2kSotRecord.h> +#include <ossim/base/ossimCommon.h> +#include <ossim/base/ossimEndian.h> + +ossimJ2kSotRecord::ossimJ2kSotRecord() + : + theSotMarker(0xff90), + theLsot(0), + theIsot(0), + thePsot(0), + theTpsot(0), + theTnsot(0) +{ +} + +ossimJ2kSotRecord::~ossimJ2kSotRecord() +{ +} + +void ossimJ2kSotRecord::parseStream(std::istream& in) +{ + // Note: marker not read... + + in.read((char*)&theLsot, 2); + in.read((char*)&theIsot, 2); + in.read((char*)&thePsot, 4); + in.read((char*)&theTpsot, 1); + in.read((char*)&theTnsot, 1); + + if (ossim::byteOrder() == OSSIM_LITTLE_ENDIAN) + { + // Stored big endian, must swap. + ossimEndian s; + s.swap(theLsot); + s.swap(theIsot); + s.swap(thePsot); + } +} + +std::ostream& ossimJ2kSotRecord::print(std::ostream& out) const +{ + out << std::setiosflags(std::ios::left) << "ossimJ2kSotRecord::print" + << std::setw(24) << "\ntheLsot:" << theLsot + << std::setw(24) << "\ntheIsot:" << theIsot + << std::setw(24) << "\nthePsot:" << thePsot + << std::setw(24) << "\ntheTpsot:" << int(theTpsot) + << std::setw(24) << "\ntheTnsot:" << int(theTnsot) + << std::endl; + + return out; +} + +std::ostream& operator<<(std::ostream& out, const ossimJ2kSotRecord& obj) +{ + return obj.print(out); +}